`

Android 数据库升级解决方案

 
阅读更多

转自:http://blog.csdn.net/leehong2005/article/details/9128501

请考虑如下情况:

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

 

总体思路

 

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

2,创建新表A。

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

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

 

[java] view plaincopy
 
  1. /** 
  2.  * Upgrade tables. In this method, the sequence is: 
  3.  * <b> 
  4.  * <p>[1] Rename the specified table as a temporary table. 
  5.  * <p>[2] Create a new table which name is the specified name. 
  6.  * <p>[3] Insert data into the new created table, data from the temporary table. 
  7.  * <p>[4] Drop the temporary table. 
  8.  * </b> 
  9.  * 
  10.  * @param db The database. 
  11.  * @param tableName The table name. 
  12.  * @param columns The columns range, format is "ColA, ColB, ColC, ... ColN"; 
  13.  */  
  14. protected void upgradeTables(SQLiteDatabase db, String tableName, String columns)  
  15. {  
  16.     try  
  17.     {  
  18.         db.beginTransaction();  
  19.   
  20.         // 1, Rename table.  
  21.         String tempTableName = tableName + "_temp";  
  22.         String sql = "ALTER TABLE " + tableName +" RENAME TO " + tempTableName;  
  23.         execSQL(db, sql, null);  
  24.   
  25.         // 2, Create table.  
  26.         onCreateTable(db);  
  27.   
  28.         // 3, Load data  
  29.         sql =   "INSERT INTO " + tableName +  
  30.                 " (" + columns + ") " +  
  31.                 " SELECT " + columns + " FROM " + tempTableName;  
  32.   
  33.         execSQL(db, sql, null);  
  34.   
  35.         // 4, Drop the temporary table.  
  36.         execSQL(db, "DROP TABLE IF EXISTS " + tempTableName, null);  
  37.   
  38.         db.setTransactionSuccessful();  
  39.     }  
  40.     catch (SQLException e)  
  41.     {  
  42.         e.printStackTrace();  
  43.     }  
  44.     catch (Exception e)  
  45.     {  
  46.         e.printStackTrace();  
  47.     }  
  48.     finally  
  49.     {  
  50.         db.endTransaction();  
  51.     }  
  52. }  

 

 

得到数据库表的列名

 

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

[java] view plaincopy
 
  1. protected String[] getColumnNames(SQLiteDatabase db, String tableName)  
  2. {  
  3.     String[] columnNames = null;  
  4.     Cursor c = null;  
  5.   
  6.     try  
  7.     {  
  8.         c = db.rawQuery("PRAGMA table_info(" + tableName + ")"null);  
  9.         if (null != c)  
  10.         {  
  11.             int columnIndex = c.getColumnIndex("name");  
  12.             if (-1 == columnIndex)  
  13.             {  
  14.                 return null;  
  15.             }  
  16.   
  17.             int index = 0;  
  18.             columnNames = new String[c.getCount()];  
  19.             for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext())  
  20.             {  
  21.                 columnNames[index] = c.getString(columnIndex);  
  22.                 index++;  
  23.             }  
  24.         }  
  25.     }  
  26.     catch (Exception e)  
  27.     {  
  28.         e.printStackTrace();  
  29.     }  
  30.     finally  
  31.     {  
  32.         closeCursor(c);  
  33.     }  
  34.   
  35.     return columnNames;  
  36. }  

 

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()方法的实现如下:

 

[java] view plaincopy
 
  1.        // Pattern for upgrade blocks:  
  2. //  
  3. //    if (upgradeVersion == [the DATABASE_VERSION you set] - 1){  
  4. //        .. your upgrade logic..  
  5. //        upgradeVersion = [the DATABASE_VERSION you set]  
  6. //    }  
  7.   
  8.   
  9. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)  
  10. {  
  11.     int upgradeVersion  = oldVersion;  
  12.   
  13.     if (18 == upgradeVersion) {  
  14.         // Create table C  
  15.         String sql = "CREATE TABLE ...";  
  16.         db.execSQL(sql);  
  17.         upgradeVersion = 19;  
  18.     }  
  19.   
  20.     if (20 == upgradeVersion) {  
  21.         // Modify table C  
  22.         upgradeVersion = 20;  
  23.     }  
  24.   
  25.     if (upgradeVersion != newVersion) {  
  26.         // Drop tables  
  27.         db.execSQL("DROP TABLE IF EXISTS " + tableName);  
  28.         // Create tables  
  29.         onCreate(db);  
  30.     }  
  31. }  


从上面的代码可以看到,我们在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秒。

 

参考:http://androidll.iteye.com/blog/1570943

分享到:
评论

相关推荐

    Android数据库升级不丢失数据解决方案 OrmLite

    本文将详细介绍使用Ormlite实现Android数据库升级而不丢失数据的解决方案。 首先,我们需要了解Ormlite的基本用法。Ormlite提供了强大的注解系统,允许我们将Java对象映射到数据库表,反之亦然。通过在Java类上添加...

    Android数据库安全解决方案,使用SQLCipher Demo

    SQLCipher就是一种针对SQLite的开源加密解决方案,它可以为数据库提供强大的加密功能,从而保护用户的敏感信息。 SQLCipher的基本原理是对SQLite数据库进行透明加密,通过修改SQLite的C库,在数据读写时自动进行加...

    Android数据库安全解决方案,使用SQLCipher进行加解密.docx

    # Android数据库安全解决方案:使用SQLCipher进行加解密 ## 一、背景介绍与问题提出 随着移动互联网的发展,智能手机已成为人们日常生活中不可或缺的一部分。在众多的移动操作系统中,Android以其开放性和灵活性受...

    android sqlite数据库升级学习

    在Android应用开发中,SQLite是一个重要的本地数据存储解决方案。SQLite是一个轻量级的、嵌入式的、关系型数据库,它允许开发者在Android设备上存储和管理数据。随着应用的迭代和功能的增加,可能需要对数据库进行...

    android数据库增删改查工具

    这个“android数据库增删改查工具”是一个自定义的解决方案,旨在简化Android应用程序中SQLite数据库的操作。开发者通常会遇到处理用户数据、成员信息等需求,这时一个方便的数据库管理工具就显得尤为重要。 首先,...

    database-lock.zip_Android 数据库_Android数据库_android_database-lock_安

    综上所述,Android数据库管理是一个多方面的任务,涉及数据库创建、操作、加密以及安全性增强。开发者应根据应用需求选择合适的加密方案,并遵循最佳实践以确保数据安全。NativeDemo项目提供了一个很好的起点,可以...

    _db_Handler.zip_Android 数据库_Android__Android数据库_手机 数据库

    SQLite是一个轻量级的、嵌入式的、关系型数据库系统,它是Android系统默认支持的数据库解决方案。SQLite数据库在Android中的应用广泛,从简单的应用设置到复杂的数据存储,都可以通过SQLite来实现。 首先,我们需要...

    Android数据库.zip

    在Android中,SQLite3作为标准的数据库解决方案,为开发者提供了高效、可靠的数据存储方式。 二、Android Studio与SQLite Android Studio是Google官方推出的Android开发集成环境,它内置了SQLite数据库管理工具,...

    Android 三方数据库ObjectBox使用

    在Android应用开发中,数据存储...总的来说,ObjectBox为Android开发者提供了一个高效、便捷的数据存储解决方案,使得数据管理变得更加简单和高效。在实际项目中,合理运用ObjectBox可以显著提升应用的性能和用户体验。

    Greendao数据库升级添加String类型,

    在Android应用开发中,数据库是数据持久化的重要手段,而Greendao则是一个高效、轻量级的对象关系映射(ORM)框架,它允许开发者直接...遇到问题时,仔细检查代码,查阅官方文档,或在社区中寻找类似问题的解决方案。

    演示Android操作数据库例子

    SQLite是一个轻量级的数据库系统,它被集成到Android操作系统中,为开发者提供了便捷的数据存储解决方案。在这个"演示Android操作数据库例子"中,我们将探讨如何使用Android的SQLite数据库以及DBHelper类来实现常见...

    android 数据库同步

    SQLite是Android系统内置的关系型数据库,它轻量级且易于使用,是大多数Android应用首选的本地数据库解决方案。本篇将深入探讨如何在Android中进行数据库的同步。 首先,我们需要了解数据库同步的基本概念。数据库...

    Android数据库框架-----GreenDao3的相关使用和版本升级更新

    在Android应用开发中,数据库是不可或缺的一部分,用于存储和管理数据。GreenDao是一个高效、轻量级的对象关系...通过不断学习和实践,可以更好地掌握这个强大的工具,为你的Android应用带来更优秀的数据库解决方案。

    android数据库

    SQLite数据库为Android应用提供了高效、可靠的数据存储解决方案,尤其适合那些对数据持久化有需求但不需要服务器端支持的应用。 SQLite在Android中的使用主要涉及以下几个方面: 1. 数据库版本管理:Android提供了...

    android 各种数据库框架使用的Demo

    通过学习这个Demo,开发者能够对比不同数据库框架的优缺点,根据项目的具体需求选择最合适的解决方案,提升数据管理的效率和代码的可维护性。无论是简单的数据存储还是复杂的业务逻辑,这些框架都能提供强大的支持。

    Android SQLite数据库操作Demo

    SQLite数据库的优势在于它不需要单独的服务进程,而是直接嵌入到应用程序中,提供了高效的本地数据存储解决方案。在这个"Android SQLite数据库操作Demo"中,我们将探讨如何在Android应用中创建、查询、更新和删除...

    Android数据库SQLite简单应用

    `onCreate()`方法会在数据库首次创建时被调用,`onUpgrade()`则在数据库升级时执行。 ```java public class MyDatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = ...

    sms.zip_Android 数据库_android_android sms_sms

    1. **SQLite数据库**:SQLite是Android系统内置的数据库解决方案,它无需服务器进程,可以直接在应用程序中使用。SQLite支持SQL标准,并提供了创建、查询、更新和删除数据的基本功能。在Android中,SQLiteOpenHelper...

    安卓SQLite数据库相关-自己实现的android数据库快速开发组件.zip

    【标题】:在Android开发中,SQLite数据库是一个重要的本地数据存储解决方案。为了简化数据库操作,开发者经常编写自己的数据库快速开发组件。本资源提供了一个自实现的Android数据库组件,旨在提高开发效率。 ...

    android 数据库加密

    SQLCipher是专门为SQLite设计的一个开源加密解决方案,它在SQLite API层面上进行了扩展,提供透明的加密功能。 - **集成加密库**:将加密库引入Android项目,通过Gradle或手动添加依赖。 - **配置SQLiteOpenHelper...

Global site tag (gtag.js) - Google Analytics