Android 数据库SQLite升级降级
前言
作业系统的新版本开发结束,由于后台的习题信息的数据字段和个数改变了,所以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
更多相关文章
- Android中Log.d和Log.v如何实现在release版本不输出
- Android设备中几种YUV420p转rgb视频帧方法效率比较
- Android Service使用方法--简单音乐播放实例
- ios与android语音通用方案 编译libopencore-amr xcode4.5/ios6版
- Android中Math取整的三个方法
- Android Studio启动时卡在Fetching Android SDK 以及导入Eclipse
- Google 菜市场(Android Market)上不去的解决方法