一、概述

SQLite是Android内置的一个很小的关系型数据库。SQLiteOpenHelper是一个用来辅助管理数据库创建和版本升级问题的抽象类。我们可以继承这个抽象类,实现它的一些方法来对数据库进行自定义操作。下面两个方法必须重写:

public void onCreate(SQLiteDatabase db)

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)

SQLiteOpenHelper里的onCreate执行:

1.只在数据库还没有建立时运行一次.如果数据库已经存在了,就不再执行onCreate方法,即在第一次打开数据库的时候才会执行

2.在清除数据之后再次运行-->打开数据库,这个方法会执行

3.没有清除数据,不会执行这个方法

4.数据库升级的时候这个方法不会执行,想执行需要先删除数据,再调用onCreate方法

onUpgrade的执行:

1.第一次创建数据库的时候,这个方法不会执行

2.清除数据后再次运行(相当于第一次创建)这个方法不会执行

3.数据库已经存在,而且版本升高的时候,这个方法才会调用,但不会自动执行onCreate

onDowngrade的执行:

1.执行数据库的降级操作

2.只有新版本比旧版本低的时候才会执行

3.如果不执行降级操作,会抛出异常

二、升级数据库

 public class MyDatabaseHelper extends SQLiteOpenHelper{

     public static final String CREATE_BOOK="create table BOOK("
+"id integer primary key autoincrement,"
+"author text,"
+"price real,"
+"pages integer,"
+"name text,"
+"category_id integer)";
public static final String CREATE_CATECORY="create table Category("
+"id integer primary key autoincrement,"
+"category_name text"
+"category_code integer)";
private Context mContext;
public MyDatabaseHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
mContext=context;
} @Override//创建数据库是调用
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_CATECORY);
Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
} @Override//版本更新时调用
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//Log.i("db","测试");
switch(oldVersion){
case 1://版本1升级版本二是执行上面的创建表的语句
db.execSQL(CREATE_CATECORY);
Log.i("db","创建成功表Category成功");
case 2://版本2升级版本3时执行向Book表中添加一个字段
db.execSQL("alter table Book add column category_id integer");
Log.i("db","添加字段成功");
default:
}
}
}

   可以看到,在 onCreate()方法里我们新增了一条建表语句,然后又在 onUpgrade()方法中添加了一个 switch 判断,如果用户当前数据库的版本号是 1,就只会创建一张 Category 表。这样当用户是直接安装的第二版的程序时,就会将两张表一起创建。而当用户是使用第二版的程序覆盖安装第一版的程序时,就会进入到升级数据库的操作中,此时由于 Book 表已经存在了,因此只需要创建一张 Category 表即可。

可以看到,首先我们在 Book 表的建表语句中添加了一个 category_id 列,这样当用户直接安装第三版的程序时,这个新增的列就已经自动添加成功了。然而,如果用户之前已经安装了某一版本的程序,现在需要覆盖安装,就会进入到升级数据库的操作中。在 onUpgrade() 方法里,我们添加了一个新的 case,如果当前数据库的版本号是 2,就会执行 alter 命令来为Book 表新增一个 category_id 列。

这里请注意一个非常重要的细节,switch 中每一个 case 的最后都是没有使用 break 的,为什么要这么做呢?这是为了保证在跨版本升级的时候,每一次的数据库修改都能被全部执行到。比如用户当前是从第二版程序升级到第三版程序的,那么 case 2 中的逻辑就会执行。而如果用户是直接从第一版程序升级到第三版程序的,那么 case 1 和 case 2 中的逻辑都会执行。使用这种方式来维护数据库的升级,不管版本怎样更新,都可以保证数据库的表结构是最新的,而且表中的数据也完全不会丢失了。

三、降级

 private static final String DB_NAME = "mydata.db"; // 数据库名称
private static final int version = 2; // 数据库版本 public MyDatabaseOpenHelper(Context context) {
super(context, DB_NAME, null, version);
} // 问题:什么时候执行
// 没有前生
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
// 编写【从0开始到最新状态】建表语句
Log.i("hi", "没有数据库,创建数据库,创建v2.0成功");
String sql_message = "create table t_message (id int primary key,tou1 varchar(50),userName varchar(50),lastMessage varchar(50),datetime varchar(50))";
String sql_init_1 = "insert into t_message values (1,'abc','abc1','abcd1','hi1')";
String sql_init_2 = "insert into t_message values (2,'abc','abc2','abcd2','hi1')";
String sql_init_3 = "insert into t_message values (3,'abc','abc2','abcd2','hi1')";
db.execSQL(sql_message);
db.execSQL(sql_init_1);
db.execSQL(sql_init_2);
db.execSQL(sql_init_3); } // v2.0 现在进行时
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (oldVersion == 2){
String sql_upgrade_1 = "alter table t_message add column isdel bit default 0";
db.execSQL(sql_upgrade_1);
Log.i("db", "从2到3,升级成功!");
}
//
if (oldVersion == 1) {
Log.i("db", "从1到3,升级成功!");
String sql_upgrade_1 = "alter table t_message add column isdel bit default 0";
db.execSQL(sql_upgrade_1);
String sql_init_1 = "insert into t_message values (1,'abc','abc1','abcd1','hi1',0)";
String sql_init_2 = "insert into t_message values (2,'abc','abc2','abcd2','hi1',0)";
String sql_init_3 = "insert into t_message values (3,'abc','abc2','abcd2','hi1',0)";
db.execSQL(sql_init_1);
db.execSQL(sql_init_2);
db.execSQL(sql_init_3);
Log.i("db", "从1到3,升级成功!");
}
}
 /* 模拟从3.0 降低会2.0 */
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//正常来讲大于2.0的,应该有t_message 这张表,且2.0有的字段,3.0都有
try {
//第一、先把t_message 未来的表,改名
String rename_sql = "alter table t_message rename to t_message_bak";
db.execSQL(rename_sql);
Log.i("down", "1.改名成功");
//第二、建立2.0的表结构
String sql_message = "create table t_message (id int primary key,tou1 varchar(50),userName varchar(50),lastMessage varchar(50),datetime varchar(50))";
db.execSQL(sql_message);
Log.i("down", "2.建立2.0表结构成功");
//第三、把备份的数据,copy到 新建的2.0的表
String sql_copy = "insert into t_message select id,tou1,userName,lastMessage,datetime from t_message_bak";
db.execSQL(sql_copy);
Log.i("down", "3.copy到用户数据到 2.0的表");
//第四、把备份表drop掉
String drop_sql = "drop table if exists t_message_bak";
db.execSQL(drop_sql);
Log.i("down", "4.把备份表drop掉"); } catch (Exception e) {
//失败
Log.i("hi", "降级失败,重新建立");
String sql_drop_old_table = "drop table if exists t_message";
String sql_message = "create table t_message (id int primary key,tou1 varchar(50),userName varchar(50),lastMessage varchar(50),datetime varchar(50))";
String sql_init_1 = "insert into t_message values (1,'abc','abc1','abcd1','hi1')";
String sql_init_2 = "insert into t_message values (2,'abc','abc2','abcd2','hi1')";
String sql_init_3 = "insert into t_message values (3,'abc','abc2','abcd2','hi1')";
db.execSQL(sql_drop_old_table);
db.execSQL(sql_message);
db.execSQL(sql_init_1);
db.execSQL(sql_init_2);
db.execSQL(sql_init_3);
}
}

代码说明,这就不说了!

Android笔记——数据库升级与降级的更多相关文章

  1. Android之数据库升级onUpgrade降级onDowngrade

    借用API文档解释: public abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 当数据库需要升 ...

  2. Android数据库升级、降级、创建(onCreate() onUpgrade() onDowngrade())[4]

    数据库版本升级对软件的管理操作. 我们手机经常会收到xxx软件升级什么的提醒,你的软件版本更新,同时你的数据库对应的版本也要相应的更新. 数据库版本更新需要主要的问题: 软件的1.0版本升级到1.1版 ...

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

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

  4. Android SQLite数据库升级,怎么做(事物更改)

    SQLiteOpenHelper // 如果数据库文件不存在,只有onCreate()被调用(该方法在创建数据库时被调用一次) public abstract void onCreate(SQLite ...

  5. Android版本更新时对SQLite数据库升级或者降级遇到的问题

    SQLite是Android内置的一个很小的关系型数据库.SQLiteOpenHelper是一个用来辅助管理数据库创建和版本升级问题的抽象类.我们可以继承这个抽象类,实现它的一些方法来对数据库进行自定 ...

  6. App版本更新时对SQLite数据库升级或者降级遇到的问题

    SQLite是Android内置的一个很小的关系型数据库.SQLiteOpenHelper是一个用来辅助管理数据库创建和版本升级问题的抽象类.我们可以继承这个抽象类,实现它的一些方法来对数据库进行自定 ...

  7. Android -- 面试 -- 数据库升级策略

    升级:重写onUpgrade方法 确定 相邻版本 的差别,从版本1开始依次迭代更新,先执行v1到v2,再v2到v3…… 为 每个版本 确定与现在数据库的差别,为每个case撰写专门的升级代码. 降级 ...

  8. Android SQLiteOpenHelper Sqlite数据库升级onUpgrade

    Android Sqlite数据库升级,在Android APP开发之中,非常常见: 在确定原来的数据库版本号之后,在原来数据库版本号+1,就会执行onUpgrade方法,进行数据库升级操作: 在on ...

  9. 用 Flask 来写个轻博客 (8) — (M)VC_Alembic 管理数据库结构的升级和降级

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 Alembic 查看指令 manager db 的可用选项 ...

随机推荐

  1. iOS drewRect方法

    You do not need to override this method if your view sets its content in other ways. By the time thi ...

  2. Json格式示意图

    json视图工具:http://www.bejson.com/jsonviewernew/ 一.Json格式化,(看到数组里面又有数组一下子疑问不是合格json):尾门地址查询: =>=> ...

  3. Ue4的UE_LOG

    说明:本文为Wiki上的RAMA大神文章的大致翻译 游戏模式: 在游戏模式下,你需要在游戏的快捷方式后面加 -Log,才会在游戏中显示. 编辑器模式(Play In Editor): 你可以在Outp ...

  4. java中的单例模式(懒汉式+饿汉式)

    什么是单例模式: 单例模式既只能在自己本类中创建有且唯一的一个实例(姑且不考虑映射的情况)通过方法将该实例对外公开 第一种:单例模式-懒汉式 既调用getInstance()方法返回实例之前判断有没有 ...

  5. twitter.common.concurrent deadline and defer

    此defer非golang中的defer https://tour.golang.org/flowcontrol/12 from twitter.common.concurrent import Ti ...

  6. WP8解析XML格式文件

    DOTA2 WebAPI请求返回的格式有两种,一种是XML,一种是JSON,默认是返回JSON格式,如果要返回XML格式的话,需要在加上format=xml. 这里举一个简单的解析XML格式的例子(更 ...

  7. weex image

    weex 的image用来渲染图片, 可以使用img作为它的别名. 需要注意的是,他的长度可宽度必须指定, 不然它是不会工作的. 它没有任何的子组件. 有两个属性: src 用来指定图片的地址图片. ...

  8. Linux上Tomcat部署JavaWeb项目

    一.安装JDK 配置java的环境变量,修改/etc/profile文件:vi /etc/profile 然后按下字母i进入插入模式, shift+insert粘贴; esc退出编辑; :wq保存退出 ...

  9. 关于chrome控制台那些事

    作为一名前端,除了编写完美代码之外(个人还不具备),当然也要会调试啦,对于firebug比较而言,我还是更喜欢chrome控制台比较多(可能使用较多,更顺手的原因吧).所以来总结下,关于chrome控 ...

  10. swfupload纠结bug总结

    上传控件传到客户端的信息在IE7下乱码: 服务端 HttpUtility.UrlEncode,客户端 decodeURIComponent 上传大文件报404错: 用fiddler截取发现提示: 最可 ...