前言
在Android中存储数据的方式有很多种,其中使用SQLite数据库是存储结构化数据的最佳选择。幸运的是,Android中默认提供了对SQLite的支持,这就使得在Android中使用SQLite数据库变得格外方便。
支持的数据类型
SQLite是一款轻量级的数据库,其支持的数据类型也很简单,主要有以下几种:
- text:字符类型
- real:浮点类型
- integer:整数类型
- blob:二进制数据类型
创建数据库
SQLite数据库的使用始于SQLiteOpenHelper这个抽象类。我们需要自定义类去继承SQLiteOpenHelper,并重写它的构造方法。实际上,有两个构造方法可以重写,一般我们选择重写参数较少的那个方法。
此外,我们还需要实现onCreate和onUpgrade这两个抽象方法。在onCreate方法中,我们对数据库进行创建。而在onUpgrade方法中,我们则对数据库进行升级、更新。基本代码如下:
public class BookOpenHelper extends SQLiteOpenHelper{
private static final String CREATE_BOOK="create table Book(" +
"id integer primary key autoincrement," +
"name text," +
"price text," +
"author text)";
public BookOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
可以看到,在构造方法中,我们只是简单地调用了父类的构造方法。在构造方法的参数列表中,第一个参数是Context对象,第二个参数是数据库名称,第三个参数一般传入null,第四个参数是数据库的版本号。
此外,我们定义了一个字符串常量。很明显,这是一条建表语句,用于创建名为Book的表。在这个表中,我们定义了四个字段,分别是id、name、price、author。其中,id由primary key和autoincrement修饰,代表它是表的主键且自增。在onCreate方法中,我们调用了SQLiteDatabase的execSQL方法,执行Book表的建表语句。
在实际使用中,我们需要先构建SQLiteOpenHelper的实例,然后调用它的getReadableDatabase或者getWritableDatabase方法,如果数据库还未创建,系统就会创建数据库并调用SQLiteOpenHelper的onCreate方法。实例代码如下:
BookOpenHelper dbOpenHelper=new BookOpenHelper(
MainActivity.this,"SQLiteDemo.db",null,1);
dbOpenHelper.getReadableDatabase();
getReadableDatabase和getWritableDatabase方法都会返回一个可以对数据库进行增删改查操作的SQLiteDatabase对象。它们的区别在于,当手机存储空间已满的时候,前者会返回null,而后者会抛出异常。
更新数据库
在实际开发中,常常需要对数据库进行修改,比如添加新的表或是增加表字段等。为了实现对数据库的更新,我们需要在构建SQLiteOpenHelper实例的时候传入一个比当前版本号更大的version参数,这将导致SQLiteOpenHelper的onUpgrade方法被调用。在这个方法中,我们就可以进行数据库的更新操作了。以下代码演示在之前的数据库中添加名为Author的表:
public class BookOpenHelper extends SQLiteOpenHelper{
.......
//创建Author表
private static final String CREATE_AUTHOR="create table Author(" +
"id integer primary key autoincrement," +
"name text," +
"age integer)";
public BookOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_AUTHOR);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion){
case 1:
db.execSQL(CREATE_AUTHOR);
default:
break;
}
}
}
我们定义了一个新的字符串常量CREATE_AUTHOR,用于创建Author表。同时,我们也在onCreate方法中执行了db.execSQL(CREATE_AUTHOR);。如果应用是首次安装,就可以正常地创建两张表。但是,如果应用之前已经被安装了。由于数据库已经存在,onCreate方法就不会被执行了。在这种情况下,我们将补救措施写在了onUpgrade方法中。通过对oldVersion、即旧版本号的判断,我们执行了后续的建表语句。只要在创建SQLiteOpenHelper的时候传入了比当前版本号更大的version参数,onUpgrade方法就会被调用,Author表也就会被创建了。
如果现在我们又想要为Author表添加一个新的字段country,用于记录作者的名字,又该如何操作呢?实际上做法和前面一样,只需要在onUpgrade方法中执行更新操作即可,具体代码如下:
public class BookOpenHelper extends SQLiteOpenHelper{
.......
//为Author表添加新的字段
private static final String ALTER_AUTHOR="alter table Author add column country text";
public BookOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_AUTHOR);
db.execSQL(ALTER_AUTHOR);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion){
case 1:
db.execSQL(CREATE_AUTHOR);
case 2:
db.execSQL(ALTER_AUTHOR);
default:
break;
}
}
}
在onCreate方法中,我们依次执行了各个SQL操作,这样当应用首次安装时就可以正常地创建所有的表。而在onUpgrade方法中,我们通过判断当前数据库的版本号,来决定应该做哪些更新操作。若当前版本号为2,则只需要为Author表添加新的字段;若当前版本号为1,则需要先创建Author表,再为Author表添加新的字段。这也是为什么每个case都不加break的原因,这样才能保证应用跨版本升级的时候能够依次执行所有的更新操作。这一点尤其需要注意。
基本操作
解决了如何创建数据库和更新数据库的问题,接下来就可以正式接触SQLite中的各项数据操作了。一般可以简称为CRUD操作,即增删改查。首先,我们需要获得一个SQLiteDatabase对象,它封装了多种数据操作方法。可以通过SQLiteOpenHelper实例的getReadableDatabase或getWritableDatabase方法获得这个对象。
SQLiteDatabase database=dbOpenHelper.getWritableDatabase();
SQLiteDatabase database=dbOpenHelper.getReadableDatabase();
添加数据
SQLiteDatabase通过insert方法实现数据的添加,其方法原型如下:
public long insert(String table, String nullColumnHack, ContentValues values)
insert方法需要传入三个参数,第一个参数是表名,第二个参数一般传入null,第三个参数是一个ContentValues对象。ContentValues通过键值对的方式存储需要写入表中的数据。插入完成后,这个方法还会返回插入数据在表中的id号,如果插入失败,则返回-1。示例代码如下:
SQLiteDatabase database= dbOpenHelper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put("name","Android");
values.put("author",&

