greenDao多表关联

亲测可用,如有问题请私信!

之前我们看到了greenDao的简单使用,但是就这些是远远不够的,有时候我们需要存储的数据较为复杂,这个时候我们可能需要使用到多表关联的操作。

ToOne

一对一的关系映射。看个例子:

 
  1. @Entity

  2. public class Score {

  3. @Id

  4. private String id;

  5. private int score;

  6. }

  7. @Entity

  8. public class Student {

  9. @Id

  10. private String id;

  11. private String name;

  12. private int age;

  13. private String scoreId;

  14. @ToOne(joinProperty = "scoreId")

  15. private Score score;

  16. }

  17. //先向数据库中插入两条数据

  18. Score score = new Score("1101", 80);

  19. Student magicer = new Student("110","Magicer",12,"1101");

  20. scoreDao.insertOrReplace(score);

  21. studentDao.insertOrReplace(magicer);

  22. //之后查找我们插入的数据,就可以查询出来我们想要的带有成绩的学生实体。

  23. QueryBuilder<Student> queryBuilder = studentDao.queryBuilder().where(StudentDao.Properties.Name.eq("Magicer"));

  24. for (Student student : queryBuilder.list()) {

  25. Log.i(TAG, "onCreate: "+student.toString());

  26. }

在上面的例子中,我们设定每个学生有一门成绩,这个时候就是个ToOne一对一的关系。我们通过joinProperty来设置外键。我们就可以很方便的查询出某个学生的成绩了。

 
  1. public @interface ToOne {

  2. /**

  3. * Name of the property inside the current entity which holds the key of related entity.

  4. * If this parameter is absent(缺少的), then an additional column is automatically created to hold the key.

  5. */

  6. String joinProperty() default "";

  7. }

ToMany

但是一般一个学生会有多个成绩,这个时候我们就需要使用ToMany一对多的关系了。先看下例子:

 
  1. @Entity

  2. public class Student {

  3. @Id

  4. private String id;

  5. private String name;

  6. private int age;

  7. @ToMany(referencedJoinProperty = "studentId")

  8. private List<Score> scores;

  9. }

  10. @Entity

  11. public class Score {

  12. @Id

  13. private String id;

  14. private int score;

  15. private String type;

  16. private String studentId;

  17. }

  18. Score math = new Score("1101", 87, "Math", "110");

  19. Score english = new Score("1102", 99, "English", "110");

  20. Score chinese = new Score("1103", 120, "Chinese", "110");

  21. scoreDao.insertOrReplaceInTx(math,english,chinese);//使用事务插入或替换数据

  22. Student magicer = new Student("110", "Magicer", 23);

  23. studentDao.insertOrReplace(magicer);

  24. Query<Student> query = studentDao.queryBuilder().where(StudentDao.Properties.Name.eq("Magicer")).build();

  25. for (Student student : query.list()) {

  26. Log.i(TAG, "onCreate: "+student);

  27. }

  28. //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 将成绩跟学生建立了关联关系。

 
  1. public @interface ToMany {

  2. /**

  3. * Name of the property inside the target entity which holds id of the source (current) entity

  4. * Required unless no {@link JoinProperty} or {@link JoinEntity} is specified

  5. */

  6. String referencedJoinProperty() default "";

  7. /**

  8. * Array of matching source -> target properties

  9. * Required unless {@link #referencedJoinProperty()} or {@link JoinEntity} is specified

  10. */

  11. JoinProperty[] joinProperties() default {};

  12. }

JoinEntity

有时我们还要创建多对多的关联关系N:M。在greenDao中就使用JoinEntity注解;先来看下他的定义:

 
  1. public @interface JoinEntity {

  2. /** Reference to join-entity class, which holds the source and the target properties */

  3. Class<?> entity();

  4. /** Name of the property inside the join entity which holds id of the source (current) entity */

  5. String sourceProperty();

  6. /** Name of the property inside the join entity which holds id of the target entity */

  7. String targetProperty();

  8. }

配置多对多关系的时候我们需要使用到ToManyJoinEntity通过JoinEntity注解来配置关联的建。如下:

 
  1. @Entity

  2. public class Student {

  3. @Id

  4. private String id;

  5. private String name;

  6. private int age;

  7. @ToMany

  8. @JoinEntity(

  9. entity = Join.class,

  10. sourceProperty = "studentId",

  11. targetProperty = "scoreId"

  12. )

  13. private List<Score> scores;

  14. }

  15. @Entity

  16. public class Join {

  17. @Id

  18. private String id;

  19. private String studentId;

  20. private String scoreId;

  21. }

  22. @Entity

  23. public class Score {

  24. @Id

  25. private String id;

  26. private int score;

  27. private String type;

  28. private String studentId;

  29. }

遇到的问题

当插入到数据库中的数据是网络请求得到的时候会有些注意事项。由于greenDao会帮助我们生成一些getset方法。这个是时候就要注意了。来看下生成的代码:

 
  1. @Entity

  2. public class Point {

  3. @Id

  4. private Long id;

  5. private Long strokeId;

  6. private int x;

  7. private int y;

  8. }

  9. @Entity

  10. public class Stroke {

  11. @Id

  12. private Long id;

  13. private String name;

  14. @ToMany(referencedJoinProperty = "strokeId")

  15. private List<Point> points;

  16. }

如上面,我们现在有每个笔画Stroke会有很多的Point。编译下之后会生成很多getset方法。
我们看下Stroke的一个get方法我们会看到下面这些代码。就由于这个代码。可能就会导致。我们解析到了Stroke后调用getPoints()方法想要获取点的集合是出现问题,这时候就可能会报错。这个时候我们可以在单独写另外的一个get方法,来支持直接获取points对象。

 
  1. @Generated(hash = 404164872)

  2. public List<Point> getPoints() {

  3. if (points == null) {

  4. final DaoSession daoSession = this.daoSession;

  5. if (daoSession == null) {

  6. throw new DaoException("Entity is detached from DAO context");

  7. }

  8. PointDao targetDao = daoSession.getPointDao();

  9. List<Point> pointsNew = targetDao._queryStroke_Points(id);

  10. synchronized (this) {

  11. if(points == null) {

  12. points = pointsNew;

  13. }

  14. }

  15. }

  16. return points;

  17. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值