Room предоставляет уровень абстракции поверх SQLite, позволяющий беспрепятственно получать доступ к базе данных, используя при этом все возможности SQLite. Связь “один ко многим” существует, когда одна строка в таблице A может быть связана со многими строками в таблице B, но одна строка в таблице B связана только с одной строкой в таблице A.
Важность использования классов room для работы в качестве сущностей очень важна, но в его документации очень мало информации о том, как работать с отношениями между сущностями. Чтобы узнать основные понятия о комнате, вы можете следовать этому руководству Чтобы узнать основные понятия о комнате, вы можете следовать этому руководству
Android один ко многим в комнате объяснение:
Для этого примера, используя базовые понятия баз данных и room, сначала объявите их сущности Course.java и Student.java:
@Entity(tableName = "course") public class Course { @PrimaryKey(autoGenerate = true) private long id_course; private String courseName; public long getId_course() { return id_course; } public void setId_course(long id_course) { this.id_course = id_course; } public String getCourseName() { return courseName; } public void setCourseName(String courseName) { this.courseName = courseName; } public Course(String courseName) { this.courseName = courseName; } }
Course.java это наш родительский класс, и мы добавляем идентификатор, который автоматически генерируется с помощью аннотации @PrimaryKey)
@Entity(tableName = "student") public class Student { @PrimaryKey(autoGenerate = true) private long id_student; @ForeignKey (entity = Course.class, parentColumns = "id_course", childColumns = "id_fkcourse", onDelete = CASCADE ) private long id_fkcourse; private String studentName; public long getId_student() { return id_student; } public Student(String studentName) { this.studentName = studentName; } public void setId_student(long id_student) { this.id_student = id_student; } public String getStudentName() { return studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } public long getId_fkcourse() { return id_fkcourse; } public void setId_fkcourse(long id_course) { this.id_fkcourse = id_course; }
В дочернем классе Student.java необходимо добавить атрибут, содержащий идентификатор родительского класса, в этом случае id_fkcourse и аннотация @Foreigkey будут использоваться для установления связи между сущностями.
/*** EXCLUSIVE CLASS TO MANAGE ONE TO MANY IN ROOM ***/ public class CourseWithStudents { @Embedded public Course course; @Relation( parentColumn = "id_course", entityColumn = "id_student" ) public Liststudents; public CourseWithStudents(Course course, List students) { this.course = course; this.students = students; } }
Чтобы сделать это, создайте новый класс данных, в котором каждый экземпляр содержит экземпляр родительской сущности и список всех соответствующих экземпляров дочерних сущностей. Добавьте аннотацию @Relation к экземпляру дочерней сущности, при этом для родительского столбца задано имя столбца первичного ключа родительской сущности, а для entityColumn задано имя столбца дочерней сущности, который ссылается на первичный ключ родительской сущности.
Добавить интерфейс Dao:
@Dao public interface CourseDao { @Transaction @Insert long insertCourse(Course course); @Insert void insertStudents(Liststudents); }
Важно отметить, что следует использовать аннотацию @Transaction. Один метод будет предназначен для курса, а другой – для списка назначенных студентов. Продолжая работу с шаблоном MVVM, у нас уже должны быть наши классы для ViewModel и Repository:
public class CourseRepository { private CourseDao courseDao; public CourseRepository(Application application) { Database database = Database.getDatabase(application); courseDao = database.courseDao(); } public void insert(CourseWithStudents courseWithStudents) { new insertAsync(courseDao).execute(courseWithStudents); } private static class insertAsync extends AsyncTask{ private CourseDao courseDaoAsync; insertAsync(CourseDao courseDao) { courseDaoAsync = courseDao; } @Override protected Void doInBackground(CourseWithStudents... courseWithStudents) { long identifier = courseDaoAsync.insertCourse(courseWithStudents[0].course); for (Student student : courseWithStudents[0].students) { student.setId_fkcourse(identifier); } courseDaoAsync.insertStudents(courseWithStudents[0].students); return null; } } }
Чтобы процесс вставки не конфликтовал с основным потоком, мы должны добавить асинхронный класс, который его обрабатывает.
В инструкции for мы присваиваем каждому студенту идентификатор курса, который был вставлен. Этот идентификатор генерируется автоматически, и нам нужно только получить его, присвоив результату длинный тип данных. Этот фрагмент очень важен для понимания, потому что управляет отношениями. Класс Viewmodel:
public class CourseViewModel extends AndroidViewModel { public CourseViewModel(@NonNull Application application) { super(application); courseRepository = new CourseRepository(application); } private CourseRepository courseRepository; public void insertCourseWithStudents(CourseWithStudents courseWithStudents){ courseRepository.insert(courseWithStudents); } }
Наконец, это классы, которые отвечают за управление отношениями одного ко многим. Класс “Курс со студентами” очень важен, поскольку он обрабатывает отношения на уровне сущностей, связывающие обе модели курса с их учащимися.
Sqlite выглядит как:
Оригинал: “https://dev.to/normanaspx/android-room-how-works-one-to-many-relationship-example-5ad0”