如何使用SQLiteOpenHelper

都知道在Android中SQLiteOpenHelper是用来创建和升级数据库,参考
$ANDROID_SDK_HOME/docs/reference/android/database/sqlite/SQLiteOpenHelper.html

软件发布出去了,用户已经安装使用了,但是随着软件的升级,数据库结构做了些改动,我们不希望用户把应用卸载了再装(这样会丢失应用所有的数据),我们希望在数据库总体结构和已有数据不变的情况下做些小的改动,比如新增一个字段或索引,新增加一个表等等,那么这个时候我们就要用到这个类了

常用的也就是onCreate和onUpgrade这两个方法,在使用的时候这两个方法都需要重写,里面实现自己的逻辑

我们先列出一个场景:
假设第一版程序发布出去,First Public Version,代码如下

	@Override
	public void onCreate(SQLiteDatabase db) {
		bootstrapDB(db);
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
	}

onUpgrade里面没有代码,第一版出去没有需要更新的,bootstrapDB方法就是些DDL和数据初始化操作等等

之后过了一段时间,新的程序发布(其中数据库结构做了些变化),这个时候已经开始使用第一版程序的用户就需要升级,我们不希望他已经存在的数据被破坏,那么我们发布出去的新的版本中代码该怎么写呢?
直接看代码,这些代码都是从Android自带的应用中抽取出来的,做了些具体业务上的简化,主要是阐述清楚用法

    @Override
	public void onCreate(SQLiteDatabase db) {
		bootstrapDB(db); // 这个方法里面都是最新版的初始化方法
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		Log.i(TAG, "Upgrading DB from version " + oldVersion + " to "
				+ newVersion);
		if (oldVersion == 1) {
			upgradeToVersion2(db);
			oldVersion += 1;
		}
		Log.v("do upgrade", "我更新了。。。");
	}

这样如果后来又有新的程序发布,那么这两个方法会变成类似这个样子

    @Override
	public void onCreate(SQLiteDatabase db) {
		bootstrapDB(db); // 这个方法里面始终都是最新版的初始化方法
	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		Log.i(TAG, "Upgrading DB from version " + oldVersion + " to "
				+ newVersion);
		if (oldVersion == 1) {
			upgradeToVersion2(db);
			oldVersion += 1;
		}
		if (oldVersion == 2) {
			upgradeToVersion3(db);
			oldVersion += 1;
		}
		// 这是一种逐级更新的方式
                // 对于目前使用的还是第一版的用户而言,会先执行完upgradeToVersion2再执行upgradeToVersion3
                // 对于目前使用的还是第二版的用户而言,会执行upgradeToVersion3
		Log.v("do upgrade", "我更新了。。。");
	}

这样也许就能看的很清楚这个类的意图和用法了,后面版本一直增加的话,我们就一直这样写就好,保证全新的用户和升级的用户都能正常使用,那么我们如何来调用呢
一般我们会有个构造方法,有个参数就是数据库的版本,比如下面这两个构造方法

	public MyDatabaseHelper(Context context, String name, CursorFactory factory,
			int version) {
		super(context, name, factory, version);
	}

	public MyDatabaseHelper(Context context, int version) {
		super(context, NAME, null, version);
	}

采用如下方式调用

	helper = new MyDatabaseHelper(context, 10); // 这个数据库版本号会随着程序的每次发布而变化,是表示每次需要更新到的版本号,也就是最新的版本号
	sqlite = helper.getWritableDatabase();

其实更好理解这个用法就是读SQLiteOpenHelper.getWritableDatabase这个方法,里面有段代码

    int version = db.getVersion();
    if (version != mNewVersion) {
        db.beginTransaction();
        try {
            if (version == 0) {
                onCreate(db);
            } else {
                onUpgrade(db, version, mNewVersion);
            }
            db.setVersion(mNewVersion);
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }
    }

另外,看看set/get Version就知道数据库版本标记是通过PRAGMA user_version;这个命令来完成的,你也可以用sqlite3之类的工具把数据库文件打开,然后执行PRAGMA user_version查看或者设置版本值

如下是完整的两个代码,是目前在使用的

One thought on “如何使用SQLiteOpenHelper”

Leave a Reply

Your email address will not be published. Required fields are marked *