安卓应用数据库升级新姿势

数据库升级
  • 数据库升级一般的sql操作有以下这些。

    1. 创建表 CREATE TABLE 表名 (列名 数据类型 限定符…)

      CREATE TABLE  Table (ID INTEGER,NAME TEXT);
    2. 修改表 ALTER TABLE …(命令允许用户重命名或添加新的字段在已有表中,不能从表中删除字段。并且只能在表的末尾添加字段)

      ALTER TABLE tTable RENAME TO MyTable;
    3. 添加一列:ALTER TABLE 表名 ADD COLUMN 列名 数据类型 限定符

      ALTER TABLE MyTable ADD COLUMN AGE INTEGER;
    4. 导入数据

      ``INSERT INTO tTable SELECT OrderId, “”, ProductId FROM MyTable; 

    5. 删除表 DROP TABLE 表名

      DROP TABLE MyTable;
  • 数据库升级顺序(如下图表示,需要给tb_user表中增加logintime字段)
    这里写图片描述 -> 这里写图片描述

    1. 如果tb_user表里面数据为空直接走X,将tb_user删除,重新创建新表。
    2. 如果不为空,则先将tb_user所在的库拷贝到另类外一个文件夹下面。(…/temp/user.db ,user.db中有tb_user表)。这么做是为了在升级过程中,如果升级失败,可以将数据还原。
    3. 修改tb_user表明为temp_tb_user

      ALTER TABLE tb_user RENAME TO temp_tb_user;
    4. 创建新表tb_user

      create table if not exists tb_user( name TEXT, password TEXT, user_id Text,logintime Integer);
    5. 将临时表temp_tb_user中的数据拷贝到tb_user中。可以调用sql语句

        insert into tb_user(name ,password ,user_id ) 
        select name ,password ,user_id from temp_tb_user;
    6. 删除临时表

      DROP TABLE temp_tb_user;
    7. 最后数据库升级成功之后,删除刚才保存在另外一个文件夹下的临时文件(…/temp/user.db ,user.db中有tb_user表)。

  • 上面的那些清楚之后,仔细一想,就会发现,如果项目中已有几张表的话,按照这个顺序,写几个升级代码就可以实现了。可是现实使用中的场景远比上面要复杂很多很多倍。

    • 表的数量可能有十几个到几十个之多,对应的每个表都有一段升级代码。
    • 一个项目上线之后,会有很多个版本,各个版本之间的数据库可能都会有或大或小的差异,那么就需要针对每个版本之间做升级。
  • 表数量 * 版本差异* … 想想都觉得头大,那么有没有其他方法,简化这个过程呢?下面就是我想要介绍的方法了。先看下面一段xml

<!-- 请保证该文档一定是 UTF-8编码 -->
<updateXml>
    <createVersion version="V003">
        <createDb name="user">
            <!-- 设备与软件关联信息 -->
            <sql_createTable>
                create table if not exists tb_user(
                name TEXT,
                password TEXT,
                loginName TEXT,
                lastLoginTime,
                user_id Integer primary key
                );
            </sql_createTable>
        </createDb>
        <createDb name="logic">
            <!-- 设备与软件关联信息 -->
            <sql_createTable>
                create table if not exists tb_photo(
                time TEXT,
                path TEXT,
                to_user TEXT,
                sendTime TEXT
                );
            </sql_createTable>
        </createDb>
    </createVersion>
    <updateStep
        versionFrom="V002"
        versionTo="V003">
        <updateDb name="logic">
            <sql_before>alter table tb_photo rename to bak_tb_photo;</sql_before>
            <sql_after>
                insert into tb_photo(time,
                path)
                select time,path
                from bak_tb_photo;
            </sql_after>
            <sql_after>
                drop table if exists bak_tb_photo;
            </sql_after>
        </updateDb>
        <updateDb name="user">
            <sql_before>alter table tb_user rename to bak_t_user;</sql_before>
            <sql_after>
                insert into tb_user(name,
                password)
                select name,password
                from bak_tb_user;
            </sql_after>
            <sql_after>
                drop table if exists bak_t_user;
            </sql_after>
        </updateDb>
    </updateStep>

</updateXml>
  • 先简单多其中的一些字段 做一下解释。
    1. version 当前运行的app所需要的版本号。
    2. versionFrom 从哪个版本升级。
    3. versionTo 要升级到哪个版本
    4. 其他的创建表,和创建db的根据名字也能看的出来了,具体就不再多做说明。
    • 上面三个version参数就是今天的关键所在。
      1. 每个app版本,在内存卡中创建一个路径,保存当前数据库的版本version。app升级时需要做一次检查,如果被用户删掉了,再次创建,总之确保新安装的app打开之后,知道上一个版本的信息。
      2. 将上面的xml保存在assest目录下,app打开后,读取assest里面的version和本地比对,如果本地的小于version里面的版本则说明要升级。
      3. updateStep应该有许多组,里面的两个参数 versionFrom 就是本地存储的,versionTo 就是app当前需求的。如果这两个参数匹配ok,就按照里面的xml升级数据库。
      4. 当然升级的过程和上面说的顺序基本类似。

总结

  • 优点 :简化了java代码的书写,一套代码可以应对所有版本的数据库升级,后期升级数据库不再需要更改java代码。
  • 缺点 : 表越多,就需要维护越多的xml文件。不过相对于每次对比着版本号来重构java代码,我更愿意维护xml文件。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值