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; }