简体   繁体   English

Android房间一对多关系

[英]Android room one to many relationship

I am trying to setup a one to many relationship, I have checked multi articles and tutorials online but all the examples shows one table having one to many relationship with another table.我正在尝试建立一对多关系,我已经在线查看了多篇文章和教程,但是所有示例都显示一个表与另一个表具有一对多关系。

In my requirement I have two tables having one to many relationship to a another table (check the diagram below)在我的要求中,我有两个表与另一个表具有一对多的关系(请查看下图)

Student table has FK from Class and School table.学生表具有来自 Class 和学校表的 FK。 Most of the example they explain one to many relationship either by Class - Student or School - Student.大多数示例他们通过 Class - 学生或学校 - 学生来解释一对多关系。

I want to do [Class, School] - Student.我想做[班级,学校] - 学生。

Core Data takes cares of it on iOS, but I am not able to sort this out on Android. Core Data 在 iOS 上处理它,但我无法在 Android 上解决这个问题。 Even tried the nested relationship example shown in Android documentation but that is not working.甚至尝试了 Android 文档中显示的嵌套关系示例,但这不起作用。

在此处输入图像描述

Your issue/problem hasn't been clearly stated.您的问题/问题尚未明确说明。 However, the following is a working example that demonstrates two ways of extracting the relationships based upon your schema.但是,以下是一个工作示例,它演示了根据您的模式提取关系的两种方法。

  • Note the use of Class as a class is fraught with potential issues and it is not recommended at all.请注意,将 Class 用作 class 存在潜在问题,根本不建议这样做。 However, the following does use the Class and to circumvent some issues may not fully reflect your schema.但是,以下确实使用了 Class 并且为了规避某些问题可能无法完全反映您的架构。

Example code示例代码

The School entity:-学校实体:-

@Entity(tableName = "_school")
class School {
    @PrimaryKey
    @ColumnInfo(name = "school_id")
    Long Schoolid;
    @NonNull
    @ColumnInfo(name = "school_name")
    String SchoolName;

    School(){}

    @Ignore
    School(String schoolName) {
        this.SchoolName = schoolName;
    }
}

The Class (an unwise choice of name):- Class (名称的不明智选择):-

@Entity(tableName = "_class")
class Class {
    @PrimaryKey
    @ColumnInfo(name = "class_id")
    Long ClassId;
    @NonNull
    @ColumnInfo(name = "class_name")
    String ClassName;

    Class(){}

    @Ignore
    Class(String className) {
        this.ClassName = className;
    }
}

The Student entity ( Foreign Key Constraints included):-学生实体(包括外键约束):-

@Entity(
        tableName = "_student", foreignKeys = {
        @ForeignKey(
                entity = School.class,
                parentColumns = {"school_id"},
                childColumns = {"school_id"},
                onDelete = ForeignKey.CASCADE,
                onUpdate = ForeignKey.CASCADE
        ),
        @ForeignKey(
                entity = Class.class,
                parentColumns = {"class_id"},
                childColumns = {"class_id"},
                onDelete = ForeignKey.CASCADE,
                onUpdate = ForeignKey.CASCADE
        )
        }
)
class Student {
    @PrimaryKey
    @ColumnInfo(name = "student_id")
    Long StudentId;
    @ColumnInfo(name = "Student_name")
    String StudentName;
    @ColumnInfo(name = "school_id", index = true)
    Long SchoolId;
    @ColumnInfo(name = "class_id", index = true)
    Long ClassId;

    Student(){}

    @Ignore
    Student(String studentName, long schoolId, long classId) {
        this.StudentName = studentName;
        this.SchoolId = schoolId;
        this.ClassId = classId;
    }
}

POJO Method 1 - Class StudentAndSchoolAndClass - (DOES NOT USE @Relation ) POJO 方法 1 - Class StudentAndSchoolAndClass - (不使用@Relation

class StudentAndSchoolAndClass {

    @Embedded
    Student student;
    String school_name;
    String class_name;
}

POJO Method 2 - Class StudentWithSchoolWithClass - (Uses @Relation 's) POJO 方法 2 - Class StudentWithSchoolWithClass - (使用@Relation的)

class StudentWithSchoolWithClass {

    @Embedded
    Student student;

    @Relation(entity = School.class,parentColumn = "school_id", entityColumn = "school_id")
    List<School> schoolList;
    @Relation(entity = Class.class,parentColumn = "class_id",entityColumn = "class_id")
    List<Class> classList;
}

The Dao Interface AllDao Dao 接口AllDao

@Dao
interface AllDao {

    @Insert
    Long insertSchool(School s);
    @Insert
    Long insertClass(Class c);
    @Insert
    Long insertStudent(Student s);
    @Query("SELECT * FROM _school")
    List<School> getAllSchools();
    @Query("SELECT * FROM _school WHERE school_id = :school_id ")
    School getSchoolById(Long school_id);
    @Query("SELECT * FROM _class")
    List<Class> getAllClasses();
    @Query("SELECT * FROM _class WHERE class_id = :class_id")
    Class getClassById(Long class_id);
    @Query("SELECT * FROM _student JOIN _school ON _school.school_id = _student.school_id JOIN _class ON _class.class_id = _student.class_id")
    List<StudentAndSchoolAndClass> getStudentAndSchoolAndClass();
    @Query("SELECT * FROM _student")
    List<StudentWithSchoolWithClass> getStudentWithSchoolWithClass();

}
  • Note The two last queries use the respective POJO and especially that注意最后两个查询使用各自的 POJO,尤其是
  • the PJO with @Relations has the relationships defined via the JOIN's带有@Relations 的 PJO 具有通过 JOIN 定义的关系

The @Database class MyDatabase @Database class MyDatabase

@Database(entities = {School.class,Class.class,Student.class},version = 1)
abstract class MyDatabase extends RoomDatabase {
    abstract AllDao allDao();
}

Lastly an Activity MainActivity that loads some data into the database and then extracts some of the data using the 2 @Queries and the respective POJO class.最后是一个 Activity MainActivity ,它将一些数据加载到数据库中,然后使用 2 个@Queries 和相应的 POJO class 提取一些数据。

public class MainActivity extends AppCompatActivity {

    MyDatabase db;
    AllDao allDao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Build the MyDatabase instance
        db = Room.databaseBuilder(this,MyDatabase.class,"mydb")
                .allowMainThreadQueries()
                .build();
        // Build the allDao instance
        allDao = db.allDao();

        // Create some school objects
        School[] s_array = {new School("School1"),
                new School("School2"),
                new School("School3")
        };
        // Insert the Schools into the database
        for (School s: s_array) {
            allDao.insertSchool(s);
        }

        // Create some Class objects
        Class[] c_array = {
                new Class("Class1"),
                new Class("Class2"),
                new Class("Class3")
        };
        // Insert the classes
        for (Class c: c_array) {
            allDao.insertClass(c);
        }

        // Create some Student Objects
        Student[] st_array = {
                new Student("Fred",3,3), new Student("Mary",1,2)
        };
        //Insert the Students
        for(Student st: st_array) {
            allDao.insertStudent(st);
        }

        // Get the Students with the School and Class information using POJO 1 (realtionship via joins)
        List<StudentAndSchoolAndClass> sasac = allDao.getStudentAndSchoolAndClass();
        // Log the data
        for(StudentAndSchoolAndClass ssc: sasac) {
            Log.d("STUDENTINFO1","Student Name = " + ssc.student.StudentName +
                    "\n\t ID=" + ssc.student.StudentId + " SchoolID=" + ssc.student.SchoolId + " ClassID=" + ssc.student.ClassId +
                    "\n\t\t School Name = " + ssc.school_name +
                    "\n\t\t Class Name = " + ssc.class_name
                    );
        }
        // Get the Students with the School and Class information using POJO 2 (with @Relation's)
        List<StudentWithSchoolWithClass> swswc = allDao.getStudentWithSchoolWithClass();
        for(StudentWithSchoolWithClass ssc: swswc) {
            Log.d("STUDENTINFO2","Student Name = " + ssc.student.StudentName +
                    "\n\t ID=" + ssc.student.StudentId + " SchoolID=" + ssc.student.SchoolId + " ClassID=" + ssc.student.ClassId +
                    "\n\t\t School Name = " + ssc.schoolList.get(0).SchoolName +
                    "\n\t\t Class Name = " + ssc.classList.get(0).ClassName
            );
        }
    }
}
  • Note in the first the School and Class name are members of the class, whilst for the second the School and Class are within a List.请注意,首先,School 和 Class 名称是 class 的成员,而其次,School 和 Class 位于列表中。 As the Student will only have a single school/class there is no need to traverse the list as the first element/item (0) will be the only element/item in the List.由于学生将只有一个学校/班级,因此无需遍历列表,因为第一个元素/项目 (0) 将是列表中唯一的元素/项目。

Results结果

When the above is run (first time) the database is:-当上述运行(第一次)时,数据库是: -

在此处输入图像描述

The log contains:-日志包含:-

2021-04-01 22:09:51.977 D/STUDENTINFO1: Student Name = Fred
         ID=1 SchoolID=3 ClassID=3
             School Name = School3
             Class Name = Class3
2021-04-01 22:09:51.977 D/STUDENTINFO1: Student Name = Mary
         ID=2 SchoolID=1 ClassID=2
             School Name = School1
             Class Name = Class2


2021-04-01 22:09:51.982 D/STUDENTINFO2: Student Name = Fred
         ID=1 SchoolID=3 ClassID=3
             School Name = School3
             Class Name = Class3
2021-04-01 22:09:51.982 D/STUDENTINFO2: Student Name = Mary
         ID=2 SchoolID=1 ClassID=2
             School Name = School1
             Class Name = Class2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM