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"); }
如果应用启动时发现DATABASE_VERSION小于当前数据库的版本号时,也是就是需要对数据库进行降级操作,会调用下面的方法:
@Override public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { super.onDowngrade(db, oldVersion, newVersion); }
进行数据库升级的时候,会调用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) { } }
其中有一句是直接调用回调函数onCreate(db)
onCreate(db);// 创建新表虽然感觉很奇怪,但确实可行。
因为暂时还没有用到数据库的升级,所以现在只是简单的把功能实现,以后根据需求再完善。
如有大神指点,感激不尽!