Android数据库版本升级

android应用在发布后,会进行版本迭代。其中因为需求的更改,功能的扩充,可能会涉及到数据库的升级。如果只是添加表,还比较好处理,直接在public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)中新建表就OK了,但是涉及到已存在的表的结构发生变更,就比较麻烦了,特别是之前已经升级过表的结构,再次升级的时候需要考虑用户当前的版本,也就是需要在代码里对不同版本的数据库,升级到最新版本进行处理。其实这个跟制作增量升级包差不多,需要为每个历史版本制作一个增量包。

虽然CSDNBlog目前还没有涉及到数据库升级,但是提前准备好还是有必要的。接下来就把这两天学习到的sqlite数据库升级总结一下:

当数据库不存在的时候,会调用SQLiteOpenHelper的onCreate()方法;之后启动应用,若数据库已经存在,就不会再次调用该方法了。当数据库版本号发生变动时会调用相应的方法。

<span style="white-space:pre">	</span>// 构造方法
	private DB(Context context) {
		// 创建数据库
		super(context, DB_NAME, null, DATABASE_VERSION);
		Log.i(TAG, "create database");
	}

上面的代码是创建SQLiteOpenHelper的实例(DB类继承的SQLiteOpenHelper),其中DATABASE_VERSION就是自定义的数据库版本号。

如果应用启动时发现DATABASE_VERSION小于当前数据库的版本号时,也是就是需要对数据库进行降级操作,会调用下面的方法:

	@Override
	public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		super.onDowngrade(db, oldVersion, newVersion);
	}

当然,基本上不会使用降级,我在试验的时候,忘记当前的数据库版本号,也没有覆写onDowngrade方法,随便给个版本号,运行之后会出现无响应,或者其他一些奇怪的现象。

进行数据库升级的时候,会调用onUpgrade方法,在此方法里面,我们不仅要更新表结构,还要考虑到表中的数据保留问题。当然直接删除旧表,重新建表格会很爽,但是用户积累的数据就没有了。也就是说,我们需要把旧表的数据保存到新表。

思路是:先更改旧表的表名(如果升级后表名发生变化的话,就不需要这一步了),新建表,然后就根据旧表的结构把数据重新插入新表。

	// 版本更新时调用
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		
		//需要转移数据的字段
		String columns = "";
		
		Log.i(TAG, "oldVersion=" + oldVersion);
		//根据不同的数据库版本进行数据的备份
		switch (oldVersion) {
		case 1:
			columns = BlogInfo.TITLE + "," + BlogInfo.LINK + ","
					+ BlogInfo.DESCRIPTION + "," + BlogInfo.MSG + ","
					+ BlogInfo.DATESTAMP + "," + BlogInfo.TIMESTAMP_READ + ","
					+ BlogInfo.CONTENT + "," + BlogInfo.TYPE_BLOG + ","
					+ BlogInfo.TYPE_ARTICLE;
			break;

		case 2:
			
			break;
			
		default:
			db.execSQL("DROP TABLE IF EXISTS " + TB_BLOG);
			db.execSQL("DROP TABLE IF EXISTS " + TB_BLOGER);
			onCreate(db);// 创建新表
			return;
		}
		
		//开始准备数据
		try {
			
			db.beginTransaction();
			
			Log.i(TAG, "Rename table.");
			String tempTableName = TB_BLOG + "_temp";
			String sql = "ALTER TABLE " + TB_BLOG + " RENAME TO " + tempTableName;
			db.execSQL(sql);
			
			Log.i(TAG, "Create table.");
			onCreate(db);// 创建新表
			
			Log.i(TAG, "Load data");
			sql = "INSERT INTO " + TB_BLOG + " (" + columns + ") " + " SELECT " + columns + " FROM " + tempTableName;
			db.execSQL(sql);
			
			Log.i(TAG, "Drop the temporary table.");
			db.execSQL("DROP TABLE IF EXISTS " + tempTableName);
			
			db.setTransactionSuccessful();
			db.endTransaction();
		} catch (Exception e) { } 
	}

如果数据库有多个历史版本,就需要在switch中一一处理,当然,如果没有考虑到的情况,只能惨然的删除重建了。

其中有一句是直接调用回调函数onCreate(db)

onCreate(db);// 创建新表
虽然感觉很奇怪,但确实可行。


因为暂时还没有用到数据库的升级,所以现在只是简单的把功能实现,以后根据需求再完善。

如有大神指点,感激不尽!

你可能感兴趣的:(CSDN博客,sqlite升级,onDowngrade)