Android greedao数据库简单的升级

首先:

greenDAO是一款开源的面向 Android 的轻便、快捷的 ORM 框架,将 Java 对象映射到 SQLite  数据库中,我们操作数据库的时候,无需要编写复杂的 SQL语句, 在性能方面,greenDAO 针对 Android 进行了高度优化,  最小的内存开销 、依赖体积小 同时还是支持数据库加密。

下面连接是集成和使用的详细说明:GreenDao集成和使用

开始上代码:

1.创建greedao数据库

Android greedao数据库简单的升级_第1张图片

创建的表为


另外还有DAOMaster、DAOSession。DAOMaster主要是负责数据库创建和升级,DAOSession负责获得实体类的xxxDAO,来进行增删改查。

DAOMaster内部有个OpenHelper,继承DatabaseOpenHelperDatabaseOpenHelper又继承SQLiteOpenHelper

另外,DAOMasterDevOpenHelper,在升级数据库的时候会把所有表删除掉,然后创建新的表,会会照成原始数据的缺失。)


Android greedao数据库简单的升级_第2张图片

可以看到,OpenHelper就是SQLiteOpenHelper的封装,且是抽象类,所以重点来了:

数据库升级 需要我们自行处理,即继承OnUpgrade()。那这样就和以往SQLiteOpenHelper一样,需要判断版本号,然后写SQL进行新增字段或新增表。这样显然不好,我们就是不想写SQL的,而且版本号判断维护麻烦。

所以怎么办?有办法:

1.在根目录的build.gradle文件的repositories内添加如下代码:

Android greedao数据库简单的升级_第3张图片

2。添加依赖


3.继承DaoMaster.OpenHelper,自定义OnUpgrade()

Android greedao数据库简单的升级_第4张图片

重点:onUpgrade方法中 

MigrationHelper.getInstance().migrate(db, AnimalDao.class);
这局话的意思是:升级数据库

这一行代码的实现原理,实际就是以下思路。 在此基础上,可以保留原数据进行升级数据库。
(1)首先创建临时表(数据格式和原表一模一样)。 
(2)把当前表的数据插入到临时表中去。 
(3)删除掉原表,创建新表。 
(4)把临时表数据插入到新表中去,然后删除临时表。 

因为大牛已经对这些进行封装,所以直接把MigrationHelper代码贴出来。

不难看出,migrate()方法按照以上思路完成的。

package com.example.d.myapplication;

import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;

import com.example.d.myapplication.dao.DaoMaster;

import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.internal.DaoConfig;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MigrationHelper {

    private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION = "MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS";
    private static MigrationHelper instance;

    public static MigrationHelper getInstance() {
        if (instance == null) {
            instance = new MigrationHelper();
        }
        return instance;
    }

    public void migrate(Database db, Classextends AbstractDao, ?>>... daoClasses) {

        generateTempTables(db, daoClasses);
        DaoMaster.dropAllTables(db, true);
        DaoMaster.createAllTables(db, false);
        restoreData(db, daoClasses);
    }

    /**
     * 生成临时列表
     *
     * @param db
     * @param daoClasses
     */
    private void generateTempTables(Database db, Classextends AbstractDao, ?>>... daoClasses) {
        for (int i = 0; i < daoClasses.length; i++) {
            DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);

            String divider = "";
            String tableName = daoConfig.tablename;
            String tempTableName = daoConfig.tablename.concat("_TEMP");
            ArrayList properties = new ArrayList<>();

            StringBuilder createTableStringBuilder = new StringBuilder();

            createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" (");

            for (int j = 0; j < daoConfig.properties.length; j++) {
                String columnName = daoConfig.properties[j].columnName;

                if (getColumns(db, tableName).contains(columnName)) {
                    properties.add(columnName);

                    String type = null;

                    try {
                        type = getTypeByClass(daoConfig.properties[j].type);
                    } catch (Exception exception) {
                        exception.printStackTrace();
                    }

                    createTableStringBuilder.append(divider).append(columnName).append(" ").append(type);

                    if (daoConfig.properties[j].primaryKey) {
                        createTableStringBuilder.append(" PRIMARY KEY");
                    }

                    divider = ",";
                }
            }
            createTableStringBuilder.append(");");

            db.execSQL(createTableStringBuilder.toString());

            StringBuilder insertTableStringBuilder = new StringBuilder();

            insertTableStringBuilder.append("INSERT INTO ").append(tempTableName).append(" (");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(") SELECT ");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(" FROM ").append(tableName).append(";");

            db.execSQL(insertTableStringBuilder.toString());

        }
    }

    /**
     * 存储新的数据库表 以及数据
     *
     * @param db
     * @param daoClasses
     */
    private void restoreData(Database db, Classextends AbstractDao, ?>>... daoClasses) {
        for (int i = 0; i < daoClasses.length; i++) {
            DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
            String tableName = daoConfig.tablename;
            String tempTableName = daoConfig.tablename.concat("_TEMP");
            ArrayList properties = new ArrayList();

            for (int j = 0; j < daoConfig.properties.length; j++) {
                String columnName = daoConfig.properties[j].columnName;

                if (getColumns(db, tempTableName).contains(columnName)) {
                    properties.add(columnName);
                }
            }

            StringBuilder insertTableStringBuilder = new StringBuilder();

            insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(") SELECT ");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");

            StringBuilder dropTableStringBuilder = new StringBuilder();
            dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);
            db.execSQL(insertTableStringBuilder.toString());
            db.execSQL(dropTableStringBuilder.toString());
        }
    }

    private String getTypeByClass(Class type) throws Exception {
        if (type.equals(String.class)) {
            return "TEXT";
        }
        if (type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class)) {
            return "INTEGER";
        }
        if (type.equals(Boolean.class)) {
            return "BOOLEAN";
        }

        Exception exception = new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString()));
        exception.printStackTrace();
        throw exception;
    }

    private List getColumns(Database db, String tableName) {
        List columns = new ArrayList<>();
        Cursor cursor = null;
        try {
            cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 1", null);
            if (cursor != null) {
                columns = new ArrayList<>(Arrays.asList(cursor.getColumnNames()));
            }
        } catch (Exception e) {
            Log.v(tableName, e.getMessage(), e);
            e.printStackTrace();
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return columns;
    }

}

升级完毕!!!

不对的地方多多指教

参考网址:https://blog.csdn.net/hfy8971613/article/details/79595096


谢谢。

你可能感兴趣的:(Android greedao数据库简单的升级)