GreenDao存儲自定義類型對象

需求場景:sqlite數(shù)據(jù)庫只能直接存儲數(shù)字渗钉、字符串晌姚、日期等簡單類型,如果要存儲一個(gè)復(fù)雜對象的話需要把對象拆解為一個(gè)個(gè)簡單數(shù)據(jù)類型挥唠,畢竟再復(fù)雜的數(shù)據(jù)類型也是由簡單數(shù)據(jù)類型組合而來宝磨。本以為大名鼎鼎的GreenDao可以幫我們智能拆解、組裝對象世囊,結(jié)果搜了一圈竟然找不到?jīng)]找到存儲自定義類型的辦法窿祥。

好在在官方文檔上找到解決方案:

@Entity
public class User {
    @Id
    private Long id;

    @Convert(converter = RoleConverter.class, dbType = Integer.class)
    private Role role;

    public enum Role {
        DEFAULT(0), AUTHOR(1), ADMIN(2);

        final int id;

        Role(int id) {
            this.id = id;
        }
    }

    public static class RoleConverter implements PropertyConverter<Role, Integer> {
        @Override
        public Role convertToEntityProperty(Integer databaseValue) {
            if (databaseValue == null) {
                return null;
            }
            for (Role role : Role.values()) {
                if (role.id == databaseValue) {
                    return role;
                }
            }
            return Role.DEFAULT;
        }

        @Override
        public Integer convertToDatabaseValue(Role entityProperty) {
            return entityProperty == null ? null : entityProperty.id;
        }
    }
}

可以看到這個(gè)實(shí)體類里包含了一個(gè)自定義的枚舉類型Role晒衩,在該類型上加了一個(gè)@Convert注解听系,括號里面指定了用于轉(zhuǎn)換對象類型和數(shù)據(jù)庫類型的converter類,以及該對象存儲在數(shù)據(jù)庫中的類型靠胜。

再來看看這個(gè)converter類做了什么事情浪漠。很簡單,它實(shí)現(xiàn)了PropertyConverter接口该镣,里面有兩個(gè)方法必盖,convertToEntityProperty是將數(shù)據(jù)庫中的類型轉(zhuǎn)換為java實(shí)體類俱饿;convertToDatabaseValue方法相反,將java實(shí)體類轉(zhuǎn)換為數(shù)據(jù)庫中的類型失驶。我們只要在這兩個(gè)方法里定義相應(yīng)的轉(zhuǎn)換規(guī)則即可枣购。

看上去也不難擦耀,思路也很清晰涩堤。但是這個(gè)例子里的Enum類型要轉(zhuǎn)換為int類型還是比較簡單的,而筆者要存儲的對象要復(fù)雜的多吁系。這還是解決不了我的需求鞍谆辍(欲哭無淚)。

如何快速簡單的把一個(gè)復(fù)雜的數(shù)據(jù)類型轉(zhuǎn)換為簡單數(shù)據(jù)類型蕴坪,而且還要能精準(zhǔn)地轉(zhuǎn)換回來敬锐?好像是有這么一個(gè)東西滞造,json!Mφ买窟!json作為客戶端和服務(wù)端之間數(shù)據(jù)傳遞的載體,確實(shí)滿足我們現(xiàn)在的業(yè)務(wù)需求瞳购。更棒的是我們有g(shù)son這個(gè)解析框架來幫我們做轉(zhuǎn)換!那么我們要做的事真就是無腦操作了亏推。來看看我的Demo代碼:

@Entity(
)
public class Zoo {
    indexes = {
            @Index(value = "zooId DESC, zoneId DESC", unique = true)
    }
    @Id(autoincrement = true)
    private Long id;

    @Property
    private Long zooId;

    @Property
    private Long zoneId;

    @Property
    @Convert(converter = CatConverter.class, columnType = String.class)
    private Cat cat;

    public static class CatConverter implements PropertyConverter<Cat, String> {
        @Override
        public Cat convertToEntityProperty(String databaseValue) {
            if (databaseValue == null) {
                return null;
            }
            return new Gson().fromJson(databaseValue, Cat.class);
        }

        @Override
        public String convertToDatabaseValue(Cat entityProperty) {
            if (entityProperty == null) {
                return null;
            }
            return new Gson().toJson(entityProperty);
        }
    }
}

這里我新建了一個(gè)叫Zoo的實(shí)體学赛,里面包含一個(gè)Cat類型的對象,且不管該對象復(fù)雜與簡單吞杭,我們甚至都不需要關(guān)心它的具體數(shù)據(jù)結(jié)構(gòu)盏浇。加上@Convert注解后新建一個(gè)CatConverter類(注意converter類是內(nèi)部類的話要聲明為static),因?yàn)槲覀円D(zhuǎn)換為json存儲起來所以數(shù)據(jù)庫中的類型肯定是String了芽狗,標(biāo)注好泛型绢掰,做一個(gè)參數(shù)的非空判斷(良好習(xí)慣)。在轉(zhuǎn)換的方法內(nèi)部我們只需要利用gson將數(shù)據(jù)在java bean類型和json之間轉(zhuǎn)換,就可以完成我們的需求了滴劲,是不是很簡單呢攻晒?

Cat miaomiao = new Cat(13, "miaomiao");
Cat jingjing = new Cat(13, "jingjing");
ZooDao zooDao = daoSession.getZooDao();
zooDao.insertOrReplace(new Zoo(null, 222L, 333L, miaomiao));
zooDao.insertOrReplace(new Zoo(null, 222L, 331L, jingjing));

List<Zoo> zoos = zooDao.queryBuilder().list();
for (Zoo zoo : zoos) {
    Log.d("xxx", zoo.getZooId()+":"+zoo.getZoneId()+":"+zoo.getCat().toString());
}

寫完代碼后make project自動生成新的ZooDao類(有興趣的可以看看這個(gè)類班挖,其實(shí)也挺簡單的)鲁捏,不放心趕緊實(shí)驗(yàn)一下能不能直接存取自定義對象了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末萧芙,一起剝皮案震驚了整個(gè)濱河市碴萧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌末购,老刑警劉巖破喻,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異盟榴,居然都是意外死亡曹质,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門擎场,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羽德,“玉大人,你說我怎么就攤上這事迅办≌玻” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵站欺,是天一觀的道長姨夹。 經(jīng)常有香客問我,道長矾策,這世上最難降的妖魔是什么磷账? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮贾虽,結(jié)果婚禮上逃糟,老公的妹妹穿的比我還像新娘。我一直安慰自己蓬豁,他們只是感情好绰咽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著地粪,像睡著了一般取募。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上驶忌,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天矛辕,我揣著相機(jī)與錄音,去河邊找鬼付魔。 笑死聊品,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的几苍。 我是一名探鬼主播翻屈,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼妻坝!你這毒婦竟也來了伸眶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤刽宪,失蹤者是張志新(化名)和其女友劉穎厘贼,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體圣拄,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嘴秸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了庇谆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岳掐。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖饭耳,靈堂內(nèi)的尸體忽然破棺而出串述,到底是詐尸還是另有隱情,我是刑警寧澤寞肖,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布纲酗,位于F島的核電站,受9級特大地震影響新蟆,放射性物質(zhì)發(fā)生泄漏耕姊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一栅葡、第九天 我趴在偏房一處隱蔽的房頂上張望茉兰。 院中可真熱鬧,春花似錦欣簇、人聲如沸规脸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽莫鸭。三九已至,卻和暖如春横殴,著一層夾襖步出監(jiān)牢的瞬間被因,已是汗流浹背卿拴。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留梨与,地道東北人堕花。 一個(gè)月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像粥鞋,于是被迫代替她去往敵國和親缘挽。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理呻粹,服務(wù)發(fā)現(xiàn)壕曼,斷路器,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • 最近公司項(xiàng)目選用GreenDao作為Android客戶端本地?cái)?shù)據(jù)庫的對象關(guān)系映射框架等浊。對于GreenDao雖然以往...
    業(yè)松閱讀 10,908評論 17 18
  • (1) 當(dāng)程玄把手鏈戴在我手上的那一刻筹燕,我有一種說不出來的感覺伴榔,怪怪的。 他說:“季凡庄萎,把手伸出來踪少。” 他說:“季...
    貓左閱讀 244評論 0 3
  • 敏感話題的搞笑版本 唐唐一年級的生活已經(jīng)過了一半糠涛,轉(zhuǎn)眼間第一個(gè)期末考試緊張的度過后援奢,第一個(gè)寒假如期而至。小姑娘最近...
    Gabbi閱讀 128評論 0 0
  • 我出生在一個(gè)以水稻種植為主的農(nóng)村里忍捡,村子灌溉條件好集漾,有溪有河。村里的人和睦勤勞砸脊,那時(shí)我的父母還算是個(gè)知識分子具篇,都在...
    繪愛正面管教閱讀 97評論 0 2