如果是为了创建一个简单数据库的话,这种方法比简单的逐行执行SQL语句来的复杂的多,但是一旦数据库结果变得更复杂或者你想预先写好创建脚本时,这种方法将会使你获益良多。同时你也看到我将执行SQL语句的代码抽象到了一个独立executeSQLScript方法中,这样它可以在其他情况下复用,这一点我在本文后面的代码会证实到的。
(【译者注】这里原作者没有说创建了DB类以后该如何使用DB类来创建数据库,但既然这是个入门级的说明文,应该假设读者没有使用过SQLite,在下一小节的代码中有这样的代码:
DB db = new DB(this);
SQLiteDatabase qdb = db.getReadableDatabase();
也可以使用getWritableDatabase(); 得到可以写入的数据库,这里Android会自己根据需要创建数据库,如果数据库文件不存在的话就创建,如果数据库文件已经存在的话,那么Android自己会根据数据库文件中的version信息和DB类构造函数中传入的Version信息对比,如果值不一样的话,会自己调用onUpgrade()方法更新数据库。因此onCreate方法和onUpgrade方法都不是由用户手动调用的。
这两句话可以加在Activity的onCreate方法中,或者onResume方法也是个不错的选择,执行完这句话后,在Android系统的/data/data/package_name/databases目录下就可以看到你创建的数据库文件,文件名就是上面代码中的DB_NAME的值,用DDMS拿出来以后可以用图形化工具打开看看,图形化工具可以使用有免费开源的sqliteman,在http://sqliteman.com/page/4.html下载;另外还有firefox的插件:sqlite manager可以使用)
与数据库交互
现在数据库已经创建好了,下面我想和它进行交互。一个简单的操作步骤:
第一步是打开数据库,有两种方法可以做到这点:使用getReadableDatabase()方法或者getWritableDatabase()方法。前者速度快,占用资源少,可以用来做除了写数据库和修改数据库之外的所有操作;后者主要用来做insert, update等操作。
在Android系统中,查询结果集作为一个Cursor对象返回,可以调用query()或者rawQuery()方法执行一次查询,例如,下面的两个方法返回的结果完全相同:
1
2
3
4
|
DB db = new DB( this ); SQLiteDatabase qdb = db.getReadableDatabase(); Cursor recordset1 =
qdb.query( "mytable" , null , null , null , null , null , null ); Cursor recordset2 = qdb.rawQuery( "SELECT * FROM mytable" , null ); |
第一个查询调用使用了一堆参数,他们分别是数据表名称,一个列名数组, WHERE子句,选择参数数组,GROUP BY子句,HAVING子句以及ORDER BY子句。可以注意到,把这么多参数都设置为null,其作用和你用通配符代替这些参数的效果是一样的,如果你不需要给这些参数赋值,你干脆就不要用这种包含那么多参数的方法。
这里大多数参数对于熟悉SQL语句的人来说相当的直白。不过这个选择参数数组需要一点点说明,它是一个字符串数组,在查询方法中,WHERE子句中可以包含‘?’,然后在查询时,所有问号依次被选择参数数组中的值替换,比如选择参数数组中的第一个值替换掉WHERE子句中第一个‘?’。
再看看rawQuery()方法,它只需要两个参数,第一个是SQL查询语句,第二个是选择参数数组-它的作用和query方法中的一样。选择参数数组一般和复杂的查询一起使用,比如说使用到JOIN操作的时候。(【译者注】这里原作者说到做连接操作,我们知道sqlite仅支持左连接,而且当left join时,连接条件不在where子句中,因此这里应该指select x1, x2 from tables1, tables 2 where table1.?=tables2.? 这样的连接操作。实际上,我觉得这样的设计应该是为了不需要每次查询都要拼接查询语句字符串,比如说写个select * from tablename where name = ?, 这个?每次查询都不一样,这样可以通过选择参数数组中的值来替换?,而不需要每次都”select * from tablename where name = ‘“+Michael+”’” 这样拼接字符串,Java中拼接字符串的代价是比较高的,特别是查询条件比较多的时候,连续的几次字符串+操作会创建一堆String对象)。