Android Room:使用 Room 插入关系实体 [英] Android Room: Insert relation entities using Room
问题描述
我使用 Relation 在 Room 中添加了一对多关系.我参考了 这篇文章 写下Room中关系的代码.
I've added one to many relationship in Room using Relation. I referred to this post to write the following code for relation in Room.
这篇文章讲述了如何从数据库中读取值,但将实体存储到数据库中导致 userId
为空,这意味着 2 个表之间没有关系.
The post tells how to read the values from the database but storing the entities into the database resulted in userId
to be empty which means there is no relation between the 2 tables.
我不确定在使用 时将
值.insert
User
和 List of Pet
插入数据库的理想方法是什么userId
I'm not sure what is the ideal way to insert
a User
and List of Pet
into the database while having userId
value.
1) 用户实体:
@Entity
public class User {
@PrimaryKey
public int id; // User id
}
2) 宠物实体:
@Entity
public class Pet {
@PrimaryKey
public int id; // Pet id
public int userId; // User id
public String name;
}
3) UserWithPets POJO:
3) UserWithPets POJO:
// Note: No annotation required at this class definition.
public class UserWithPets {
@Embedded
public User user;
@Relation(parentColumn = "id", entityColumn = "userId", entity = Pet.class)
public List<Pet> pets;
}
现在要从数据库中获取记录,我们使用以下DAO
:
Now to fetch the records from DB we use the following DAO
:
@Dao
public interface UserDao {
@Insert
fun insertUser(user: User)
@Query("SELECT * FROM User")
public List<UserWithPets> loadUsersWithPets();
}
<小时>
编辑
我创建了这个问题 https://issuetracker.google.com/issues/62848977在问题跟踪器上.希望他们能为此做点什么.
I have created this issue https://issuetracker.google.com/issues/62848977 on the issue tracker. Hopefully they will do something regarding it.
推荐答案
您可以通过将 Dao 从接口更改为抽象类来实现此目的.
You can do this by changing your Dao from an interface to an abstract class.
@Dao
public abstract class UserDao {
public void insertPetsForUser(User user, List<Pet> pets){
for(Pet pet : pets){
pet.setUserId(user.getId());
}
_insertAll(pets);
}
@Insert
abstract void _insertAll(List<Pet> pets); //this could go in a PetDao instead...
@Insert
public abstract void insertUser(User user);
@Query("SELECT * FROM User")
abstract List<UserWithPets> loadUsersWithPets();
}
您还可以通过让 User
对象具有 @Ignored List
You can also go further by having a User
object have an @Ignored List<Pet> pets
@Entity
public class User {
@PrimaryKey
public int id; // User id
@Ignored
public List<Pet> pets
}
然后 Dao 可以将 UserWithPets
映射到 User:
and then the Dao can map UserWithPets
to User:
public List<User> getUsers() {
List<UserWithPets> usersWithPets = loadUserWithPets();
List<User> users = new ArrayList<User>(usersWithPets.size())
for(UserWithPets userWithPets: usersWithPets) {
userWithPets.user.pets = userWithPets.pets;
users.add(userWithPets.user);
}
return users;
}
这给你留下了完整的道:
This leaves you with the full Dao:
@Dao
public abstract class UserDao {
public void insertAll(List<User> users) {
for(User user:users) {
if(user.pets != null) {
insertPetsForUser(user, user.pets);
}
}
_insertAll(users);
}
private void insertPetsForUser(User user, List<Pet> pets){
for(Pet pet : pets){
pet.setUserId(user.getId());
}
_insertAll(pets);
}
public List<User> getUsersWithPetsEagerlyLoaded() {
List<UserWithPets> usersWithPets = _loadUsersWithPets();
List<User> users = new ArrayList<User>(usersWithPets.size())
for(UserWithPets userWithPets: usersWithPets) {
userWithPets.user.pets = userWithPets.pets;
users.add(userWithPets.user);
}
return users;
}
//package private methods so that wrapper methods are used, Room allows for this, but not private methods, hence the underscores to put people off using them :)
@Insert
abstract void _insertAll(List<Pet> pets);
@Insert
abstract void _insertAll(List<User> users);
@Query("SELECT * FROM User")
abstract List<UserWithPets> _loadUsersWithPets();
}
您可能希望在 PetDAO 中使用 insertAll(List
和 insertPetsForUser(User, List
方法来代替...划分您的 DAO 由您决定!:)
You may want to have the insertAll(List<Pet>)
and insertPetsForUser(User, List<Pet>)
methods in a PetDAO instead... how you partition your DAOs is up to you! :)
无论如何,这只是另一种选择.将 DAO 包装在 DataSource 对象中也有效.
Anyway, it's just another option. Wrapping your DAOs in DataSource objects also works.
这篇关于Android Room:使用 Room 插入关系实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!