我使用 Relation 在 Room 中添加了一对多关系. 我提到了this post为 Room 中的关系编写以下代码。
这篇文章讲述了如何从数据库中读取值,但将实体存储到数据库中导致 userId
为空,这意味着这两个表之间没有关系。
我不确定在拥有 的同时将
值。insert
User
和 List of Pet
放入数据库的理想方法是什么userId
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:
// 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;
}
现在要从 DB 中获取记录,我们使用以下 DAO
:
@Dao
public interface UserDao {
@Insert
fun insertUser(user: User)
@Query("SELECT * FROM User")
public List<UserWithPets> loadUsersWithPets();
}
编辑
我创建了这个问题 https://issuetracker.google.com/issues/62848977在问题跟踪器上。希望他们会为此做点什么。
最佳答案
您可以通过将 Dao 从接口(interface)更改为抽象类来做到这一点。
@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<Pet> pets
@Entity
public class User {
@PrimaryKey
public int id; // User id
@Ignored
public List<Pet> pets
}
然后道可以映射UserWithPets
给用户:
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;
}
这给你留下了完整的道:
@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();
}
您可能想要 insertAll(List<Pet>)
和 insertPetsForUser(User, List<Pet>)
而是 PetDAO 中的方法......如何划分 DAO 取决于您! :)
无论如何,这只是另一种选择。将您的 DAO 包装在 DataSource 对象中也可以。
关于安卓机房 : Insert relation entities using Room,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44667160/