1.greenDao多表關(guān)聯(lián)
-
一對一關(guān)聯(lián):使用@ToOne 注解關(guān)聯(lián)對象,通過注解joinProperty參數(shù)來定義一個外鍵,下面是示例代碼:
image
使用@ToOne注解的屬性都需要分別進行數(shù)據(jù)庫保存拐袜,先在數(shù)據(jù)庫中插入被注解的對象,把插入成功返回的id值作為外鍵與主表關(guān)聯(lián)
image
這樣只要獲得User對象就能通過getFriend()方法獲取User所對應的Friend了,這樣是不是很高效费就,很簡便过蹂。其實getFriend()方法也很簡單,就是在底層幫助我們封裝好了查詢語句而已歪赢,另外getFriend()獲取的對象也是懶查詢機制,只有當我們調(diào)用getFriend()方法的時候单料,greenDao才會執(zhí)行查詢操作埋凯,并將查詢結(jié)果封裝成對象返給我們。如果你想獲取User對象時立即執(zhí)行查詢操作獲取Friend對象扫尖,可以調(diào)用UserDAO類的loadDeep()與queryDeep()方法
image
注意:只有bean對象中使用了@ToOne注解的時候白对,編譯代碼,才會在對應的Dao類中生成loadDeep()與queryDeep()方法换怖。
-
一對多關(guān)聯(lián):使用@ToMany 注解關(guān)聯(lián)的List甩恼,注解參數(shù)有兩種情況
如果外鍵可以通過id來定義,可以見到使用下面的形式:
image
這種定義方式表述沉颂,將User表中的id值作為外鍵存儲在Customer表userId中
如果外鍵不可以通過id來定義条摸,可以見到使用下面的形式:
image
其實第一種方式可以完全用第二種方式替代,如下:@ToMany(joinProperties = { @JoinProperty(name = "id", referencedName = "userId") })
下面我是以主鍵可以通過id來定義演示兆览。在保存數(shù)據(jù)庫的時候屈溉,先保存主表,再保存注解對象抬探,這一點剛好和@ToOne注解相反子巾。
說明:我在看網(wǎng)上的其他bolg說使用@ToMany注解的時候帆赢,編譯后在對應的Dao類中也會生成loadDeep()與queryDeep()方法,而實際我使用greenDAO3.2.2的時候是沒有生成這兩個方法线梗。個人猜測椰于,也許是因為,如果支持預加載執(zhí)行sql語句查詢多對象數(shù)據(jù)仪搔,如果數(shù)據(jù)量比較大的時候瘾婿,可能會很執(zhí)行很長時間,也很消耗性能烤咧,因此在一對多關(guān)聯(lián)的時候偏陪,greenDAO不支持懶查詢機制,這只是我個人看法煮嫌,如果有不同意見可以在blog留言笛谦,如果有問題也請留言指正。
2.greenDao session緩存導致數(shù)據(jù)不一致問題
在一對多關(guān)聯(lián)中昌阿,如果我們在一次查詢子表后饥脑,更改了子表的數(shù)據(jù),那個再次查詢的時候懦冰,查詢出來的數(shù)據(jù)顯示的還是原來的數(shù)據(jù)灶轰,不會顯示更改后數(shù)據(jù),如下圖示例:
如果我們沒有打開注釋代碼刷钢,我們在第一次查詢完User子表中的數(shù)后笋颤,在子表數(shù)據(jù)中添加了一個Customer對象,然后再次執(zhí)行查詢闯捎,發(fā)現(xiàn)兩次查詢出來的結(jié)果一直椰弊。這是因為,我們在第一次執(zhí)行查詢后瓤鼻,會將結(jié)果寫入greenDao的session中,當再次執(zhí)行查詢時候贤重,greenDao發(fā)現(xiàn)和第一次執(zhí)行的查詢是一樣茬祷,就直接在session中取出查詢的結(jié)果,不會去數(shù)據(jù)庫中查詢?nèi)〕鼋Y(jié)果并蝗。注釋的代碼作用就是清除session緩存祭犯,讓每次查詢都去數(shù)據(jù)庫取數(shù)據(jù)。
- session.clear():清除greenDao的全部sessoin緩存
- xxxDao().detachAll():清除greenDao中xxxDao的session緩存
3.greenDao 自定義參數(shù)類型
-
greenDao默認支持的數(shù)據(jù)類型
boolean, Boolean int, Integer short, Short long, Long float, Float double, Double byte, Byte byte[] String Date
-
官網(wǎng)文檔給出是示例Demo滚停,將枚舉類型保存到數(shù)據(jù)庫
@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; } } }
- 通過使用 @Convert注解需要保存到數(shù)據(jù)庫中的對象
- 在@Convert注解參數(shù)中指名進行轉(zhuǎn)換操作的java類和數(shù)據(jù)庫中保存的類型
- 定義轉(zhuǎn)換類沃粗,實現(xiàn)PropertyConverter接口,重寫里面的兩個轉(zhuǎn)換方法
-
自己定義類型键畴,保存到數(shù)據(jù)庫
@Entity public class Friend { @Id private Long id; @Convert(converter =CatConverter.class, columnType =String.class) private Cat cat; public class Cat { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } public static class CatConverter implements PropertyConverter<Cat,String> { //將數(shù)據(jù)庫中的類型轉(zhuǎn)換成java類型 @Override public Cat convertToEntityProperty(String databaseValue) { if(TextUtils.isEmpty(databaseValue)){ return null; } return JSON.parseObject(databaseValue,Cat.class); } //將java類型轉(zhuǎn)換成數(shù)據(jù)庫類型 @Override public String convertToDatabaseValue(Cat entityProperty) { if(entityProperty==null){ return null; } return JSON.toJSONString(entityProperty); } } }
說明:代碼中所使用的json轉(zhuǎn)換工具是fastJson