Android SQLite数据库升级,怎么做(事物更改)
SQLiteOpenHelper
// 如果数据库文件不存在,只有onCreate()被调用(该方法在创建数据库时被调用一次)
public abstract void onCreate(SQLiteDatabase db);
// 如果数据库文件存在,会调用onUpgrade()方法升级数据库,并更新版本号。
public abstract void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion);
OnCreate : 如果数据库文件不存在,SQLiteOpenHelper在创建数据库文件,打开数据库这个数据库后,调用onCreate()方法,在该方法中一般需要创建表、视图等组件。在创建前数据库一般是空的,因此不需要先删除数据库中相关的组件。
OnUpgrade : 当系统在构造SQLiteOpenHelper类的对象时,如果发现版本号不一样,就会自动调用onUpgrade函数,让你在这里对数据库进行升级。
新版本号和老版本号都会作为onUpgrade函数的参数传进来,便于开发者知道数据库应该从哪个版本升级到哪个版本。
升级完成后,数据库会自动存储最新的版本号为当前数据库版本号。
需要对SQLite数据库的结构进行升级:
SQLite提供了ALTER TABLE命令,允许用户重命名或添加新的字段到已有表中,但是不能从表中删除字段。
并且只能在表的末尾添加字段,比如,为 Student添加两个字段:
ALTER TABLE Student ADD COLUMN UserPhone VARCHAR;
ALTER TABLE Student ADD COLUMN UserNickName VARCHAR;
如果遇到复杂的修改操作,比如在修改的同时,需要进行数据的转移,那么可以采取在一个事务中执行如下语句来实现修改表的需求。
1. 将表名改为临时表
ALTER TABLE Student RENAME TO __temp__Student;
2. 创建新表
CREATE TABLE Student (UserId VARCHAR() PRIMARY KEY ,UserName VARCHAR() NOT NULL ,UserAddress VARCHAR() 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;
通过以上四个步骤,就可以完成旧数据库结构向新数据库结构的迁移,并且其中还可以保证数据不会应为升级而流失。
当然,如果遇到减少字段的情况,也可以通过创建临时表的方式来实现。
获取表中字段:
// 获取升级前表中的字段
protected String getColumnNames(SQLiteDatabase db, String tableName)
{
StringBuffer columnNameBuffer = 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;
columnNameBuffer = new StringBuffer(c.getCount());
for ( c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
columnNameBuffer.append(c.getString( columnIndex ));
columnNameBuffer.append(",");
index++;
}
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (c != null) {
c.close();
}
}
return columnNameBuffer.toString(); }
加上事物控制:
// update table
private void updateTable(SQLiteDatabase db, String tableName, String columns)
{
try
{
db.beginTransaction();
String oldColumns = columns.substring(0, columns.length() - 1);
// rename the table
String tempTable = tableName + "texp_temptable";
String renameTableSql = "alter table " + tableName + " rename to " + tempTable;
db.execSQL(renameTableSql); // drop the oldtable
String dropTableSql = "drop table if exists " + tableName;
db.execSQL(dropTableSql);
// creat table
String createTableSql = "create table if not exists " + tableName + "(name text, pwd text, tel text)";
db.execSQL(createTableSql);
// load data
String newColume = "tel";
String newColumns = oldColumns + "," + newColumn;
String insertSql = "insert into " + tableName + " (" + newColumns + ") " + "select " + oldColumns + "" + " " + " from " + tempTable;
db.execSql(insertSql);
db.setTransactionSuccessful();
}
catch (Exception e)
{
// TODO: handle exception
Log.i( "tag", e.getMessage() );
}
finally
{
db.endTransaction();
}
}
//DBHelper:
public class DBHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "student.db";
private static final int DATABASE_VERSION = 1002;
private static DBHelper instance = null;
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public synchronized static DBHelper getInstance(Context context) {
if (instance == null) {
instance = new DBHelper(context);
}
return instance;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL.CREATE_TABLE_FAVORITE);
// 若不是第一个版本安装,直接执行数据库升级
// 请不要修改FIRST_DATABASE_VERSION的值,其为第一个数据库版本大小
final int FIRST_DATABASE_VERSION = 1000;
onUpgrade(db, FIRST_DATABASE_VERSION, DATABASE_VERSION);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 使用for实现跨版本升级数据库
for (int i = oldVersion; i < newVersion; i++) {
switch (i) {
case 1000:
upgradeToVersion1001(db);
break;
case 1001:
upgradeToVersion1002(db);
break;
default:
break;
}
}
}
private void upgradeToVersion1001(SQLiteDatabase db){
// student 表新增1个字段
String sql1 = "ALTER TABLE Student ADD COLUMN age VARCHAR";
db.execSQL(sql1);
}
private void upgradeToVersion1002(SQLiteDatabase db){
// student 表新增2个字段, 添加新字段只能一个字段一个字段加,sqlite有限制不予许一条语句加多个字段
String sql1 = "ALTER TABLE Student ADD COLUMN tel VARCHAR";
String sql2 = "ALTER TABLE Student ADD COLUMN address VARCHAR";
db.execSQL(sql1);
db.execSQL(sql2);
}
}
Android SQLite数据库升级,怎么做(事物更改)的更多相关文章
- Android SQLiteOpenHelper Sqlite数据库升级onUpgrade
Android Sqlite数据库升级,在Android APP开发之中,非常常见: 在确定原来的数据库版本号之后,在原来数据库版本号+1,就会执行onUpgrade方法,进行数据库升级操作: 在on ...
- Android SQLite 数据库 增删改查操作
Android SQLite 数据库 增删改查操作 转载▼ 一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库--SQLite,SQLite3支持NU ...
- Android Sqlite 数据库版本更新
Android Sqlite 数据库版本更新 http://87426628.blog.163.com/blog/static/6069361820131069485844/ 1.自己写一个类继承 ...
- Android SQLite 数据库详细介绍
Android SQLite 数据库详细介绍 我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用 ...
- Android sqlite数据库存取图片信息
Android sqlite数据库存取图片信息 存储图片:bitmap private byte[] getIconData(Bitmap bitmap){ int size = bitmap.get ...
- 图解IntelliJ IDEA 13版本对Android SQLite数据库的支持
IntelliJ IDEA 13版本的重要构建之一是支持Android程序开发.当然对Android SQLite数据库的支持也就成为了Android开发者对IntelliJ IDEA 13版本的绝对 ...
- Android——SQLite/数据库 相关知识总结贴
android SQLite简介 http://www.apkbus.com/android-1780-1-1.html Android SQLite基础 http://www.apkbus.com/ ...
- Android——SQLite数据库(二)升级数据库、增、删、改、查、事务
xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= ...
- [android] SQLite 数据库的升级 和 降级
public class SqliteHelp extends SQLiteOpenHelper { /* * context:创建数据库所需的 上下文对象 * name: 数据库名字 * facto ...
随机推荐
- Linux-Shell编程之求命令行中所有整数之和
前言 复习shell编程知识,书中有此练习题,之前学习时便没有搞透彻,此次是非啃下不可. 但是,摸索许久,却屡碰南墙,于是查阅网络博客,结果有让人比学不懂知识更让生气的是:博文遍地,净是抄袭!连个截图 ...
- rsync + sersync 实现实时数据同步
一.环境: 主机1:youzhuan-bak centos 7.2 主机2:youzhuan-online centos 7.2 二.部署过程: youzhuan-bak : [root@ ...
- win10 64位Python 3.6.2 + Django 环境安装
一.安装Python3.6.2 1.下载安装包 https://www.python.org/downloads/release/python-362/ 2.一直下一步,记得到了这个界面全部勾选再下一 ...
- (三)ORB特征匹配
ORBSLAM2匹配方法流程 在基于特征点的视觉SLAM系统中,特征匹配是数据关联最重要的方法.特征匹配为后端优化提供初值信息,也为前端提供较好的里程计信息,可见,若特征匹配出现问题,则整个视觉SLA ...
- Burp插件开发——环境配置
最近打算开发个Burp插件,从网上各种地找资料学习.第一步就应该是环境配置,请见下文. (其实最重要的前提是你已经安装了Burp,否则下面的所有内容都是无稽之谈了. https://pan.baidu ...
- 基于注解的SpringMVC添加其他的Servlet、Filter以及Listener
我们可以在AbstractAnnotationConfigDispatcherServletInitializer的实现类中重写onStartup(ServletContext servletCont ...
- 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能
题目:编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能 要求:MyCP支持两个参数: java MyCP -tx XXX1.txt XXX2.bin 用来把文本文件(内容为十 ...
- 爬虫 解析库re,Beautifulsoup,
re模块 点我回顾 Beautifulsoup模块 #安装 Beautiful Soup pip install beautifulsoup4 #安装解析器 Beautiful Soup支持Pytho ...
- 最优的路线(floyd最小环)
问题描述 学校里面有N个景点.两个景点之间可能直接有道路相连,用Dist[I,J]表示它的长度:否则它们之间没有直接的道路相连.这里所说的道路是没有规定方向的,也就是说,如果从I到J有直接的道路,那么 ...
- js 利用canvas + flv.js实现视频流 截屏 、本地下载功能实现,兼容火狐,谷歌;canvas截屏跨域问题,无音频视频流加载不显示问题
项目:物联网监控项目----后台视频流管理(前端实现视频截屏功能) 本文就不同视频源分情况展示: 1 本地视频(项目同目录视频)截屏(canvas.getContext("2d).drawI ...