http://blog.magicer.xyz/2017/...java
以前咱們看到了greenDao
的簡單使用,可是就這些是遠遠不夠的,有時候咱們須要存儲的數據較爲複雜,這個時候咱們可能須要使用到多表關聯的操做。數據庫
一對一的關係映射。看個例子:網絡
@Entity public class Score { @Id private String id; private int score; } @Entity public class Student { @Id private String id; private String name; private int age; private String scoreId; @ToOne(joinProperty = "scoreId") private Score score; } //先向數據庫中插入兩條數據 Score score = new Score("1101", 80); Student magicer = new Student("110","Magicer",12,"1101"); scoreDao.insertOrReplace(score); studentDao.insertOrReplace(magicer); //以後查找咱們插入的數據,就能夠查詢出來咱們想要的帶有成績的學生實體。 QueryBuilder<Student> queryBuilder = studentDao.queryBuilder().where(StudentDao.Properties.Name.eq("Magicer")); for (Student student : queryBuilder.list()) { Log.i(TAG, "onCreate: "+student.toString()); }
在上面的例子中,咱們設定每一個學生有一門成績,這個時候就是個ToOne
一對一的關係。咱們經過joinProperty
來設置外鍵。咱們就能夠很方便的查詢出某個學生的成績了。less
public @interface ToOne { /** * Name of the property inside the current entity which holds the key of related entity. * If this parameter is absent(缺乏的), then an additional column is automatically created to hold the key. */ String joinProperty() default ""; }
可是通常一個學生會有多個成績,這個時候咱們就須要使用ToMany
一對多的關係了。先看下例子:ide
@Entity public class Student { @Id private String id; private String name; private int age; @ToMany(referencedJoinProperty = "studentId") private List<Score> scores; } @Entity public class Score { @Id private String id; private int score; private String type; private String studentId; } Score math = new Score("1101", 87, "Math", "110"); Score english = new Score("1102", 99, "English", "110"); Score chinese = new Score("1103", 120, "Chinese", "110"); scoreDao.insertOrReplaceInTx(math,english,chinese);//使用事務插入或替換數據 Student magicer = new Student("110", "Magicer", 23); studentDao.insertOrReplace(magicer); Query<Student> query = studentDao.queryBuilder().where(StudentDao.Properties.Name.eq("Magicer")).build(); for (Student student : query.list()) { Log.i(TAG, "onCreate: "+student); } //I/MainActivity: onCreate: Student{id='110', name='Magicer', age=23, score=[Score{id='1101', score=87, type='Math', studentId='110'}, Score{id='1102', score=99, type='English', studentId='110'}, Score{id='1103', score=120, type='Chinese', studentId='110'}]}
這個時候,一個學生就有Math
Enghlish
Chinese
三個的成績。這個時候,咱們使用referencedJoinProperty
將成績跟學生創建了關聯關係。ui
public @interface ToMany { /** * Name of the property inside the target entity which holds id of the source (current) entity * Required unless no {@link JoinProperty} or {@link JoinEntity} is specified */ String referencedJoinProperty() default ""; /** * Array of matching source -> target properties * Required unless {@link #referencedJoinProperty()} or {@link JoinEntity} is specified */ JoinProperty[] joinProperties() default {}; }
有時咱們還要建立多對多的關聯關係N:M
。在greenDao
中就使用JoinEntity
註解;先來看下他的定義:this
public @interface JoinEntity { /** Reference to join-entity class, which holds the source and the target properties */ Class<?> entity(); /** Name of the property inside the join entity which holds id of the source (current) entity */ String sourceProperty(); /** Name of the property inside the join entity which holds id of the target entity */ String targetProperty(); }
配置多對多關係的時候咱們須要使用到ToMany
和JoinEntity
經過JoinEntity
註解來配置關聯的建。以下:code
@Entity public class Student { @Id private String id; private String name; private int age; @ToMany @JoinEntity( entity = Join.class, sourceProperty = "studentId", targetProperty = "scoreId" ) private List<Score> scores; } @Entity public class Join { @Id private String id; private String studentId; private String scoreId; } @Entity public class Score { @Id private String id; private int score; private String type; private String studentId; }
當插入到數據庫中的數據是網絡請求獲得的時候會有些注意事項。因爲greenDao
會幫助咱們生成一些get
和set
方法。這個是時候就要注意了。來看下生成的代碼:對象
@Entity public class Point { @Id private Long id; private Long strokeId; private int x; private int y; } @Entity public class Stroke { @Id private Long id; private String name; @ToMany(referencedJoinProperty = "strokeId") private List<Point> points; }
如上面,咱們如今有每一個筆畫Stroke
會有不少的Point
。編譯下以後會生成不少get
和set
方法。
咱們看下Stroke
的一個get
方法咱們會看到下面這些代碼。就因爲這個代碼。可能就會致使。咱們解析到了Stroke
後調用getPoints()
方法想要獲取點的集合是出現問題,這時候就可能會報錯。這個時候咱們能夠在單獨寫另外的一個get
方法,來支持直接獲取points
對象。blog
@Generated(hash = 404164872) public List<Point> getPoints() { if (points == null) { final DaoSession daoSession = this.daoSession; if (daoSession == null) { throw new DaoException("Entity is detached from DAO context"); } PointDao targetDao = daoSession.getPointDao(); List<Point> pointsNew = targetDao._queryStroke_Points(id); synchronized (this) { if(points == null) { points = pointsNew; } } } return points; }