SQLiteOpenHelper
引入:
在编写数据库应用软件时,需要考虑这样的问题:我们开发的软件如果应用使用到SQLite数据库,
我们必须在用户初次使用软件时创建出数据库表结构及添加一些初始化记录;另外在软件升级的时候,
也需要对数据表结构进行更新。
如何才能实现在用户初次使用或升级软件时自动在用户的手机上创建出应用需要的数据库表呢?
所以在Android系统,为我们提供了一个名为SQLiteOpenHelper的抽象类。
详解:
SQLiteOpenHelper是系统提供的一个管理数据库表创建和版本管理(尤其是版本更新)的抽象类,
我们必须通过继承SQLiteOpenHelper来实现自己的工具类。一般我们要重写三个方法,构造器、onCreate方法、
onUpgrade方法。
为了实现对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是:
- onCreate(SQLiteDatabase db)
- onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
1、当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()
方法获取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系
统会自动生成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库
时才会被调用,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始
化数据。
版本号,而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更
,修改了数据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据
库表结构,为了实现这一目的,可以把原来的数据库版本设置为2(有同学问设置为3行不行?
当然可以,如果你愿意,设置为100也行),并且在onUpgrade()方法里面实现表结构的更新。
当软件的版本升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号
进行判断,然后作出相应的表结构及数据更新。
SQLiteOpenHelper 类的使用步骤:【重点】
- 创建SQLiteOpenHelper类的子类MySQLiteOpenHelper 类,实现SQLiteOpenHelper类中的抽象方法onCreate()和onUpgrade();
- 调用 MySQLiteOpenHelper 对象的getWritableDatabase 或 getReadableDatabase方法,获得SQLiteDatabase 对象;
- 创建表
- 调用SQLiteDatabase 对象的execSQL()方法,执行 update,insert,delete操作;调用rawQuery()方法执行select查询操作;
- 如果执行的是查询操作,则对返回的Cursor进一步处理。
SQLiteOpenHelper类中常用方法:
- onCreate(SQLiteDatabase db) : 当数据库被首次创建时执行该方法,一般将创建表等初始化操作在该方法中执行。
- onUpgrade(SQLiteDatabse dv, int oldVersion,int new Version):当打开数据库时传入的版本号与当前的版本号不同时会调用该方法。
【备注:】除了上述两个必须要实现的方法外,还可以选择性地实现onOpen 方法,该方法会在每次打开数据库时被调用。
- getWritableDatabase() 创建一个可读写数据库
- getReadableDatabase() 创建一个可读写数据库
【备注:】调用getReadableDatabase 方法返回的并不总是只读数据库对象,一般来说该方法和getWriteableDatabase 方法的返回情况相同,只有在数据库仅开放只读权限或磁盘已满时才会返回一个只读的数据库对象。而getWriteableDatabase()方法打开的数据库,一旦数据库磁盘空间满了,就只能读而不能写,如果再写则报错。因此建议使用getReadableDatabase()方法来获打开数据库。getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。但getWritableDatabase()方法以写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用getWritableDatabase()打开数据库就会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。
封装MySQLiteOpenHelper 类
封装的目的
为了工作方便,为了提高代码重用性,将重复写的代码封装起来。
封装的原则:要注意粒度和耦合性。要尽量做到耦合性低。
封装 MySQLiteOpenHelper 类的核心代码
<span style="font-size:18px;">public class DBHelper extends SQLiteOpenHelper {
private static final String DBNAME = "mydb.db";
private static final int CURRENTVERSION = 4;
public static final String USERTABLE = "USER";
public static final String BOOK = "BOOK";
// 第一个参数上下文
// 第二个参数表示数据库名称
// 第三个参数游标构造器
// 第四个参数表示数据库版本号
public DBHelper(Context context) {
super(context, DBNAME, null, CURRENTVERSION);
}
// 数据库创建时调用
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + USERTABLE
+ "(_id INTEGER PRIMARY KEY AUTOINCREMENT,USERNAME,PASSWORD)");
onUpgrade(db, 1, CURRENTVERSION);
}
// 当数据库版本升级的时候调用
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d("qianfeng", "oldVersion:" + oldVersion + ";newVersion:" + newVersion);
switch (oldVersion) {
// 版本二执行的更新
case 1:
db.execSQL("ALTER TABLE " + USERTABLE + " ADD COLUMN 'NICKNAME'");
// 版本三执行的更新
case 2:
db.execSQL("CREATE TABLE IF NOT EXISTS " + BOOK + "(_id INTEGER PRIMARY KEY AUTOINCREMENT,NAME,PRICE)");
// 版本四执行的更新
case 3:
db.execSQL("ALTER TABLE " + BOOK + " ADD COLUMN 'AUTHOR'");
break;
}
}
}</span>