1、事务使用
首先说明一下SQLite支持的技术:事务的作用。比如银行,现在我要转账给别人,那么有两个过程:自己账户扣钱、对方账户加钱。如果这两步是分开执行的,而且中间出现错误,就会导致自己的钱凭空消失。所以这两步必须同时执行才能保证安全性。
现在在DatabaseTest上测试事务的使用:比如现在数据库的内容太旧了,需要换成新的,就需要执行delete和insert操作,而且要同时执行。方法是通过database.beginTransaction()开启事务,然后再执行这两个操作。
mBReplace = (Button) findViewById(R.id.replace_button);
mBReplace.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.beginTransaction(); // 开始事务
try {
db.delete(MyDatabaseHelper.TABLE_NAME, null, null);
if (true) throw new NullPointerException(); // 手动抛出异常,让事务执行失败
ContentValues values = new ContentValues();
values.put("no", "30");
values.put("name", "kuritian");
values.put("number", "11111");
db.insert(MyDatabaseHelper.TABLE_NAME, null, values);
db.setTransactionSuccessful(); // 事务已经执行成功
}
catch (Exception e) {e.printStackTrace();}
finally {
db.endTransaction(); // 结束事务
}
}
});
手动抛出异常之后,再查询数据,可以发现数据并没有被删除掉。如果把那行代码删除掉,就可以实现数据替换了。
2、升级数据库的最佳写法
之前我们写的升级数据库的方法比较简单粗暴:在onUpgrade方法中,先删除掉所有的表,然后强行执行onCreate方法。这样会导致原来数据库的内容全部丢失。这个问题可以通过修改onUpgrade,增加switch-case语句来解决。
第一步:增加一张表,名为subject
// MyDatabaseHelper.java
private static final String CREATE_SUBJECT = "create table subject(id integer primary key autoincrement, "
+ "name text)";
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_DB);
db.execSQL(CREATE_SUBJECT);
Toast.makeText(mContext, "创建数据库成功!", Toast.LENGTH_LONG).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 1:
db.execSQL(CREATE_SUBJECT);
default:
}
}
第二步:修改创建student表,增加一列
private static final String CREATE_DB = "create table student(id integer primary key autoincrement, "
+ "no text, name text, number text, room text)";
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 1:
db.execSQL(CREATE_SUBJECT);
case 2:
db.execSQL("alter table student add column room text");
default:
}
}
也就是对每一个版本的更新都执行不同的操作。