greenDao 3.x遇到数据库升级,且表结构中添加int类型字段问题。

【转载自http://blog.csdn.net/u013183495/article/details/53467746】不过在测试阶段发现问题还是存在,后来逐步调试过程中发现getTypeByClass()方法中,type.getName()的值为int。显然无法return。后来就添加了if(type.getName.equals(“int”)){type = Integer.class}。再次运行,升级成功。后来反过来查看转载的bolg里面的getTypeByClass()方法,其实已经做了相同的操作。不管怎样,记录一下。怕再次疏忽。

首先在试用GreenDao的时候,默认的数据库升级会先Drop表再Create,这样问题显而易见,如果版本已经上线必然不能接受

解决方法:网上有很多转载解决方案。一般是利用临时表转移2次数据

现在要说的问题:

       当某张表需要添加一个Int类型的列时,升级数据库则会报NOT NULL约束不通过,原因是 GreenDao建表时Int 类型 加了NOT NULL。而再数据转移的时候并没有Insert 该列。 

下面对之前网上的代码做一些调整:

  1. for (int j = 0; j < daoConfig.properties.length; j++) {  
  2.                String columnName = daoConfig.properties[j].columnName;  
  3.   
  4.                if (getColumns(db, tempTableName).contains(columnName)) {  
  5.                    properties.add(columnName);  
  6.                    propertiesQuery.add(columnName);  
  7.                } else {  
  8.                    try {  
  9.                       <span style=”color:#ff0000;”if (getTypeByClass(daoConfig.properties[j].type).equals(“INTEGER”)) {  
  10.                            propertiesQuery.add(”0 as ” + columnName);  
  11.                            properties.add(columnName);  
  12.                        }</span>  
  13.                    } catch (Exception e) {  
  14.                        e.printStackTrace();  
  15.                    }  
  16.                }  
  17.            }  
 for (int j = 0; j < daoConfig.properties.length; j++) {
                String columnName = daoConfig.properties[j].columnName;

                if (getColumns(db, tempTableName).contains(columnName)) {
                    properties.add(columnName);
                    propertiesQuery.add(columnName);
                } else {
                    try {
                        if (getTypeByClass(daoConfig.properties[j].type).equals("INTEGER")) {
                            propertiesQuery.add("0 as " + columnName);
                            properties.add(columnName);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

遍历新的表结构,发现新增的列的时候,从临时表查数据的时候,对应把新增的列默认填值  0 as columnName

该类全部代码如下:

  1. public class GreenDaoUpgrade {  
  2.     private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION = “MIGRATION HELPER - CLASS DOESN’T MATCH WITH THE CURRENT PARAMETERS”;  
  3.     private static GreenDaoUpgrade instance;  
  4.   
  5.     public static GreenDaoUpgrade getInstance() {  
  6.         if (instance == null) {  
  7.             instance = new GreenDaoUpgrade();  
  8.         }  
  9.         return instance;  
  10.     }  
  11.   
  12.     private static List<String> getColumns(Database db, String tableName) {  
  13.         List<String> columns = new ArrayList<>();  
  14.         Cursor cursor = null;  
  15.         try {  
  16.             cursor = db.rawQuery(”SELECT * FROM ” + tableName + “ limit 1”null);  
  17.             if (cursor != null) {  
  18.                 columns = new ArrayList<>(Arrays.asList(cursor.getColumnNames()));  
  19.             }  
  20.         } catch (Exception e) {  
  21.             Log.v(tableName, e.getMessage(), e);  
  22.             e.printStackTrace();  
  23.         } finally {  
  24.             if (cursor != null)  
  25.                 cursor.close();  
  26.         }  
  27.         return columns;  
  28.     }  
  29.   
  30.     public void migrate(Database db, Class<? extends AbstractDao<?, ?>>… daoClasses) {  
  31.         generateTempTables(db, daoClasses);  
  32.         DaoMaster.dropAllTables(db, true);  
  33.         DaoMaster.createAllTables(db, false);  
  34.         restoreData(db, daoClasses);  
  35.     }  
  36.   
  37.     private void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>… daoClasses) {  
  38.         for (int i = 0; i < daoClasses.length; i++) {  
  39.             DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);  
  40.   
  41.             String divider = ”“;  
  42.             String tableName = daoConfig.tablename;  
  43.             String tempTableName = daoConfig.tablename.concat(”_TEMP”);  
  44.             ArrayList<String> properties = new ArrayList<>();  
  45.   
  46.             StringBuilder createTableStringBuilder = new StringBuilder();  
  47.   
  48.             createTableStringBuilder.append(”CREATE TABLE ”).append(tempTableName).append(“ (“);  
  49.   
  50.             for (int j = 0; j < daoConfig.properties.length; j++) {  
  51.                 String columnName = daoConfig.properties[j].columnName;  
  52.   
  53.                 if (getColumns(db, tableName).contains(columnName)) {  
  54.                     properties.add(columnName);  
  55.   
  56.                     String type = null;  
  57.   
  58.                     try {  
  59.                         type = getTypeByClass(daoConfig.properties[j].type);  
  60.                     } catch (Exception exception) {  
  61.                         exception.printStackTrace();  
  62.                     }  
  63.   
  64.                     createTableStringBuilder.append(divider).append(columnName).append(” ”).append(type);  
  65.   
  66.                     if (daoConfig.properties[j].primaryKey) {  
  67.                         createTableStringBuilder.append(” PRIMARY KEY”);  
  68.                     }  
  69.   
  70.                     divider = ”,”;  
  71.                 }  
  72.             }  
  73.             createTableStringBuilder.append(”);”);  
  74.   
  75.             db.execSQL(createTableStringBuilder.toString());  
  76.   
  77.             StringBuilder insertTableStringBuilder = new StringBuilder();  
  78.   
  79.             insertTableStringBuilder.append(”INSERT INTO ”).append(tempTableName).append(“ (“);  
  80.             insertTableStringBuilder.append(TextUtils.join(”,”, properties));  
  81.             insertTableStringBuilder.append(”) SELECT ”);  
  82.             insertTableStringBuilder.append(TextUtils.join(”,”, properties));  
  83.             insertTableStringBuilder.append(” FROM ”).append(tableName).append(“;”);  
  84.   
  85.             db.execSQL(insertTableStringBuilder.toString());  
  86.         }  
  87.     }  
  88.   
  89.     private void restoreData(Database db, Class<? extends AbstractDao<?, ?>>… daoClasses) {  
  90.         for (int i = 0; i < daoClasses.length; i++) {  
  91.             DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);  
  92.   
  93.             String tableName = daoConfig.tablename;  
  94.             String tempTableName = daoConfig.tablename.concat(”_TEMP”);  
  95.             ArrayList<String> properties = new ArrayList();  
  96.             ArrayList<String> propertiesQuery = new ArrayList();  
  97.             for (int j = 0; j < daoConfig.properties.length; j++) {  
  98.                 String columnName = daoConfig.properties[j].columnName;  
  99.   
  100.                 if (getColumns(db, tempTableName).contains(columnName)) {  
  101.                     properties.add(columnName);  
  102.                     propertiesQuery.add(columnName);  
  103.                 } else {  
  104.                     try {  
  105.                         if (getTypeByClass(daoConfig.properties[j].type).equals(“INTEGER”)) {  
  106.                             propertiesQuery.add(”0 as ” + columnName);  
  107.                             properties.add(columnName);  
  108.                         }  
  109.                     } catch (Exception e) {  
  110.                         e.printStackTrace();  
  111.                     }  
  112.                 }  
  113.             }  
  114.   
  115.             StringBuilder insertTableStringBuilder = new StringBuilder();  
  116.   
  117.             insertTableStringBuilder.append(”INSERT INTO ”).append(tableName).append(“ (“);  
  118.             insertTableStringBuilder.append(TextUtils.join(”,”, properties));  
  119.             insertTableStringBuilder.append(”) SELECT ”);  
  120.             insertTableStringBuilder.append(TextUtils.join(”,”, propertiesQuery));  
  121.             insertTableStringBuilder.append(” FROM ”).append(tempTableName).append(“;”);  
  122.   
  123.             StringBuilder dropTableStringBuilder = new StringBuilder();  
  124.   
  125.             dropTableStringBuilder.append(”DROP TABLE ”).append(tempTableName);  
  126.   
  127.             db.execSQL(insertTableStringBuilder.toString());  
  128.             db.execSQL(dropTableStringBuilder.toString());  
  129.         }  
  130.     }  
  131.   
  132.     private String getTypeByClass(Class<?> type) throws Exception {  
  133.         if (type.equals(String.class)) {  
  134.             return “TEXT”;  
  135.         }  
  136.         if (type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class) || type.equals(int.class)) {  
  137.             return “INTEGER”;  
  138.         }  
  139.         if (type.equals(Boolean.class) || type.equals(boolean.class)) {  
  140.             return “BOOLEAN”;  
  141.         }  
  142.   
  143.         Exception exception = new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(“ - Class: ”).concat(type.toString()));  
  144.         exception.printStackTrace();  
  145.         throw exception;  
  146.     }  
  147. }  
public class GreenDaoUpgrade { 
private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION = "MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS";
private static GreenDaoUpgrade instance;
public static GreenDaoUpgrade getInstance() {
    if (instance == null) {
        instance = new GreenDaoUpgrade();
    }
    return instance;
}

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

public void migrate(Database db, Class&lt;? extends AbstractDao&lt;?, ?&gt;&gt;... daoClasses) {
    generateTempTables(db, daoClasses);
    DaoMaster.dropAllTables(db, true);
    DaoMaster.createAllTables(db, false);
    restoreData(db, daoClasses);
}

private void generateTempTables(Database db, Class&lt;? extends AbstractDao&lt;?, ?&gt;&gt;... daoClasses) {
    for (int i = 0; i &lt; daoClasses.length; i++) {
        DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);

        String divider = "";
        String tableName = daoConfig.tablename;
        String tempTableName = daoConfig.tablename.concat("_TEMP");
        ArrayList&lt;String&gt; properties = new ArrayList&lt;&gt;();

        StringBuilder createTableStringBuilder = new StringBuilder();

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

        for (int j = 0; j &lt; 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());
    }
}

private void restoreData(Database db, Class&lt;? extends AbstractDao&lt;?, ?&gt;&gt;... daoClasses) {
    for (int i = 0; i &lt; daoClasses.length; i++) {
        DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);

        String tableName = daoConfig.tablename;
        String tempTableName = daoConfig.tablename.concat("_TEMP");
        ArrayList&lt;String&gt; properties = new ArrayList();
        ArrayList&lt;String&gt; propertiesQuery = new ArrayList();
        for (int j = 0; j &lt; daoConfig.properties.length; j++) {
            String columnName = daoConfig.properties[j].columnName;

            if (getColumns(db, tempTableName).contains(columnName)) {
                properties.add(columnName);
                propertiesQuery.add(columnName);
            } else {
                try {
                    if (getTypeByClass(daoConfig.properties[j].type).equals("INTEGER")) {
                        propertiesQuery.add("0 as " + columnName);
                        properties.add(columnName);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        StringBuilder insertTableStringBuilder = new StringBuilder();

        insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
        insertTableStringBuilder.append(TextUtils.join(",", properties));
        insertTableStringBuilder.append(") SELECT ");
        insertTableStringBuilder.append(TextUtils.join(",", propertiesQuery));
        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&lt;?&gt; type) throws Exception {
    if (type.equals(String.class)) {
        return "TEXT";
    }
    if (type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class) || type.equals(int.class)) {
        return "INTEGER";
    }
    if (type.equals(Boolean.class) || type.equals(boolean.class)) {
        return "BOOLEAN";
    }

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

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值