#android #database #android-room #relationship #dao
Вопрос:
У меня есть два класса, которые называются Транзакция и Человек.
Класс Транзакции:
@Entity(tableName = "Transaction") public class Transaction { @PrimaryKey(autoGenerate = true) private long id; private int traderID; private int amount; private long transactionDate; private long dateOfRegistration; private String about; private long time; private String from; private String transactionType; private long transactionNum; private String description; //Getter and Setter
Класс Персоны:
@Entity(tableName = "Person") public class Person { @PrimaryKey(autoGenerate = true) private long id; private String name; private long TransactionId; //Getter and Setter
- Я хочу, чтобы эти два класса были соединены через TraderId в классе транзакций и TransactionID в классе Person.
- Это отношения один на один?
- Должен ли я создавать Dao для каждого класса?
Я читал документы Google, но они кажутся запутанными.
Ответ №1:
Я хочу, чтобы эти два класса были соединены через TraderId в классе транзакций и TransactionID в классе Person.
Это отношения один на один?
Нет, это 1-много, т. е. На Транзакцию может ссылаться много людей.
- Для отношений «один-один» у вас также может быть одна таблица с транзакцией и человеком.
- Возможно, наличие транзакции, ссылающейся на человека, — это то, что вам нужно.
- Возможно, вы хотите, чтобы Транзакция могла иметь много людей и чтобы у человека могло быть много транзакций, в этом случае вам понадобились бы отношения «Много-много», и в этом случае у вас была бы промежуточная таблица (ассоциативная/ссылочная/сопоставляющая таблица (все имена для одного и того же)). В такой таблице будет столбец для Транзакции и Столбец для Человека.
Do I have to build a Dao for each class?
Dao могут быть все в одном классе или распределены по классам.
Однако, поскольку вы, скорее всего, захотите использовать отношения, если вы используете класс Dao для каждой сущности, у вас, вероятно, будут дополнительные классы Dao для обработки отношений.
То есть вы, скорее всего, захотите заключить Сделку вместе с этим Человеком. В этом случае у вас будет POJO как с Человеком, так и с транзакцией, так что, возможно, у вас будет еще один урок с Daos.
Таким образом, наряду с вашими занятиями транзакциями и личностями у вас могли бы быть :-
ПерсонДао
@Dao interface PersonDao { @Insert long insert(Person person); @Query("SELECT * FROM Person") Listlt;Persongt; getAllPersons(); @Query("SELECT * FROM Person WHERE id=:personId") Person getPersonById(long personId); }
и аналогично для транзакций.
и или вы могли бы иметь все это
@Dao abstract class AllDao { /* Abstract Class so need to define methods as abstract, but can have non abstract classes */ @Insert abstract long insert(Transaction transaction); @Query("SELECT * FROM `Transaction`") abstract Listlt;Transactiongt; getAllTransactions(); @Query("SELECT * FROM `Transaction` WHERE id=:transactionId") abstract Transaction getTransactionById(long transactionId); @Insert abstract long insert(Person person); @Query("SELECT * FROM Person") abstract Listlt;Persongt; getAllPersons(); @Query("SELECT * FROM Person WHERE id=:personId") abstract Person getPersonById(long personId); }
- Обратите внимание, что вышесказанное является абстрактным классом, а не интерфейсом. абстрактные классы немного более гибкие.
Конечно, как упоминалось ранее, вы, скорее всего, захотите получить человека и его транзакцию, чтобы у вас мог быть человек POJO с транзакцией, например :-
class PersonWithTransaction { @Embedded Person person; @Relation( entity = Transaction.class, parentColumn = "id", entityColumn = "id" ) Transaction transaction; }
Возможно, с помощью класса PersonWithTransactionDao, например :-
@Dao interface PersonWithTransactionDao { @Query("SELECT * FROM Person") Listlt;PersonWithTransactiongt; getAllPersonsWithTransaction(); @Query("SELECT * FROM Person WHERE id=:personId") PersonWithTransaction getPersonWithTransactionByPersonId(long personId); }
- у вас, скорее всего, не было бы вставок. обновляет или удаляет, просто запрашивает.
- конечно, вышесказанное может быть в других Дао
Вы также можете счесть полезным иметь возможность совершать Транзакции со связанными лицами или Лицами, например, транзакциями с лицами POJO
class TransactionWithPersons { @Embedded Transaction transaction; @Relation( entity = Person.class, parentColumn = "id", entityColumn = "id" ) Listlt;Persongt; persons; }
- Обратите внимание, что, поскольку теоретически в Транзакции может быть много людей, у вас есть список людей. Из-за того, что у Человека есть только 1 транзакция, список не требуется для PersonWithTransaction. Однако обычно @Relation используется со списком.
Возможно, вы также захотите рассмотреть возможность обеспечения ссылочной целостности. То есть дети (Человек-это ребенок для Транзакции) или никогда не были сиротами.
В нынешнем виде вы можете добавить ребенка с идентификатором транзакции, которого не существует, и SQLite не будет жаловаться. Однако, если вы попытаетесь получить несуществующую транзакцию (например, с помощью запроса getPersonWithTransactionById), у вас возникнут проблемы, поскольку транзакция не может быть получена.
Вы можете определить правила, гарантирующие существование Транзакции при добавлении Человека. Вы используете внешние ключи для определения таких правил (ограничений). Таким образом, человек может быть :-
@Entity(tableName = "Person", /* Defining Foreign Key constraints (rules) enforces referential integrity - Optional */ foreignKeys = { @ForeignKey( entity = Transaction.class, parentColumns = "id", childColumns = "id", /* Optional Define onDelete and onUpdate can be useful e.g. if a Transaction is deleted then all the Persons are deleted that reference/relate to the Transaction are deleted onUpdate is less useful but if the Transaction id is changed then all the Persons that referenced the Transaction will be changed to reflect the update id */ onDelete = ForeignKey.CASCADE, onUpdate = ForeignKey.CASCADE ) } ) public class Person { @PrimaryKey(autoGenerate = true) private long id; private String name; private long TransactionId; ....
Комментарии:
1. Большое спасибо!. это решило мою проблему.