志不强者智不达,言不信者行不果。这篇文章主要讲述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数据库的结构进行升级:
【Android 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(32) PRIMARY KEY ,UserName VARCHAR(32) NOT NULL ,UserAddress VARCHAR(16) NOT 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 { 4StringBuffer columnNameBuffer = null; 5Cursor c = null; 6try 7{ 8c = db.rawQuery( "PRAGMA table_info(" + tableName + ")", null); 9if (null != c) { 11int columnIndex = c.getColumnIndex("name"); 12if (-1 == columnIndex) { 14return null; 15} 16 17int index = 0; 18columnNameBuffer = new StringBuffer(c.getCount()); 19for ( c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) { 21columnNameBuffer.append(c.getString( columnIndex )); 22columnNameBuffer.append(","); 23index++; 24} 25} 26} 27catch (Exception e) { 29e.printStackTrace(); 30} 31finally { 33if (c != null) { 35c.close(); 36} 37} 38return columnNameBuffer.toString(); 40 }
加上事物控制:
1 // update table 2 private void updateTable(SQLiteDatabase db, String tableName, String columns) 3 { 4try 5{ 6db.beginTransaction(); 7String oldColumns = columns.substring(0, columns.length() - 1); 8// rename the table 9String tempTable = tableName + "texp_temptable"; 10String renameTableSql = "alter table " + tableName + " rename to " + tempTable; 11db.execSQL(renameTableSql); 12 14// drop the oldtable 15String dropTableSql = "drop table if exists " + tableName; 16db.execSQL(dropTableSql); 17// creat table 18String createTableSql = "create table if not exists " + tableName + "(name text, pwd text, tel text)"; 19db.execSQL(createTableSql); 20// load data 21String newColume = "tel"; 22String newColumns = oldColumns + "," + newColumn; 23String insertSql = "insert into " + tableName + " (" + newColumns + ") " + "select " + oldColumns + "" + " " + " from " + tempTable; 25db.execSql(insertSql); 26db.setTransactionSuccessful(); 27} 28catch (Exception e) 29{ 30// TODO: handle exception 31Log.i( "tag", e.getMessage() ); 32} 33finally 34{ 35db.endTransaction(); 36} 39 }
//DBHelper:
1 public class DBHelper extends SQLiteOpenHelper { 2 3private static final String DATABASE_NAME = "student.db"; 4private static final int DATABASE_VERSION = 1002; 5 6private static DBHelper instance = null; 7 8 9public DBHelper(Context context) { 10super(context, DATABASE_NAME, null, DATABASE_VERSION); 11} 12 13public synchronized static DBHelper getInstance(Context context) { 14if (instance == null) { 15instance = new DBHelper(context); 16} 17return instance; 18} 19 20@Override 21public void onCreate(SQLiteDatabase db) { 22db.execSQL(SQL.CREATE_TABLE_FAVORITE); 23 24// 若不是第一个版本安装,直接执行数据库升级 25// 请不要修改FIRST_DATABASE_VERSION的值,其为第一个数据库版本大小 26final int FIRST_DATABASE_VERSION = 1000; 27onUpgrade(db, FIRST_DATABASE_VERSION, DATABASE_VERSION); 28} 29 30@Override 31public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 32// 使用for实现跨版本升级数据库 33for (int i = oldVersion; i < newVersion; i++) { 34switch (i) { 35case 1000: 36upgradeToVersion1001(db); 37break; 38case 1001: 39upgradeToVersion1002(db); 40break; 41 42default: 43break; 44} 45} 46} 47 48private void upgradeToVersion1001(SQLiteDatabase db){ 49// student 表新增1个字段 50String sql1 = "ALTER TABLE Student ADD COLUMN age VARCHAR"; 51db.execSQL(sql1); 52}
53private void upgradeToVersion1002(SQLiteDatabase db){ 54// student 表新增2个字段, 添加新字段只能一个字段一个字段加,sqlite有限制不予许一条语句加多个字段 55String sql1 = "ALTER TABLE Student ADD COLUMN tel VARCHAR"; 56String sql2 = "ALTER TABLE Student ADD COLUMN address VARCHAR"; 57db.execSQL(sql1); 58db.execSQL(sql2); 59} 60 }
推荐阅读
- Android APP开发内容图片不显示
- 配置文件——App.config文件读取和修改
- Android自定义Dialog多选对话框(Dialog+Listview+CheckBox)
- 不安分的android开发者(小程序初尝试,前后台都自己做)
- Android进程机制
- App inventor的初级教程粗略地介绍
- Android进阶之绘制-自定义View完全掌握
- Django命名空间app_name和namespace
- dubbo Wrapper