Android数据库升级策略
一:问题产生的一般原因
版本的升级引发以往的数据结构不能满足新的要求
新的数据表的不断引入
小版本迭代可能会导致数据库的频繁变更
二:目前常用的方案
方案:
每次更新数据库时,删除旧的数据,重新建表
避免使用复杂的数据表,采用json或者xml存储
对数据库的每次变更做记录,在升级时执行变更的记录
分析:
可以避免数据库变更对新版本程序的影响,但是用户数据会被清除,可以考虑将重要的数据存储到SharedPreference中去。
该方式避免的数据库变更可能产生的所有问题,但是整理上的性能和内存消耗会比较大。
该方式稍微复杂,但是是比较理想的解决方案,既避免了数据被清除掉,也避免了性能和内存消耗
三:本文讨论的方案
本文主要讨论二中的第三种方案,进行增量式数据变更
思路:
建立配置文件,存储数据库版本号,每次数据库变更的时候将该版本号+1
建立数据变更配置文件,每一行记录一个版本的数据变更
应用启动执行到自定义的SQLiteOpenHelper的public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 方法时,首先执行配置文件中的版本变更记录,然后执行onCreate()方法
实现:
DBHelper构造,传入配置文件中的数据库版本号
- private DBHelper(Context context, String name, CursorFactory factory,
- int version) {
- super(context, name, factory, version);
- }
create
- public void onCreate(SQLiteDatabase db) {
- //这里建库时记得这样就好了CREATE TABLE IF NOT EXISTS
- }
onUpgrade
- /**
- * 数据库升级时,根据配置文件中的配置信息进行升级,可以涉及到添加字段,具体升级配置在res/raw/system.properties文件中定义
- */
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- executeLocalSQL(db);
- onCreate(db);
- }
executeLocalSQL
- /**
- * @Title: executeLocalSQL
- * @Description: 执行本地SQL语句
- * @param 设定文件
- * @return void
- */
- private void executeLocalSQL(SQLiteDatabase db) {
- ArrayList<String> sqlList = getLocalSQL();
- for (int i = 0, l = sqlList.size(); i < l; i++) {
- try {
- db.execSQL(sqlList.get(i));
- } catch (Exception e) {
- Util.log(e.getMessage());
- }
- }
- }
获取本地数据变更记录
- private ArrayList<String> getLocalSQL() {
- ArrayList<String> result = new ArrayList<String>();
- InputStream is = null;
- InputStreamReader reader = null;
- BufferedReader br = null;
- try {
- // is = Variable.appllicationContext.getResources().getAssets().open("dbchange.txt");
- is = Variable.appllicationContext.getResources().openRawResource(
- R.raw.alter);
- reader = new InputStreamReader(is);
- br = new BufferedReader(reader);
- String line = null;
- while((line = br.readLine()) !=null){
- result.add(line);
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- Util.closeStream(br);
- Util.closeStream(reader);
- Util.closeStream(is);
- }
- return result;
- }