前言
在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
,用于创建Autho
r表。同时,我们也在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",&