SQLite数据库升级

  • 格式:doc
  • 大小:59.38 KB
  • 文档页数:7

Android客户端SQLite数据库升级方案一,前言没有采用Android自身提供的那一套数据库操作方式。

而是想对SQLite数据库文件有更全面的控制,包括随时导出数据库文件修改表结构,增删数据等等。

这样一来虽然在开放中得到不少便利,但是也带来了数据库升级的一些问题。

后来不得已采用了一种方案,可以解决问题,现将方案的全部实现细节记录下来。

最后也会提出一些我认为有问题的地方。

二,数据库文件拷贝程序不负责数据库的创建,SQLite数据库文件是在外部创建好的。

程序启动阶段拷贝进SD 卡。

以达到对数据库结构的全面控制。

数据库文件存放位置见附件图片。

1.public void copyDBFile() {2.// 数据库路径3.if (!FileOperator.checkFile(SysConst.DB_PATH)) {4. boolean result = FileOperator.write2Sdcard(activity,5.R.raw.scpip_collection, SysConst.DB_PATH);6. Debug.log("无数据库文件,首次拷贝" + result);7. if (!result) {8. throw new IllegalAccessError(activity9. .getString(R.string.copy_db_exception));10. } else {11. // 拷贝成功,更新数据库版本12. try {13.PackageInfo info = activity.getPackageManager()14. .getPackageInfo(activity.getPackageName(), 0);15.// 当前程序版本号,在AndroidManifest.xml中定义16.int versionCode = info.versionCode;17.Config.saveDbVer(versionCode);18.Debug.log("拷贝成功" + result);19. } catch (NameNotFoundException e) {20.Debug.e(e);21. }22. }23.} else {24. // 数据库已存在的情况25. if (dbUpdate.needUpdate() ) {26. activity.showProgress("数据库升级中,请稍后", false);27. new Thread() {28.@Override29.public void run() {30. try {31. Debug.log("update db");32. dbUpdate.updateDb();33. handler.sendEmptyMessage(0);34. } catch (Exception e) {35. Debug.e(e);36. handler.sendEmptyMessage(-1);37. }38.};39. }.start();40. }41.}42. }复制代码其中有几个要点:1、检测数据库文件是否已经存在。

不存在则从raw文件夹复制数据库文件拷贝至SD卡中指定目录。

2、数据库版本是根据应用的versionCode相同。

拷贝数据库后,会把当前versionCode写入数据库的表中。

1.<manifest2. xmlns:android="/apk/res/android"3. package="com.xxx"4. android:versionCode="2"5. android:versionName="1.01.001">6. <uses-sdk android:minSdkVersion="8" />复制代码versionCode在AndroidManifest.xml文件中。

在这种方案下,实际上是由versionCode控制数据库版本,versionName控制程序版本。

3、SD卡指定目录已经存在数据库文件的情况,则读取其中保存的数据库版本号,与versionCode对比,从而确定是否需要升级数据库。

代码如下:1.public boolean needUpdate() {2.int currVer = Config.getDbVer();3.return currVer < getAppVersion();4. }5.6. public int getAppVersion(){7.try {8. PackageInfo info = context.getPackageManager().getPackageInfo(9.context.getPackageName(), 0);10. // 当前程序版本号,在AndroidManifest.xml中定义11. return info.versionCode;12.} catch (NameNotFoundException e) {13. Debug.e(e);14. return 1;15.}16. }复制代码三,升级数据库包括三个步骤:1、从程序中拷贝新数据库文件至SD卡指定目录,命名为temp.db。

1. String temp = SysConst.DB_FOLDER + "temp.db";2.boolean s1 = FileOperator.write2Sdcard(context, R.raw.scpip_collection,temp);复制代码2、分别获取两个数据源。

1. //原数据库文件2. BaseDao sd = new BaseDao();3. //新数据库文件4. BaseDao nd = new BaseDao(temp);复制代码对于SQLite数据库来讲,数据源就是数据库文件。

BaseDao是自己封装的,关键在于要可以配置不同的数据源具体实现的相关代码如下:1.private String dbPath;2.3. public BaseDao() {}4.5. public BaseDao(String dbPath) {6.this.dbPath = dbPath;7. }8.9.public SQLiteDatabase getDb() {10.return SQLiteDatabase.openDatabase(SysConst.DB_PATH, null,11. SQLiteDatabase.OPEN_READWRITE);12. }13.14. public SQLiteDatabase getDb(String dbPath) {15.return SQLiteDatabase.openDatabase(dbPath, null,16. SQLiteDatabase.OPEN_READWRITE);17. }复制代码这样就可以根据文件,获取不同的SQLiteDatabase 对象。

3、传输数据把原数据库中的数据查询出来,插入到新数据库中。

1.public <E>void transfer(BaseDao sd,BaseDao nd,Class<E> cls) throws Exception{2.List<E> list = sd.find(cls, null);3.nd.batchInsert(list);4. }复制代码这里有两个要点,第一,使用了自行封装的ORM。

第二,使用了SQLite批量插入,增加写入效率。

代码如下:1.@Override2. public <T> void batchInsert(List<T> datas) throws Exception {3.SQLiteDatabase dba = null;4.if(dbPath == null){5. dba = getDb();6.} else {7. dba = getDb(dbPath);8.}9.int size = datas.size();10.try {11. dba.beginTransaction();12. for (int i = 0; i < size; i++) {13. DaoHelper helper = new DaoHelper(datas.get(i));14. String tableName = helper.getTableName();15. String sql = "select 1 from " + tableName + " where "16. + helper.getPkCol() + "=";17. Object id = helper.getPkValue();18. if (id instanceof String) {19.sql = sql + "'" + id + "'";20. } else {21.sql = sql + id;22. }23. c = dba.rawQuery(sql, null);24. if (c != null ? (c.getCount() == 1) : false) {25. c.close();26.continue;27. }28. if(c != null){29. c.close();30. }31.// SqlArgs sa = helper.prepareInsert();32.// dba.execSQL(sa.getSql(), sa.getArgs());33. dba.insert(helper.getTableName(), "", helper.getInsertContent());34. }35. dba.setTransactionSuccessful();36. dba.endTransaction();37.} finally {38. dba.close();39.}40. }复制代码4、写入当前数据库版本,即从程序获得的versionCode。

5、删除原数据库文件,重命名temp.db。