请考虑如下情况:

在数据库升级时,不同版本的数据库,他们定义的表结构完全可能是不一样的,比如V1.0的表A有10个column,而在V1.1的表A有12个colum,在升级时,表A增加了两列,此时我们应该怎么做呢。

总体思路

1,将表A重命名,改了A_temp。

2,创建新表A。

3,将表A_temp的数据插入到表A。

下面代码列出了更新表的实现,upgradeTables,给定表名,更新的列名,就可以实现数据库表的更新。

/*** Upgrade tables. In this method, the sequence is:* <b>* <p>[1] Rename the specified table as a temporary table.* <p>[2] Create a new table which name is the specified name.* <p>[3] Insert data into the new created table, data from the temporary table.* <p>[4] Drop the temporary table.* </b>** @param db The database.* @param tableName The table name.* @param columns The columns range, format is "ColA, ColB, ColC, ... ColN";*/
protected void upgradeTables(SQLiteDatabase db, String tableName, String columns)
{try{db.beginTransaction();// 1, Rename table.String tempTableName = tableName + "_temp";String sql = "ALTER TABLE " + tableName +" RENAME TO " + tempTableName;execSQL(db, sql, null);// 2, Create table.onCreateTable(db);// 3, Load datasql =   "INSERT INTO " + tableName +" (" + columns + ") " +" SELECT " + columns + " FROM " + tempTableName;execSQL(db, sql, null);// 4, Drop the temporary table.execSQL(db, "DROP TABLE IF EXISTS " + tempTableName, null);db.setTransactionSuccessful();}catch (SQLException e){e.printStackTrace();}catch (Exception e){e.printStackTrace();}finally{db.endTransaction();}
}

得到数据库表的列名

我们可以通过SQL表得到表的列名。 这里需要注意的一点,int columnIndex = c.getColumnIndex("name"); 这里根据name去取得index。

protected String[] getColumnNames(SQLiteDatabase db, String tableName)
{String[] columnNames = null;Cursor c = null;try{c = db.rawQuery("PRAGMA table_info(" + tableName + ")", null);if (null != c){int columnIndex = c.getColumnIndex("name");if (-1 == columnIndex){return null;}int index = 0;columnNames = new String[c.getCount()];for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){columnNames[index] = c.getString(columnIndex);index++;}}}catch (Exception e){e.printStackTrace();}finally{closeCursor(c);}return columnNames;
}

  

upgradeTables方法应该是在onUpgrade方法中去调用。

数据库升级的意义

在应用程序开发的过程中,数据库的升级是一个很重要的组成部分(如果用到了数据库),因为程序可能会有V1.0,V2.0,当用户安装新版本的程序后,必须要保证用户数据不能丢失,对于数据库设计,如果发生变更(如多添加一张表,表的字段增加或减少等),那么我们必须想好数据库的更新策略。

1,定义数据库版本

数据库的版本是一个整型值,在创建SQLiteOpenHelper时,会传入该数据库的版本,如果传入的数据库版本号比数据库文件中存储的版本号大的话,那么SQLiteOpenHelper#onUpgrade()方法就会被调用,我们的升级应该在该方法中完成。

2,如何写升级逻辑

假如我们开发的程序已经发布了两个版本:V1.0,V1.2,我们正在开发V1.3。每一版的数据库版本号分别是18,19,20。

对于这种情况,我们应该如何实现升级?

用户的选择有:

1) V1.0 -> V1.3  DB 18 -> 20

2) V1.1 -> V1.3  DB 19 -> 20

3,注意

数据库的每一个版本所代表的数据库必须是定义好的,比如说V18的数据库,它可能只有两张表TableA和TableB,如果V19要添加一张表TableC,如果V20要修改TableC,那么每一个版本所对应的数据库结构如下:

V18  --->  TableA, TableB

V19  --->  TableA, TableB, TableC

V20  --->  TableA, TableB, TableC (变更)

onUpgrade()方法的实现如下:

        // Pattern for upgrade blocks:////    if (upgradeVersion == [the DATABASE_VERSION you set] - 1){//        .. your upgrade logic..//        upgradeVersion = [the DATABASE_VERSION you set]//    }public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){int upgradeVersion  = oldVersion;if (18 == upgradeVersion) {// Create table CString sql = "CREATE TABLE ...";db.execSQL(sql);upgradeVersion = 19;}if (20 == upgradeVersion) {// Modify table CupgradeVersion = 20;}if (upgradeVersion != newVersion) {// Drop tablesdb.execSQL("DROP TABLE IF EXISTS " + tableName);// Create tablesonCreate(db);}}

  

从上面的代码可以看到,我们在onUpgrade()方法中,处理了数据库版本从18 -> 20的升级过程,这样做的话,不论用户从18 -> 20,还是从19 -> 20,最终程序的数据库都能升级到V20所对应的数据库结构。

4,如何保证数据不丢失

这是很重要的一部分,假设要更新TableC表,我们建议的做法是:

1) 将TableC重命名为TableC_temp

SQL语句可以这样写:ALERT TABLE TableC RENAME TO TableC_temp;

2) 创建新的TableC表

3) 将数据从TableC_temp中插入到TableC表中

SQL语句可以这样写:INSERT INTO TableC (Col1, Col2, Col3) SELECT (Col1, Col2, Col3) FROM TableC_temp;

经过这三步,TableC就完成了更新,同时,也保留了原来表中的数据。

注意:

在onUpgrade()方法中,删除表时,注意使用事务处理,使得修改能立即反应到数据库文件中。

SQL语句

由于Android是使用开源的SQLite3作为其数据库,所以,我们在开发数据库模块时,一定要注意SQLite3支持哪些关键字,函数等,不是所有的关键字,SQLite都是支持的。

下面列出了一些参考链接:

SQLite3官方文档:http://sqlite.org/

W3CSchool网站:http://www.w3school.com.cn/sql/index.asp/

SQL语句写得好坏能直接影响到数据库的操作。我曾经就遇到过SQL语句影响查询性能,更新3000条记录,用时30移左右,但在对WHERE条件的字段加上索引后,性能提升到3~4秒。

Android 数据库升级解决方案相关推荐

  1. 18.移动架构数据库升级解决方案

    今天的数据库升级将通过这个脚本文件完成,我们假设目前版本迭代中,已经上线了V001 V002版本,近期将要上线V003.首先先理清三个版本的数据库情况,三个版本中都涉及一个个数据库文件(暂不考虑分库的 ...

  2. Android数据库升级实例

    第一部分 Andoird的SQLiteOpenHelper类中有一个onUpgrade方法.帮助文档中只是说当数据库升级时该方法被触发.经过实践,解决了我一连串的疑问: 1. 帮助文档里说的" ...

  3. Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())的注意点

    以下内容可以作为面试官在面试的时候的问题,感觉比较好,是比较常用的知识点,可以用来考察基础是否扎实. 也可以程序猿学习.开发中的注意点.因为稍微不注意,就有可能导致数据库不能用. DBAdapter. ...

  4. android数据库升级兼容老版本吗,成功升级后Android升级数据库不更新数据库版本...

    我想添加三个新表到我现有的sqlite数据库,我遇到了成功升级后不更新数据库版本的问题.下面是运行DatabaseHelper:成功升级后Android升级数据库不更新数据库版本 private st ...

  5. oracle数据库的医院信息系统数据库升级方案,医院信息系统数据库从Oracle8i到10gR2升级的实现...

    医院信息系统数据库从Oracle8i到10gR2升级的实现 时间:2009年03月02日16:05 来源:当代医学 作者:李泰环 [摘要]  目的  解决资源紧张,系统运行较慢等问题.方法 升级数据库 ...

  6. android数据库降级_Android SQLite (二.数据库创建,升级及降级)

    上篇文章简介和常用语法介绍了SQLite数据库的基本信息和一些常用的语法操作,本篇文章主要介绍Android开发过程中SQLite数据库的创建使用和常见问题处理. 一.SQLiteOpenHelper ...

  7. Android数据库高手秘籍(三)——使用LitePal升级表

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/39151617 在上一篇文章中,我们学习了LitePal的基本使用方法,体验了使用框 ...

  8. android自动更新列表,Android数据库表结构自动升级

    Android App开发如果涉及过数据库的朋友们肯定会碰到数据库升级的工作,Android官方的建议办法是override public void onUpgrade(SQLiteDatabase ...

  9. Android ORM 框架:GreenDao 数据库升级

    本文作者:Speedy CSDN 专栏:blog.csdn.net/speedystone 掘金专栏:juejin.im/user/57e082- 前言 在 Android ORM 框架:GreenD ...

最新文章

  1. VMware虚拟机安装黑苹果MacOS Mojave系统详细教程
  2. 阿里面试 Java 都问什么?万字总结!
  3. SpringBoot专栏(一) -- SpringBoot简介
  4. SAP BOPF和Spring框架里加了注解的控制器是如何被调用的
  5. 类型缩放Google map 地图类型
  6. python进阶指南_Python特性工程动手指南
  7. Spring Boot面试题
  8. javascript闭包新认识
  9. web服务-Axis2的安装
  10. loaded question解释
  11. OS_windows_性能监视器资源监视器任务管理器:指标阅读与使用/关闭/调整虚拟内存/android内存调度
  12. CSS基础——简单的文字样式
  13. PostmanCn: Postman中文版
  14. kubectl认证 授权 准入控制
  15. sklearn.neighbors 最近邻相关算法,最近邻分类和回归
  16. requests模块基本使用、代理ip、session访问
  17. Word在试图打开文件时遇到错误,请尝试下列方法:检查文档或驱动器的文件权限 确保有足够的内存和磁盘空间 用文本恢器打开文件
  18. 野兽北京读书记:关于精神力量的层次
  19. LGA 775 是什么意思
  20. 高防服务器对ip有影响吗,高防服务器与高防IP的区别和联系

热门文章

  1. 11 Python Pandas tricks that make your work more efficient
  2. softsign与tanh的比较
  3. win7虚拟磁盘服务器,Win7系统如何删除虚拟磁盘 win7系统删除虚拟磁盘的方法
  4. docker desktop 镜像_Spring Boot实战工具4 - Docker
  5. 稀疏矩阵快速转置c语言代码(详解)
  6. javaswing引入百度地图_【react】React怎么引用百度地图
  7. 编译原理——词法分析器
  8. 笔记-信息化与系统集成技术-工作流
  9. Node中的Http模块和Url模块的使用
  10. Docker获取镜像并运行