GreenDAO数据库版本升级

来源:互联网 发布:火炮兰灵族捏脸数据 编辑:程序博客网 时间:2024/04/19 04:04

GreenDAO在进行默认的数据库升级时,会采取先删除所有的表,再全部重新建的操作,这就意味着所有的数据都会遗失。

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");    dropAllTables(db, true);//删除所有的表    onCreate(db);//重新建表}
因此为了在升级数据库时保存原有的数据,必须重写下onUpgrade里的代码。


说到底,保留数据的升级数据库的流程就是:

1.建一个零时表作为升级后的表,包括自己新建的字段。

2.将原来的表改名为零时表。

3.把原来的表中的数据copy到新建的零时表里。


此处贴上网上的一个数据转移的成品代码:

package com.android.mygreendao;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.text.TextUtils;import android.util.Log;import de.greenrobot.dao.AbstractDao;import de.greenrobot.dao.internal.DaoConfig;import com.example.bean.DaoMaster;import java.util.ArrayList;import java.util.Arrays;import java.util.List;/** * Created by Fly on 2015/11/7. */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(SQLiteDatabase db, Class<? extends AbstractDao<?, ?>>... daoClasses) {        generateTempTables(db, daoClasses);        DaoMaster.dropAllTables(db, true);        DaoMaster.createAllTables(db, false);        restoreData(db, daoClasses);    }    private void generateTempTables(SQLiteDatabase db, Class<? extends 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<String> properties = new ArrayList<String>();            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) {                    }                    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());        }    }    private void restoreData(SQLiteDatabase db, Class<? extends 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<String> 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()));        throw exception;    }    private static List<String> getColumns(SQLiteDatabase db, String tableName) {        List<String> columns = new ArrayList<String>();        Cursor cursor = null;        try {            cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 1", null);            if (cursor != null) {                columns = new ArrayList<String>(Arrays.asList(cursor.getColumnNames()));            }        } catch (Exception e) {            Log.v(tableName, e.getMessage(), e);            e.printStackTrace();        } finally {            if (cursor != null)                cursor.close();        }        return columns;    }}

整个升级的过程分为:

1.在生成DAO文件的java代码里加入你要新建的或者修改的表的信息,run。

2.此时所有的DAO文件和表文件全部重置,改变DaoMaster文件里的SCHEMA_VERSION,改成比刚才大1(一定要高于刚才的值,不然会报错无法更新)。

3.重写onUpgrade里的代码:

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {    Log.i("greenDAO", "Upgrading schema from version " + oldVersion + " to " + newVersion + " by dropping all tables");    //dropAllTables(db, true);    //onCreate(db);    MigrationHelper.getInstance().migrate(db,NoteDao.class);}

至此,保留数据的GreenDAO数据库升级完成。

1 0
原创粉丝点击