zoukankan      html  css  js  c++  java
  • Android SQLite数据库升级,怎么做(事物更改)

    SQLiteOpenHelper
    1 // 如果数据库文件不存在,只有onCreate()被调用(该方法在创建数据库时被调用一次)
    2 public abstract void onCreate(SQLiteDatabase db);
    3 // 如果数据库文件存在,会调用onUpgrade()方法升级数据库,并更新版本号。
    4 public abstract void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion);

    OnCreate : 如果数据库文件不存在,SQLiteOpenHelper在创建数据库文件,打开数据库这个数据库后,调用onCreate()方法,在该方法中一般需要创建表、视图等组件。在创建前数据库一般是空的,因此不需要先删除数据库中相关的组件。

    OnUpgrade : 当系统在构造SQLiteOpenHelper类的对象时,如果发现版本号不一样,就会自动调用onUpgrade函数,让你在这里对数据库进行升级。

    新版本号和老版本号都会作为onUpgrade函数的参数传进来,便于开发者知道数据库应该从哪个版本升级到哪个版本。

    升级完成后,数据库会自动存储最新的版本号为当前数据库版本号。

    需要对SQLite数据库的结构进行升级:

    SQLite提供了ALTER TABLE命令,允许用户重命名或添加新的字段到已有表中,但是不能从表中删除字段。
    并且只能在表的末尾添加字段,比如,为 Student添加两个字段:
    1 ALTER TABLE Student ADD COLUMN UserPhone VARCHAR;
    2 ALTER TABLE Student ADD COLUMN UserNickName VARCHAR;

    如果遇到复杂的修改操作,比如在修改的同时,需要进行数据的转移,那么可以采取在一个事务中执行如下语句来实现修改表的需求。
    1. 将表名改为临时表
             ALTER TABLE Student RENAME TO __temp__Student;

    2. 创建新表
            CREATE TABLE Student (UserId VARCHAR(32PRIMARY KEY ,UserName VARCHAR(32NOT NULL ,UserAddress VARCHAR(16NOT NULL);
      
    3. 导入数据  
             INSERT INTO Student  SELECT UserId, “”, UserAddress FROM __temp__Student;
    或者  
            INSERT INTO Student()  SELECT UserId, “”, UserAddress FROM __temp__Student;
    * 注意 双引号”” 是用来补充原来不存在的数据的
      
    4. 删除临时表  
            DROP TABLE __temp__Student;

      通过以上四个步骤,就可以完成旧数据库结构向新数据库结构的迁移,并且其中还可以保证数据不会应为升级而流失。
      当然,如果遇到减少字段的情况,也可以通过创建临时表的方式来实现。

    获取表中字段:

     1 // 获取升级前表中的字段
     2 protected String getColumnNames(SQLiteDatabase db, String tableName)
     3 {
     4   StringBuffer columnNameBuffer = null;
     5   Cursor c = null;
     6   try
     7   {
     8     c = db.rawQuery( "PRAGMA table_info(" + tableName + ")", null);
     9     if (null != c) {
    11       int columnIndex = c.getColumnIndex("name");
    12       if (-1 == columnIndex) {
    14         return null;
    15       }
    16 
    17       int index = 0;
    18       columnNameBuffer = new StringBuffer(c.getCount());
    19       for ( c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
    21         columnNameBuffer.append(c.getString( columnIndex ));
    22         columnNameBuffer.append(",");
    23         index++;
    24       }
    25     }
    26   }
    27   catch (Exception e) {
    29     e.printStackTrace();
    30   }
    31   finally {
    33     if (c != null) {
    35       c.close();
    36     }
    37   }
    38   return columnNameBuffer.toString();40 }

    加上事物控制:

     1 // update table
     2 private void updateTable(SQLiteDatabase db, String tableName, String columns)
     3 {
     4     try
     5     {
     6        db.beginTransaction();
     7        String oldColumns = columns.substring(0, columns.length() - 1);
     8        // rename the table
     9        String tempTable = tableName + "texp_temptable";
    10        String renameTableSql = "alter table " + tableName + " rename to " + tempTable;
    11        db.execSQL(renameTableSql);
    12 
    14     // drop the oldtable
    15     String dropTableSql = "drop table if exists " + tableName;
    16     db.execSQL(dropTableSql);
    17     // creat table
    18     String createTableSql = "create table if not exists " + tableName + "(name text, pwd text, tel text)";
    19     db.execSQL(createTableSql);
    20     // load data
    21     String newColume = "tel";
    22     String newColumns = oldColumns + "," + newColumn;
    23     String insertSql = "insert into " + tableName + " (" + newColumns + ") " + "select " + oldColumns + "" + " " + " from " + tempTable;
    25     db.execSql(insertSql);
    26     db.setTransactionSuccessful();
    27   }
    28   catch (Exception e)
    29   {
    30     // TODO: handle exception
    31     Log.i( "tag", e.getMessage() );
    32   }
    33   finally
    34   {
    35     db.endTransaction();
    36   }
    39 }    

    //DBHelper: 

     1 public class DBHelper extends SQLiteOpenHelper {
     2  
     3     private static final String DATABASE_NAME = "student.db"; 
     4     private static final int DATABASE_VERSION = 1002;
     5  
     6     private static DBHelper instance = null;
     7  
     8  
     9     public DBHelper(Context context) {
    10         super(context, DATABASE_NAME, null, DATABASE_VERSION);
    11     }
    12      
    13     public synchronized static DBHelper getInstance(Context context) {
    14         if (instance == null) {
    15             instance = new DBHelper(context);
    16         }
    17         return instance;
    18     }
    19  
    20     @Override
    21     public void onCreate(SQLiteDatabase db) {
    22         db.execSQL(SQL.CREATE_TABLE_FAVORITE);
    23          
    24         // 若不是第一个版本安装,直接执行数据库升级
    25         // 请不要修改FIRST_DATABASE_VERSION的值,其为第一个数据库版本大小
    26         final int FIRST_DATABASE_VERSION = 1000;
    27         onUpgrade(db, FIRST_DATABASE_VERSION, DATABASE_VERSION);
    28     }
    29  
    30     @Override
    31     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    32         // 使用for实现跨版本升级数据库
    33         for (int i = oldVersion; i < newVersion; i++) {
    34             switch (i) {
    35             case 1000:
    36                 upgradeToVersion1001(db);
    37                 break;
    38             case 1001:
    39                 upgradeToVersion1002(db);
    40                 break;
    41                  
    42             default:
    43                 break;
    44             }
    45         }
    46     }
    47      
    48     private void upgradeToVersion1001(SQLiteDatabase db){
    49         // student 表新增1个字段
    50         String sql1 = "ALTER TABLE Student ADD COLUMN age VARCHAR";
    51         db.execSQL(sql1);
    52     }
    53 private void upgradeToVersion1002(SQLiteDatabase db){ 54 // student 表新增2个字段, 添加新字段只能一个字段一个字段加,sqlite有限制不予许一条语句加多个字段 55 String sql1 = "ALTER TABLE Student ADD COLUMN tel VARCHAR"; 56 String sql2 = "ALTER TABLE Student ADD COLUMN address VARCHAR"; 57 db.execSQL(sql1); 58 db.execSQL(sql2); 59 } 60 }
  • 相关阅读:
    二分查找
    泛型 学习
    一个时间转换的功能的类
    TCP/IP、Http、Socket的区别
    值得学习的
    popupwindow使背景变暗
    设计模式最好的学习网站
    观察者模式
    数据报的使用
    网络编程server
  • 原文地址:https://www.cnblogs.com/CharlesGrant/p/9144253.html
Copyright © 2011-2022 走看看