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;
            //如果还有其他的版本就继续判断,维护版本兼容性
        }
    }
}

三,注意

  1. 三个主要方法(onCreat,onUpgrade,onDowngrade)中的语句不要随便修改,因为涉及到本地数据库的更新,语句的修改需要同时更改数据库版本号,做好新旧版本的兼容。
  2. 如果表结构修改了,原来提供的一些crud操作方法,都需要修改,最好是重写帮助类SQLiteOpenHelper类,以防有方法遗漏,或者SQL语句(?,?,?)参数个数没对应上等等错误。

 

其他: 我的项目中有2个地方,使用了数据库:

1.批量音视频资源的缓存下载。 类似迅雷下载,Activity会显示下载中和下载完成的资源信息(进度,大小,名称等)

2.布置习题。多个Activity可以添加或删除需要布置的习题,且最后布置的时候,提交给服务器已选习题的所有信息(id,分值,题型等)

(还有一个地方,应该也可以做本地json文件缓存或数据库缓存:省市区学校的数据信息。嗯,想了想,这种个人信息选择,基本用户选一次,几乎不会再用了,没有存储的必要)

 

最后,有空再看看Google 组件 Room: 一个在SQLite上提供抽象层的持久存储库。

https://mp.weixin.qq.com/s/JH3XG39qhfuCKDX98To3zA

 

你可能感兴趣的:(Android技术学习)