数据库升级
数据库升级一般的sql操作有以下这些。
创建表 CREATE TABLE 表名 (列名 数据类型 限定符…)
CREATE TABLE Table (ID INTEGER,NAME TEXT);
修改表 ALTER TABLE …(命令允许用户重命名或添加新的字段在已有表中,不能从表中删除字段。并且只能在表的末尾添加字段)
ALTER TABLE tTable RENAME TO MyTable;
添加一列:ALTER TABLE 表名 ADD COLUMN 列名 数据类型 限定符
ALTER TABLE MyTable ADD COLUMN AGE INTEGER;
导入数据
``INSERT INTO tTable SELECT OrderId, “”, ProductId FROM MyTable;
删除表 DROP TABLE 表名
DROP TABLE MyTable;
数据库升级顺序(如下图表示,需要给tb_user表中增加logintime字段)
->
- 如果tb_user表里面数据为空直接走X,将tb_user删除,重新创建新表。
- 如果不为空,则先将tb_user所在的库拷贝到另类外一个文件夹下面。(…/temp/user.db ,user.db中有tb_user表)。这么做是为了在升级过程中,如果升级失败,可以将数据还原。
修改tb_user表明为temp_tb_user
ALTER TABLE tb_user RENAME TO temp_tb_user;
创建新表tb_user
create table if not exists tb_user( name TEXT, password TEXT, user_id Text,logintime Integer);
将临时表temp_tb_user中的数据拷贝到tb_user中。可以调用sql语句
insert into tb_user(name ,password ,user_id ) select name ,password ,user_id from temp_tb_user;
删除临时表
DROP TABLE temp_tb_user;
最后数据库升级成功之后,删除刚才保存在另外一个文件夹下的临时文件(…/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参数就是今天的关键所在。
- 每个app版本,在内存卡中创建一个路径,保存当前数据库的版本version。app升级时需要做一次检查,如果被用户删掉了,再次创建,总之确保新安装的app打开之后,知道上一个版本的信息。
- 将上面的xml保存在assest目录下,app打开后,读取assest里面的version和本地比对,如果本地的小于version里面的版本则说明要升级。
- updateStep应该有许多组,里面的两个参数 versionFrom 就是本地存储的,versionTo 就是app当前需求的。如果这两个参数匹配ok,就按照里面的xml升级数据库。
- 当然升级的过程和上面说的顺序基本类似。
- 上面三个version参数就是今天的关键所在。
总结
- 优点 :简化了java代码的书写,一套代码可以应对所有版本的数据库升级,后期升级数据库不再需要更改java代码。
- 缺点 : 表越多,就需要维护越多的xml文件。不过相对于每次对比着版本号来重构java代码,我更愿意维护xml文件。