复习数据库相关知识
前几天遇到的问题,app升级的时候,如果数据库结构有变化,该如何升级数据库?
首先我们来看看数据库的创建过程:
1、当我们在使用数据库时会调用getWritableDatabase()和getReadableDatabase()方法,而他们都调用了同一个方法getDatabaseLocked(false);
该方法中首先会判断指定的数据库是否存在,不存在则调SQLiteDatabase.create创建, onCreate只在数据库第一次创建时才执行;(有兴趣同学可以产看源码)
2、关于升级部分,该方法中还有有这样一段代码:
final int version = db.getVersion();
if (version != mNewVersion) {
if (db.isReadOnly()) {
throw new SQLiteException("Can't upgrade read-only database from version " +
db.getVersion() + " to " + mNewVersion + ": " + mName);
}
db.beginTransaction();
try {
if (version == 0) {
onCreate(db);
} else {
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
onOpen(db);
代码很简单,当当前版本号>老的版本号时,会调用onUpgrade方法,所以我们只需要在升级app时,填写大于之前版本号的数字,在使用数据库时onUpgrade方法即可自动被调用,所以我们在该方法中修改数据升级的逻辑即可,升级数据库。
3.升级逻辑的两种方式:
假如,数据库的版本有1 ,2,3
如何兼容所有的升级方案有两种方式:
a. onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
int curVersion = oldVersion;
if(curVersion == 1){
//1-2的升级逻辑
curVersion =2;
}
if(curVersion == 2){
//2-3的升级逻辑
curVersion =3;
}
}
b. onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
switch(newVersion){
case 2:
//1-2的升级逻辑;
case 3:
if(oldVersion == 1){
//1-3的升级逻辑
}else if(oldVersion == 2){
//2-3的升级逻辑
}
}
}
两种升级方式的对比:
a.逻辑简单,维护简单,但升级的时候从1-3可能消耗的时间长
b.逻辑复杂,维护复杂,但升级的时间只会比a短
升级逻辑:
a.简单的数据库修改,例如数据库只是添加一列:
--数据库 表结构 增加一列
String sqlCmd = “alter table city_test add column address char(100)“;
db.execSQL(renameSql);
b.数据库表变化比较大,会分为几步处理
开启事务:
db.beginTransaction();
1.重名名旧的数据库表名:
String renameSql = "ALTER TABLE account RENAME TO account_temp";
2.创建新表:这个命令不懂建议先复习数据库命令:http://www.runoob.com/sqlite/sqlite-alter-command.html
3.将旧表的可用数据存储到新表:
String copyDataSql = "insert into account(accountId,nickName,iconUrl) Select accountId,nickName,iconUrl from account_temp";
4.删除旧表:
String delTableSql = "DROP TABLE account_temp";
成功后,关闭事务
db.setTransactionSuccessful();
db.endTransaction()
备注:SQLite更多的数据库语句命令,可参考网页:
http://www.runoob.com/sqlite/sqlite-alter-command.html
http://www.yiibai.com/sqlite/sqlite_insert_query.html
数据库基础命令:
表结构操作:
create:创建表
drop:删除表
alter:修改表结构
表数据操作:
select:查询表数据
insert:插入表数据
update:更新表数据
delete:删除表数据
查询中特殊关键字
Like (大小写不敏感): %:0个或者多个字符,_:代表单个字符
GLOB (大小写敏感): *:0个或者多个, ? :代表单个字符
Limit: Select * from city limit 10;:取city表的前十条记录
OFFSET: Select * from city limit 10 offset 10; --取city表从11条记录开始的十条记录
order by:选择出来的数据排序(asc升序,desc降序)
SQLite的约束条件:
NOT NULL 约束:确保某列不能有 NULL 值。
DEFAULT 约束:当某列没有指定值时,为该列提供默认值。
UNIQUE 约束:确保某列中的所有值是不同的。
PRIMARY Key 约束:唯一标识数据库表中的各行/记录。
CHECK 约束:CHECK 约束确保某列中的所有值满足一定条件。