GreenDao 詳解
GreenDao 簡(jiǎn)介
GreenDAO 是一款開源的面向 Android 的輕便休弃、快捷的 ORM 框架奕枢,將 Java 對(duì)象映射到 SQLite 數(shù)據(jù)庫(kù)中得院,我們操作數(shù)據(jù)庫(kù)的時(shí)候票编,不在需要編寫復(fù)雜的 SQL語(yǔ)句蔫慧, 在性能方面滓走,GreenDAO 針對(duì) Android 進(jìn)行了高度優(yōu)化, 最小的內(nèi)存開銷 嗓化、依賴體積小 同時(shí)還是支持?jǐn)?shù)據(jù)庫(kù)加密棠涮。
GreenDAO 官網(wǎng)地址:http://greenrobot.org/greendao/
PS: 官網(wǎng)上,GreenDAO官方推薦最新的應(yīng)用使用最好使用新的數(shù)據(jù)庫(kù)框架 ObjectBox刺覆。
升級(jí)的問(wèn)題:
主鍵問(wèn)題:
默認(rèn)可以用@Id來(lái)設(shè)置主鍵严肪,但是如果需要復(fù)合主鍵的要怎么處理呢:
如果是sql可以這樣寫:
create table test
(
name varchar(19),
id number,
value varchar(10),
primary key (name,id)
)
但是 GreenDao 需要使用 約束來(lái)實(shí)現(xiàn): 是個(gè)例子:
@Entity(nameInDb = "MoodBean", indexes = {@Index(value = "id,uid", unique = true)})
public class MoodBean {
/**
* 20180827 日期轉(zhuǎn)為數(shù)值
*/
public long id = 0;
/**
* 用戶Id
*/
public String uid = "";
/**
* 當(dāng)前日期字符串,:如2018-08-28
*/
public String date = "";
/**
* 心情類型: 0:未選擇:
*/
public int moodType = 0;
}
主鍵最好是用基礎(chǔ)類型的包裝類谦屑,如果是基礎(chǔ)類型驳糯,GreenDao轉(zhuǎn)化為SQL的時(shí)候會(huì)要求自動(dòng)加上 not null 限制。
long 氢橙,int 等會(huì)對(duì)應(yīng)是數(shù)據(jù)庫(kù)的 INTEGER
"CREATE TABLE " + constraint + "\"RecordBean\" (" + //
"\"ID\" INTEGER NOT NULL ," + // 0: id
"\"UID\" TEXT," + // 1: uid
數(shù)據(jù)庫(kù)升級(jí)
自動(dòng)生成的DAOMaster里面會(huì)生成默認(rèn)的數(shù)據(jù)庫(kù)升級(jí)類:
/** * WARNING: Drops all table on Upgrade! Use only during development. */
public static class DevOpenHelper extends OpenHelper {
public DevOpenHelper(Context context, String name, CursorFactory factory) {
super(context, name, factory);
}
@Override
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);
}
}
可以看到酝枢,數(shù)據(jù)庫(kù)默認(rèn)的行為是:刪掉所有數(shù)據(jù)庫(kù),在重新建數(shù)據(jù)庫(kù)悍手。
但是這樣會(huì) 導(dǎo)致已經(jīng)存在的數(shù)據(jù)都被清掉帘睦。因此我需要繼承OpenHelper來(lái)實(shí)現(xiàn)自己的數(shù)據(jù)庫(kù)升級(jí)方法:
public class CalendarDaoOpenHelper extends DaoMaster.OpenHelper {
public CalendarDaoOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
super.onUpgrade(db, oldVersion, newVersion);
if (oldVersion == newVersion) {
return;
}
LogUtil.d(String.format("版本升級(jí):oldVersion= %s,newVersion= %s ", oldVersion, newVersion));
switch (oldVersion) {
case 1:
//todo
break;
case 2:
//todo
break;
default:
break;
}
}
}
或者使用GitHub上現(xiàn)成的庫(kù):
https://github.com/yuweiguocn/GreenDaoUpgradeHelper
通過(guò) MigrationHelper 在刪表重建的過(guò)程中袍患,使用臨時(shí)表保存數(shù)據(jù)并還原。
public class MySQLiteOpenHelper extends DaoMaster.OpenHelper {
public MySQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
MigrationHelper.migrate(db, TestDataDao.class, TestData2Dao.class, TestData3Dao.class);
}
}
// 初始化
MigrationHelper.DEBUG = true; //如果你想查看日志信息官脓,請(qǐng)將 DEBUG 設(shè)置為 true
MySQLiteOpenHelper helper = new MySQLiteOpenHelper(this, "test.db", null);
DaoMaster daoMaster = new DaoMaster(helper.getWritableDatabase());
translate緩存問(wèn)題
對(duì)象字段用 @translate 標(biāo)識(shí)协怒,代表這個(gè)字段不會(huì)被保存到數(shù)據(jù)庫(kù)中。但是會(huì)被緩存到是內(nèi)存卑笨。
如果要 讓下次查詢的 對(duì)象字段還原孕暇,需要調(diào)用方法來(lái)強(qiáng)制清除緩存:
com.babytree.apps.pregnancy.db.DaoSession#clear