android SQLiteOpenHelper详解
Activites 可以通过 Content Provider 或者 Service 访问一个数据库。
Android平台下数据库相关类:
SQLiteOpenHelper 抽象类:通过从此类继承实现用户类,来提供数据库打开、关闭等操作函数。
SQLiteDatabase 数据库访问类:执行对数据库的插入记录、查询记录等操作。
SQLiteCursor 查询结构操作类:用来访问查询结果中的记录。
创建数据库
Android不自动提供数据库。在 Android 应用程序中使用 SQLite,必须自己创建数据库,然后创建表、索引,填充数据。
Android 提供了 SQLiteOpenHelper 帮助你创建一个数据库,你只要继承 SQLiteOpenHelper 类,就可以轻松的创建数据库。
SQLiteOpenHelper 类根据开发应用程序的需要,封装了创建和更新数据库使用的逻辑。SQLiteOpenHelper 的子类,至少需要实现三个方法:
1 | package com.dandan.fm.db; |
2 |
3 | import android.content.Context; |
4 | import android.database.sqlite.SQLiteDatabase; |
5 | import android.database.sqlite.SQLiteDatabase.CursorFactory; |
6 | import android.database.sqlite.SQLiteOpenHelper; |
7 |
8 | /** |
9 | * 可以通过SQLiteOpenHelper的以下两个方法来或得SQLiteDatabase的对象: |
10 | * getReadableDatabase() 创建或者打开一个查询数据库 |
11 | * getWritableDatabase() 创建或者打开一个可写数据库 |
12 | */ |
13 | public class DBHelper extends SQLiteOpenHelper { |
14 |
15 | /** |
16 | * 构造函数,必须实现 |
17 | * @param context 上下文路径 |
18 | * @param name 数据库名称 |
19 | * @param factory 可选游标工厂,通常为NULL |
20 | * @param version 当前数据库版本号 |
21 | */ |
22 | public DBHelper(Context context, String name, CursorFactory factory, |
23 | int version) { |
24 | super (context, name, factory, version); |
25 | } |
26 | |
27 | //数据库第一次创建时会调用,一般在其中创建数据库表 |
28 | @Override |
29 | public void onCreate(SQLiteDatabase db) { |
30 | //使用execSQL()方法执行DDL语句,如果没有异常,这个方法没有返回值 |
31 | db.execSQL( "create table user(id INTEGER PRIMARY KEY AUTOINCREMENT," + |
32 | "name varchar(20), address TEXT)" ); |
33 | } |
34 | |
35 | //当数据库需要修改的时候,Android系统会主动的调用这个方法。 |
36 | @Override |
37 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {} |
38 | |
39 | //打开数据库时的回调函数,一般不会用 |
40 | @Override |
41 | public void onOpen(SQLiteDatabase db) { |
42 | super .onOpen(db); |
43 | } |
44 | |
45 | @Override |
46 | public synchronized void close() { |
47 | super .close(); |
48 | } |
49 | } |
创建表和索引
上面这行代码
1 | db.execSQL( "create table user(id INTEGER PRIMARY KEY AUTOINCREMENT," + |
2 | "name varchar(20), address TEXT)" ); |
创建了一个名为user的表,有一个列名id,为主键,并且这列的值是自动增长的整数(当你插入一行时,SQLite会自动给这列赋值)。
SQLite会自动为主键列添加索引。
给表添加数据
有两种方式添加数据:
1.向上面创建表一样,可以使用execSQL方法执行 INSERT, UPDATE, DELETE 等语句来更新表的数据。
execSQL适用于所有不需要返回结果的SQL语句。如:
1 | db.execSQL( "INSERT INTO user (name, address) VALUES ('YuanFang'," + |
2 | "'http://www.20864.com')" ); |
2.SQLiteDatabase 对象的 insert(), update(), delete() 方法。这些方法把 SQL 语句的一部分作为参数。如:
1 | private SQLiteDatabase mDataBase = null ; |
2 | private static final String USER_TABLE = "user" ; |
3 | |
4 | public void getDB() { |
5 | //创建DBHelper对象 |
6 | DBHelper db = new DBHelper( this , USER_TABLE, null , 1 ); |
7 | //获取可写SQLiteDatabase |
8 | mDataBase = db.getWritableDatabase(); |
9 | } |
10 | |
11 | public void insert() { |
12 | //ContentValues对象,向其中插入键值对,键是数据库列名,值是插入到这一列的值 |
13 | ContentValues cv = new ContentValues(); |
14 | cv.put( "name" , "LiuMing" ); |
15 | cv.put( "address" , "ShangHai" ); |
16 | mDataBase.insert(USER_TABLE, null , cv); |
17 | } |
18 | |
19 | public int update() { |
20 | ContentValues cv = new ContentValues(); |
21 | cv.put( "name" , "MaLi" ); |
22 | //第三个参数where语句,相当于sql语句中where后面的语句,?是占位符 |
23 | //第四个参数是占位符的值 |
24 | return mDataBase.update(USER_TABLE, cv, "id = ?" , new String[]{ "1" }); |
25 | } |
26 | |
27 | public int delete() { |
28 | //和udate()类似 |
29 | return mDataBase.delete(USER_TABLE, "id = ? and name = ?" , |
30 | new String[]{ "1" , "MaLi" }); |
31 | } |
查询数据库
与INSERT,UPDATE,DELETE类似,有两种方法从数据库中查询数据。
1 | /** |
2 | * 使用rawQuery()直接调用SELECT语句,最简单的查询方法 |
3 | * 如果查询是动态的,使用rawQuery就会非常复杂 |
4 | * @return Cursor可以迭代查询结果 |
5 | */ |
6 | public Cursor rawQuery() { |
7 | return mDataBase.rawQuery( "select * from user where id = ? and name = ?" , |
8 | new String[]{ "1" , "LiuMing" }); |
9 | } |
10 | |
11 | //使用SELECT语句段构建查询,SELECT语句内容做为query()方法的参数 |
12 | public Cursor query() { |
13 | String[] columns = { "name" , "address" }; |
14 | //第二个参数: 要查询的列名 |
15 | //第三个参数:where语句 |
16 | //第三个参数:where语句中占位符的值 |
17 | //第四个参数:对查询结果进行分组 |
18 | //第五个参数:对分组结果进行限制 |
19 | //第六个参数:对查询结果进行排序 |
20 | return mDataBase.query(USER_TABLE, columns, "id = ?" , new String[] { "1" }, |
21 | null , null , null ); |
22 | } |
使用游标
不管如何执行查询,都会返回一个Cursor,Curosr主要方法如下:
getCount():获得结果集中有多少记录。
moveToFirst():移动到第一行。
moveToNext():移动到下一行,可遍历所有记录。
isAfterLast():判断是否最后一行。
getColumnNames():返回字段名。
getColumnCount():返回字段号。
getString(),getInt():得到给定字段当前记录的值。
requery():重新执行查询得到游标。
close():释放游标资源。
1 | public void getValue() { |
2 | //遍历user表 |
3 | Cursor c = mDataBase.rawQuery( "select id, name from user" , null ); |
4 | c.moveToFirst(); |
5 | while (!c.isAfterLast()) { |
6 | int id = c.getInt( 0 ); |
7 | String name = c.getString( 1 ); |
8 | //do something |
9 | c.moveToNext(); |
10 | } |
11 | |
12 | //或者 |
13 | //使用do while 最好判断一下count,否则空数据时会报出超出索引 |
14 | if (c.getCount() > 0 ) { |
15 | c.moveToFirst(); |
16 | //使用while直接去查第二条数据了,所以这里使用do while,才可以遍历出完整的结果集。 |
17 | do { |
18 | int id = c.getInt(c.getColumnIndex( "id" )); |
19 | String name = c.getString(c.getColumnIndex( "name" )); |
20 | } while (c.moveToNext()); //将光标移动到下一行,从而判断该结果集是否有下一条数据 |
21 | } |
22 | c.close(); |
23 | } |
更多相关文章
- Android 直接连MySQL数据库
- android 多线程数据库读写分析与优化
- Android 数据库Sqlite的使用(3)
- 我的android 第12天 - 嵌入式关系型SQLite数据库存储数据
- android 3d游戏研究(二)(边学边写,多谢高手指正,鞠躬) :数据库
- Android利用JDBC连接服务器数据库
- 赵雅智_使用sqlite创建数据库