当前位置: 代码迷 >> 综合 >> GreenDao 3.3.0 多表关联使用(二)
  详细解决方案

GreenDao 3.3.0 多表关联使用(二)

热度:41   发布时间:2024-01-30 23:00:35.0

GreenDao 3.3.0 基本使用与入门(一)

注解关系说明

GreenDao 进行表关联的处理 一对一, 一对多和 多对多的表管理处理,
其联关系是通过主外键(对象之间关联的id,外键是对应表的主键id)来构建的,

  • @ToOne(joinProperty =“teacherId” ) 一对一
  • @ToMany(referencedJoinProperty =“courseId”) 一对多
  • @ToMany //多对多 需要一个中间表去连接
    @JoinEntity(entity = GradeJionTeacher.class,sourceProperty = “teaId”,targetProperty = “stuId”)

@ToOne 一对一的使用

教师表 Teachers

@Entity(nameInDb = "Teachers")
public class Teachers {@Id(autoincrement = true)@Property(nameInDb = "teacherId")private long teacherId;@Property(nameInDb = "teacherName")private String teacherName;@Property(nameInDb = "sex")private String sex;@Overridepublic String toString() {return "Teachers{" +"teacherId=" + teacherId +", teacherName='" + teacherName + '\'' +", sex='" + sex + '\'' +'}';}

课程表 Courses

@Entity(nameInDb = "Courses")
public class Courses {@Id(autoincrement = true)@Property(nameInDb = "courseId")private long courseId;@Property(nameInDb = "courseName")private String courseName;@Property(nameInDb = "teacherId")//这里的teacherId为Teachers表中的主键idprivate long teacherId;@ToOne(joinProperty ="teacherId" ) //一对一 ,一课一老师private Teachers teacher;@Overridepublic String toString() {return "Courses{" +"courseId=" + courseId +", courseName='" + courseName + '\'' +", teacherId=" + teacherId +", teacher=" + teacher +'}';}

测试数据

    Teachers teachers=new Teachers();teachers.setTeacherId(31);teachers.setTeacherName("31 老师");teachers.setSex("男");Teachers teachers1=new Teachers();teachers1.setTeacherId(32);teachers1.setTeacherName("32 老师");teachers1.setSex("男");Teachers teachers2=new Teachers();teachers2.setTeacherId(33);teachers2.setTeacherName("33 老师");teachers2.setSex("女");Courses courses=new Courses();courses.setCourseId(1);courses.setTeacherId(31);courses.setCourseName("语文");Courses courses1=new Courses();courses1.setCourseId(2);courses1.setTeacherId(32);courses1.setCourseName("英语");Courses courses2=new Courses();courses2.setCourseId(3);//courses2.setTeacherId(33);courses2.setTeacher(teachers2);//设置Teachers 对象关联courses2.setCourseName("数学");//插入数据GreenDaoUtils.getDaoSession().getTeachersDao().insertOrReplaceInTx(teachers,teachers1,teachers2);GreenDaoUtils.getDaoSession().getCoursesDao().insertOrReplaceInTx(courses,courses1,courses2);List<Teachers> teachers = GreenDaoUtils.getDaoSession().getTeachersDao().queryBuilder().build().list();List<Courses> courses = GreenDaoUtils.getDaoSession().getCoursesDao().queryBuilder().build().list();Log.d("LHW","teachers="+teachers);Log.d("LHW","courses="+courses);

注意:
针对上面一对多的情况 也可以不定义teacherId关联外键,可以插入在数据的时候setTeachers

@ToMany 一对多的使用

新建表 Students

@Entity(nameInDb = "Students")
public class Students {@Id(autoincrement = true)private long id;@Property(nameInDb = "studentId")private long studentId;@Property(nameInDb = "studentName")private String studentName;@Property(nameInDb = "classes")private String classes;@Property(nameInDb = "courseId")//Courses表的主键idprivate long courseId;@ToMany(referencedJoinProperty ="courseId")//一对多 一个学生多堂课private List<Courses> courses;@Overridepublic String toString() {return "Students{" +"id=" + id +", studentId=" + studentId +", studentName='" + studentName + '\'' +", classes='" + classes + '\'' +", courseId=" + courseId +", courses=" + getCourses() +'}';}

测试数据

        Students students=new Students();students.setId(1);students.setStudentId(21);students.setCourseId(1);students.setStudentName("21 学生");Students students1=new Students();students1.setId(2);students1.setStudentId(22);students1.setCourseId(2);students1.setStudentName("22 学生");Students students2=new Students();students2.setId(3);students2.setStudentId(23);students2.setCourseId(3);students2.setStudentName("23学生");GreenDaoUtils.getDaoSession().getStudentsDao().insertOrReplaceInTx(students,students1,students2);List<Students> students = GreenDaoUtils.getDaoSession().getStudentsDao().queryBuilder().build().list();Log.d("LHW","students="+students);

@ToMany @JoinEntity 多对多的使用

多对多,@JoinEntity注解:entity 中间表;sourceProperty 实体属性主键id;targetProperty 外链实体属性主键id

GradeJionTeacher 新建中间表

@Entity(nameInDb = "GradeJionTeacher")
public class GradeJionTeacher {@Id(autoincrement = true)private long id;@Property(nameInDb ="stuId")private long stuId;@Property(nameInDb ="teaId")private long teaId;

Grade 年级表

@Entity(nameInDb = "Grade")
public class Grade {@Id(autoincrement = true)private long id;@Property(nameInDb = "gId")private long gId;@Property(nameInDb = "gradeName")private String gradeName;@Property(nameInDb = "gradeState")private String gradeState="day day up";@ToMany //多对多  多个年纪对 多个老师@JoinEntity(entity = GradeJionTeacher.class,sourceProperty = "stuId",targetProperty = "teaId")private List<Teachers> teachersList;@Overridepublic String toString() {return "Grade{" +"id=" + id +", gId=" + gId +", gradeName='" + gradeName + '\'' +", gradeState='" + gradeState + '\'' +", teachersList=" +getTeachersList()+//teachersList'}';}

Teachers 教师表

@Entity(nameInDb = "Teachers")
public class Teachers {@Id(autoincrement = true)@Property(nameInDb = "teacherId")private long teacherId;@Property(nameInDb = "teacherName")private String teacherName;@Property(nameInDb = "sex")private String sex;@ToMany //多对多   多个老师 多个年纪@JoinEntity(entity = GradeJionTeacher.class,sourceProperty = "teaId",targetProperty = "stuId")private List<Grade> grades;@Overridepublic String toString() {return "Teachers{" +"teacherId=" + teacherId +", teacherName='" + teacherName + '\'' +", sex='" + sex + '\'' +", grades=" + grades +'}';}

测试数据

   Grade grade=new Grade();grade.setId(41);grade.setGId(41);grade.setGradeName("31 年纪");grade.setGradeState("happy every day");Grade grade1=new Grade();grade1.setId(42);grade1.setGId(42);grade1.setGradeName("32 年纪");grade1.setGradeState("no happy ");Grade grade2=new Grade();grade2.setId(43);grade2.setGId(43);grade2.setGradeName("33 年纪");//Teacher 31 有 41 42 43  反过来Grade 41 42 43 都有 Teacher 31GradeJionTeacher st=new GradeJionTeacher();st.setId(1);st.setTeaId(31);st.setStuId(41);GradeJionTeacher st1=new GradeJionTeacher();st1.setId(2);st1.setTeaId(31);st1.setStuId(42);GradeJionTeacher st2=new GradeJionTeacher();st2.setId(3);st2.setTeaId(31);st2.setStuId(43);//Teacher 32 有 41 42 43  反过来Grade 41 42 43 都有 Teacher 32GradeJionTeacher st3=new GradeJionTeacher();st3.setId(4);st3.setTeaId(32);st3.setStuId(41);GradeJionTeacher st4=new GradeJionTeacher();st4.setId(5);st4.setTeaId(32);st4.setStuId(42);GradeJionTeacher st5=new GradeJionTeacher();st5.setId(6);st5.setTeaId(32);st5.setStuId(43);GradeJionTeacher st6=new GradeJionTeacher();st6.setId(7);st6.setTeaId(33);st6.setStuId(41);GradeJionTeacher st7=new GradeJionTeacher();st7.setId(8);st7.setTeaId(33);st7.setStuId(42);GreenDaoUtils.getDaoSession().getGradeDao().insertOrReplaceInTx(grade,grade1,grade2);GreenDaoUtils.getDaoSession().getTeachersDao().insertOrReplaceInTx(teachers,teachers1,teachers2);List<Teachers> teachers = GreenDaoUtils.getDaoSession().getTeachersDao().queryBuilder().build().list();List<Grade> grades = GreenDaoUtils.getDaoSession().getGradeDao().queryBuilder().build().list();Log.d("LHW","teachers="+teachers);Log.d("LHW","grades="+grades);for (Teachers teacher : teachers) {Log.d("LHW","teacher="+teacher);}

数据显示如下图

image

注意事项:
通过观察上图我们可以看到,grades 打印出来的数据是null空的,而teachersList是有数据的。
这里注意我们建表的实体类中的toString方法:

  • Grades中默认打印,List 是 teachersList 这是数据是null
  • 修改成getTeachersList() 就会显示数据

但是当我们在Teachers 和 Grades 中都打印getList数据时就会报错如下:

E/AndroidRuntime: FATAL EXCEPTION: mainProcess: com.lhw.greendaodemo, PID: 1020java.lang.StackOverflowError: stack size 8MBat java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:451)at java.lang.StringBuilder.append(StringBuilder.java:137)at com.lhw.daggerdemo.greendao.bean.Teachers.toString(Teachers.java:39)at java.lang.String.valueOf(String.java:2896)at java.lang.StringBuilder.append(StringBuilder.java:132)at java.util.AbstractCollection.toString(AbstractCollection.java:462)at java.lang.String.valueOf(String.java:2896)at java.lang.StringBuilder.append(StringBuilder.java:132)at com.lhw.daggerdemo.greendao.bean.Grade.toString(Grade.java:42)

因为都写getList后,就会相互调用出现死循环,所以我们要手动调用才可以,上图的数据显示就是一个getList和默认打印的结果