前言
作业系统的新版本开发结束,由于后台的习题信息的数据字段和个数改变了,所以Android本地的数据库表字段也需要做相应调整。记录下关于数据库的升级和降级相关知识。超简单 。:)
一,SQLite
SQLite是Android内置的一个轻量级的关系型数据库。数据库嘛,就是用来存储数据的。在什么情况下,Android开发需要用到数据库存储数据呢?
需要存储大量的结构化的数据,使用关系型数据库更方便。
二,主要方法
1.构造方法:
- public ClassName(Context context, String name, CursorFactory factory, int version)
参数1:上下文对象(MainActivity.this)、
参数2:数据库的名称、
参数3:创建Cursor的工厂类,参数为了可以自定义Cursor创建(ps:一般为null)、
参数4:数据库的版本
2.三个回调函数:
- onCreate(SQLiteDatabase db)
第一次运行才会执行,本地没有数据库,执行创建数据库 。
- onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
本地有数据库,覆盖安装的数据库版本比本地数据库版本高,执行数据库版本升级。
- onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion)
本地有数据库,覆盖安装的数据库版本比本地数据库版本低,执行数据库版本降级。如果没有重写该方法,应用将会崩溃。
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDatabaseOpenHelper extends SQLiteOpenHelper {
private static MyDatabaseOpenHelper instance = null;
private static String DBName = "student.db"; // 数据库名称
private static final int currentVersion = 2; // 数据库当前版本
private String tabName = "user"; // 表名
private MyDatabaseOpenHelper(Context context) {
super(context, DBName, null,currentVersion);
}
/**
* 通过单例获取SQLiteOpenHelper对象
* @param context
* @return
*/
public static MyDatabaseOpenHelper getInstance(Context context) {
if (instance == null) {
synchronized (MyDatabaseOpenHelper.class) {
if (instance == null)
instance = new MyDatabaseOpenHelper(context);
}
}
return instance;
}
/**
* 创建数据库(该方法没有数据库存在才会执行)
* @param db
*/
@Override
public void onCreate(SQLiteDatabase db) {
String sql = "create table if not exists "+tabName+" (_id integer primary key autoincrement, name nchar,age nchar)";
db.execSQL(sql);
}
/**
* 数据库版本升级(覆盖安装的数据库版本比本地数据库版本高)
* 比如原来版本是1,升级到2
* @param db
* @param oldVersion
* @param newVersion
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
switch (oldVersion) {
case 1:
//从版本1升级到版本2,可能的操作:
//A.增加telephone字段
String add_tel_sql = "alter table "+tabName+" add column telephone VARCHAR(20)";
db.execSQL(add_tel_sql);
//B.删除age字段 下面语句是无效的,sqlite不支持drop column
// String del_age_sql = "alter table "+tabName+" drop column age";
// db.execSQL(del_age_sql);
//换一种方法删除字段,可以新建一张表,将数据复制过去
// 1.原来的数据库表重命名为临时表
String create_temp_sql = "alter table "+tabName+" rename to _temp_user";
// 2.根据原表创建一张新表
String create_tab_sql = "create table if not exists "+tabName+" (_id integer primary key autoincrement, name nchar)";
// 3.将旧表的数据迁移至新表
String insert_data_sql = "insert into "+tabName+"(_id,name) select _id,name from _temp_user;";
// 4.删除临时表
String drop_tab_sql = "drop table _temp_user";
db.execSQL(create_temp_sql);
db.execSQL(create_tab_sql);
db.execSQL(insert_data_sql);
db.execSQL(drop_tab_sql);
//有个更好的方法,---根据原来的表,复制一张表出来
String copy_sql = "CREATE TABLE _temp_user as SELECT _id,name FROM user;";
db.execSQL(copy_sql);
break;
//如果还有更老的版本就继续判断,维护版本兼容性
}
}
/**
* 数据库版本降级(覆盖安装的数据库版本比本地数据库版本低)
* 比如原来版本是3,降级到2
* @param db
* @param oldVersion
* @param newVersion
*/
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//降级,和升级一样,根据版本号,来对数据库表进行修改
switch (oldVersion) {
case 3:
//从版本1升级到版本2,可能的操作:去掉字段
String copy_sql = "CREATE TABLE _temp_user as SELECT _id,name FROM user;";
db.execSQL(copy_sql);
String del_tab = "drop table user;";
db.execSQL(del_tab);
String rename_sql = "alter table _temp_user rename to user;";
db.execSQL(rename_sql);
break;
//如果还有其他的版本就继续判断,维护版本兼容性
}
}
}
三,注意
- 三个主要方法(onCreat,onUpgrade,onDowngrade)中的语句不要随便修改,因为涉及到本地数据库的更新,语句的修改需要同时更改数据库版本号,做好新旧版本的兼容。
- 如果表结构修改了,原来提供的一些crud操作方法,都需要修改,最好是重写帮助类SQLiteOpenHelper类,以防有方法遗漏,或者SQL语句(?,?,?)参数个数没对应上等等错误。
其他: 我的项目中有2个地方,使用了数据库:
1.批量音视频资源的缓存下载。 类似迅雷下载,Activity会显示下载中和下载完成的资源信息(进度,大小,名称等)
2.布置习题。多个Activity可以添加或删除需要布置的习题,且最后布置的时候,提交给服务器已选习题的所有信息(id,分值,题型等)
(还有一个地方,应该也可以做本地json文件缓存或数据库缓存:省市区学校的数据信息。嗯,想了想,这种个人信息选择,基本用户选一次,几乎不会再用了,没有存储的必要)
最后,有空再看看Google 组件 Room: 一个在SQLite上提供抽象层的持久存储库。
https://mp.weixin.qq.com/s/JH3XG39qhfuCKDX98To3zA
来源:CSDN
作者:我可以 陪你去看星星☆☆
链接:https://blog.csdn.net/u011109931/article/details/82688115