android中数据的存储方式(SQLite)

来源:互联网 发布:鞋店需要软件吗 编辑:程序博客网 时间:2024/06/01 08:08

四、SQLite数据库存储

以该种方式存储的数据也不能被其他的应用访问。

接下来我们就来看看是如何实现的吧

1、写一个类继承SQLiteOpenHelper,并重写它的onCreate()方法和onUpgrade()方法

public class MySqlDb extends SQLiteOpenHelper {    private static final String DB_NAME = "mydb";    private static final int DB_VERSION = 1;    public MySqlDb(Context context) {        super(context, DB_NAME, null, DB_VERSION);    }    //当数据库第一次被创建的时候调用    @Override    public void onCreate(SQLiteDatabase sqLiteDatabase) {        String sql = "create table my_table (id integer not null primary key,name varchar(20),password varchar(12))";        sqLiteDatabase.execSQL(sql);    }    //当数据修改的时候调用    @Override    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {    }}

2、可以通过 getWritableDatabase()和 getReadableDatabase()获取SQLiteDatabase对象,来对数据库进行相应的操作。

下面给了一个操作数据库的工具类:

public class MySQLiteOpenHelper extends SQLiteOpenHelper {    private SQLiteDatabase sQLiteDatabase = null;    // 它是数据库名    private static final String DB_NAME = "sqldb";    // 它是数据库的路径    private static final String DB_PATH = Environment            .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)            .getAbsolutePath();    // 它是数据库全路径名    private static final String DB = DB_PATH + File.separator + DB_NAME;    // 这是封装在内部的,访问数据库的对象    public MySQLiteOpenHelper(Context context) {        super(context, DB, null, 2);        // TODO Auto-generated constructor stub        sQLiteDatabase=getWritableDatabase();    }    // 它是创建时候的回调    @Override    public void onCreate(SQLiteDatabase db) {        // TODO Auto-generated method stub        Log.i("onCreate", "执行了");        db.execSQL("CREATE TABLE IF NOT EXISTS tb_my(_id integer PRIMARY KEY AUTOINCREMENT,name);");    }    // 这个是版本更新的回调    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {        // TODO Auto-generated method stub        Log.i("onUpgrade", "执行了");        if(newVersion>oldVersion){            db.execSQL("DROP TABLE IF EXISTS tb_my;");            db.execSQL("CREATE TABLE IF NOT EXISTS tb_my1(_id integer PRIMARY KEY AUTOINCREMENT,name);");        }    }    // 这是查询数据库的方法们,也就是各种重载        public Cursor selectCursor(String table, String[] columns,                String selection, String[] selectionArgs, String groupBy,                String having, String orderBy) {            return sQLiteDatabase.query(table, columns, selection, selectionArgs,                    groupBy, having, orderBy);        }        public Cursor selectCursor(String sql) {            return sQLiteDatabase.rawQuery(sql, new String[] {});        }        public Cursor selectCursor(String sql, String[] selectionArgs) {            return sQLiteDatabase.rawQuery(sql, selectionArgs);        }        // 这是一个插入的方法,封装了内部访问数据库的insert        public long insert(String table, String nullColumnHack, ContentValues values) {            // insert方法第一个参数是表名,第二个参数是防止空行所提供的列名,第三个参数是要插入的字段对应的键值对            // ContentValues它是一种键值对,可以直接new出来,就像hashmap            // 返回这一行的行号            return sQLiteDatabase.insert(table, nullColumnHack, values);        }        // 这是一个删除的方法,封装了内部访问数据库的delete        public long delete(String table, String whereClause, String[] whereArgs) {            // 第一个参数是表名,第二个参数是条件,第三个参数是替换条件中的占位符            // 返回值是此次操作影响了多少行            return sQLiteDatabase.delete(table, whereClause, whereArgs);        }        // 这是一个更新的方法,封装了内部访问数据库的update        public long update(String table, ContentValues values, String whereClause,                String[] whereArgs) {            // 第一个参数是表名,第二个参数表示要更新的列,用键值对的方式来表达,第三个参数是条件,第四个参数是替换条件中的占位符            // 返回值是此次操作影响了多少行            return sQLiteDatabase.update(table, values, whereClause, whereArgs);        }        public Cursor query(String table, String[] columns, String selection,                String[] selectionArgs, String groupBy, String having,                String orderBy){            return sQLiteDatabase.query(table, columns, selection, selectionArgs, groupBy, having, orderBy);        }        // 封装一个执行任意语句的方法        public void execSQL(String sql) {            sQLiteDatabase.execSQL(sql);        }        // 封装一个执行任意语句的方法的重载        public void execSQL(String sql, Object[] bindArgs) {            // 第一个参数是任意sql语句,第二个参数是替换占位符,为了兼容数据类型,这里使用了Object数组            sQLiteDatabase.execSQL(sql, bindArgs);        }        // 封装一个cursor转换成list的方法        public List<Map<String, Object>> cursorToList(Cursor cursor) {            if (cursor == null) {                return null;            }            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();            // 获取操作cursor之前的下标            int position = cursor.getPosition();            cursor.moveToPosition(-1);            for (; cursor.moveToNext();) {                Map<String, Object> map = new HashMap<String, Object>();                // cursor.getColumnCount()方法可以获取到一共有多少个列                for (int i = 0; i < cursor.getColumnCount(); i++) {                    // cursor.getColumnName(i)可以获取到第i列的列名                    map.put(cursor.getColumnName(i), cursor.getString(i));                }                list.add(map);            }            // 把cursor恢复到之前的状态            cursor.moveToPosition(position);            return list;        }        // 查询list的方法们,各种重载就像cursor的查询一样。        public List<Map<String, Object>> selectList(String table, String[] columns,                String selection, String[] selectionArgs, String groupBy,                String having, String orderBy) {            // 调用之前的查询方法            Cursor cursor = selectCursor(table, columns, selection, selectionArgs,                    groupBy, having, orderBy);            // 返回list使用之前的转换方法            return cursorToList(cursor);        }        public List<Map<String, Object>> selectList(String sql,                String[] selectionArgs) {            Cursor cursor = selectCursor(sql, selectionArgs);            return cursorToList(cursor);        }        public List<Map<String, Object>> selectList(String sql) {            Cursor cursor = selectCursor(sql);            return cursorToList(cursor);        }        public void destroy() {            if (sQLiteDatabase != null) {                sQLiteDatabase.close();            }        }}

3、简单说一下两种方式获取的SQLiteDatabase的不同

getWritableDatabase()和 getReadableDatabase()在正常情况下均打开一个可读写的数据库(不要被名字误导哦)。但是当出现权限错误或者磁盘满了的情况时,前者会抛出异常,一旦修复会重新打开读写的数据库,但会消耗很长的时间,所以不建议在主线程中去做。对于后者来说,一但出现问题,不会抛出异常,会打开一个只读的数据库,当修复后会重新打开读写的数据库,同样也不推荐在主线程中去调用。

五、网络存储

也就是将数据存到网上。这个要和后端配合了。所以这里不说了

总结一下android的存储方式吧:

一共有5中存储方式,有些资料说有4种,我是以API文档为依据的。并且ContentProvider我认为不能算存储方式,算是一种数据的共享方式;但是说到底,ContentProvider的底层也是用SQLite写的。所以我这里说的5种存储方式分别是:

1)Shared Preference

2)Internal Storage(内部存储)

3)External Storage(外部存储)

4)数据库存储

5)网络存储

1 0
原创粉丝点击