Android系统存储数据的第四种方式是SQLite Database,即数据库存储。
该方式(数据库存储)的特点是存储私有数据,且数据是具有数据结构的,存储位置/data/data/<包名>/databases目录下。
数据库存储有两个核心类:
SQLiteOpenHelper类: 数据库管理类
SQLiteDatabase类: 数据库操作类
SQLiteOpenHelper查阅官方文档知:
从上可知:SQLiteOpenHelper是一个帮助类,用来管理数据库的创建和数据库的版本,一般定义它的子类,实现它的两个方法onCreate,onUpdate。
eg:
1 public class DBHelper extends SQLiteOpenHelper {
2
3 public DBHelper(Context context)
4 {
5 //第一个参数是Context对象
6 //第二个参数是数据库的名字
7 //第三个参数是管理游标的工厂类对象
8 //第四个参数是当前数据库的版本
9 super(context, "user.db", null, 1);
10 }
11
12 //创建数据库时执行该方法
13 //表中字段必须含有一个 _id
14 @Override
15 public void onCreate(SQLiteDatabase db) {
16
17 db.execSQL("create table t_user(_id integer primary key,name text,age int,tel text)");
18
19 }
20
21 //数据库版本升级时执行该方法
22 @Override
23 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
24
25 if(newVersion>oldVersion)
26 {
27 db.execSQL("drop table if exists t_user");
28 }
29 }
30
31 }
SQLiteOpenHelper子类的创建
SQLiteOpenHelper类的构造方法:
这里我们一般使用第一个有四个参数的构造方法,其参数含有分别为:
Context context: context对象
String name: 创建的数据库名字
SQLiteDatabase.CursorFactory factory: 管理数据库中游标的工厂类对象,一般设为null
int version: 数据库的版本号,用于数据库版本的升级或降级
SQLiteOpenHelper类的公共方法:
其中我们较长使用的是:
getReadableDatabase(); 获取一个可读(不包含可写)的数据库对象,返回的是一个SQLiteDatabase对象
getWriteableDatabase(); 获取一个可写(包含可读)的数据库对象,返回的是一个SQLiteDatabase对象
SQLiteDatabase查阅官方文档知:
根据以上可知SQLiteDatabase是一个实际操作数据库的类,可执行数据库的增删改查操作。
获取SQLiteData对象,我们一般使用上面所介绍的方法:getReadableDatabase()和getWriteableDatabase()。此外我们也可以使用SQLiteDatabase的静态方法打开一个指定的数据库。
使用SQLiteDatabase的静态方法打开数据库:
eg:
1 // 被操作的数据库文件的路径
2 public static final String DB_PATH = Environment
3 .getExternalStorageDirectory() + "/cache/db/gp.db";
4
5 SQLiteDatabase db = SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READWRITE);
注释:这里打开的数据库文件位于手机的扩展卡上,此处我们也可以知道数据库存储位置也可以位于扩展卡,SQLiteDatabase可以操作扩展卡上的数据库文件。
SQLiteDatabase常用操作:
数据库存储的操作中,最重要的是查询操作,对于数据库的查询,会返回一个Cursor对象,通过Cursor对象,我们可以获取查询的结果。
Cursor即游标,是一个与数据库操作紧密相关的类,查阅官方文档知:
Cursor的常用方法:
moveToNext();
getColumnCount();
getColumnNames(); 返回一个字符串数组
getColumnName();
getColumnIndex();
getString(),getInt(),...
设想这样一种情景:通过数据库查询,获取结果,然后在界面ListView中显示出来。显然我们是通过适配器来适配数据,对于Cursor的使用有如下两种方式:
方式一:可以使用一般的适配器,从Cursor中获取数据,初始化数据源。
1 private void initListView(){
2 ListView listView = (ListView) findViewById(R.id.listView);
3
4 List<Map<String,Object>> data = new ArrayList<Map<String,Object>>();
5
6 SQLiteDatabase db = dbHelper.getReadableDatabase();
7 Cursor cursor = db.rawQuery("select * from t_user",null);
8 while(cursor.moveToNext()){
9 Map<String,Object> map = new HashMap<String,Object>();
10 map.put("_id",cursor.getInt(cursor.getColumnIndex("_id")));
11 map.put("name",cursor.getString(cursor.getColumnIndex("name")));
12 map.put("age",cursor.getInt(cursor.getColumnIndex("age")));
13 map.put("tel",cursor.getInt(cursor.getColumnIndex("tel")));
14 data.add(map);
15 }
16
17 SimpleAdapter adapter =
18 new SimpleAdapter(this,data,R.layout.item_user,
19 new String[]{"_id","name","age","tel"},
20 new int[]{R.id.text_id,R.id.text_name,R.id.text_age,R.id.text_tel});
21
22 listView.setAdapter(adapter);
23 }
注释:这里dbHelper是一个DatabaseOpenHelper子类的对象,已经提前创建,该处使用的是SimpleAdapter适配器。
方式二:使用与Cursor相对应的适配器SimpleCursorAdapter。
1 private void initListView(){
2 String[] columns={"_id","name","age","tel"};
3 int[] to ={R.id.text_id,R.id.text_name,R.id.text_age,R.id.text_tel};
4
5 ListView listView = (ListView) findViewById(R.id.listView);
6 Cursor cursor = null;
7 SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.item_user,cursor,
8 columns,
9 to,
10 SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
11
12 listView.setAdapter(adapter);
13
14
15 //加载数据
16 SQLiteDatabase db = dbHelper.getReadableDatabase();
17 cursor = db.query("t_user", columns, null, null, null, null, null);
18
19 //游标中的数据变化了,需要切换适配器的数据源
20 adapter.swapCursor(cursor);
21
22 }
这里将相应的代码分别全部集中于同一个方法,看起来有些繁琐,当然使用的时候可以从实际情况出发,以上仅为了作为例子的方便使用才这么做。
对比这两种方式,可知:对于数据库的操作,更多的时候会返回一个Cursor对象,当我们为了在AdapterView中显示数据库中的数据,我们可以使用SimpleCursorAdapter这个类,它可以将AdapterView和Cursor(数据源)直接沟通起来.
补上数据库添加数据的部分:
1 private void initData() {
2 SQLiteDatabase db = dbHelper.getWritableDatabase();
3
4 ContentValues values = null;
5
6 for(int i=0;i<20;i++){
7 values = new ContentValues();
8 values.put("_id", i);
9 values.put("name", "Tom "+ i);
10 values.put("age", 18 + i);
11 values.put("tel","2323"+i);
12
13 db.insert("t_user", null, values);
14 }
15 db.close();
16 }
数据库文件位置:
采用两种方式呈现的结果相同:
关于Cursor和SimpleCursorAdapter的详细内容,请查询相关文档或参见后续文章。
未完,待续。