Android中使用GreenDao的坑整理
- 1,GreenDao更新的坑
- (1)更新處使用Dao()建立表後資料庫進行資料庫操作失敗
1,GreenDao更新的坑
(1)更新處使用Dao()建立表後資料庫進行資料庫操作失敗
場景:在某一個版本更新處,如果使用GreenDao自帶的Dao.createTable()來建立表。并且在目前版本或者後續版本做了該表的資料移動,或者使用其他sql語句寫成的操作,然後容易導緻報錯。
報錯原因通常會被sql語句try-catch住,而且資料庫更新在app啟動時期,調試困難比較大。
該問題出在:後續版本中如果對出問題的表進行了列增加,會在前面建表處建立最新的表再進行sql語句操作。但是由于sql語句中字段未覆寫全部資料庫字段(已經新增),導緻報錯走了catch。
例子:
//在某一個版本處更新
case VERSION_32:
//建立新表
KeywordCustomRecordDao.createTable(db,true);
insertNotificationIntoKeywordCustomRecordData(db);
break;
//建立表後做表的資料遷移
private void insertNotificationIntoKeywordCustomRecordData(Database db) {
int customPriority = KeyWordAddFragment.KEY_KEYWORD_PROPERTY;
int i = 0;
Cursor cursor = db.rawQuery("SELECT * FROM NOTIFICATION_KEYWORD", null);
try {
if (cursor != null && cursor.moveToFirst()) {
do {
Long recordId = cursor.getLong(cursor.getColumnIndex("_id"));
String word = cursor.getString(cursor.getColumnIndex("WORD"));
Integer showType = cursor.getInt(cursor.getColumnIndex("SHOW_TYPE"));
Long timestamp = cursor.getLong(cursor.getColumnIndex("TIMESTAMP"));
String recordedSql = "INSERT INTO KEYWORD_CUSTOM_RECORD(_id,NAME,SHOW_TYPE,INCLUDE,EXCLUDE"
+ ",IS_EFFECT,IS_ALL_APP,NOTICE_SETTING,IS_FLOATING,IS_KEYWORD_HIGH,PRIORITY,TIMESTAMP"
+ ",SKY_RULE,SKY_BACKGROUND_URL,SKY_CONTENT,SKY_FLOAT_NOTIFICATION_URL,SKY_POPUP_TITLE"
+ ",SKY_POPUP_CONTENT)values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
db.execSQL(recordedSql, new Object[] {recordId, word, 1, word, "", true, true, showType, false, true,
(customPriority + (i++)), timestamp, "", "", "", "", "", ""});
} while (cursor.moveToNext());
}
} catch (Exception e) {
// do nothing
} finally {
if (cursor != null) {
cursor.close();
}
}
}
該操作中,execsql語句執行過程中會因為找不到字段而報錯。
解決方法:在建立資料庫表後,如果對表進行sql操作,且後續版本會新增字段的話。就不能使用greendao自帶的建立資料庫表的dao.createTable()操作。而是直接使用sql語句進行表建立,這樣建立的表字段和目前版本的字段數量保持一緻,進而避免出錯。
sql建立表語句例如下:
private void createCustomRecordTable(Database db, boolean ifNotExists) {
String constraint = ifNotExists ? "IF NOT EXISTS " : "";
db.execSQL("CREATE TABLE " + constraint + "\"KEYWORD_CUSTOM_RECORD\" (" + //
"\"_id\" INTEGER PRIMARY KEY AUTOINCREMENT ," + // 0: id
"\"NAME\" TEXT," + // 1: name
"\"SHOW_TYPE\" INTEGER NOT NULL ," + // 2: showType
"\"INCLUDE\" TEXT," + // 3: include
"\"EXCLUDE\" TEXT," + // 4: exclude
}
以上。