在数据库中处理自己的对象(实体中的子实体)的房间

时间:2018-08-06 13:28:23

标签: java android android-room

我一直在研究这样的时间,以找出解决此问题的最佳方法。 假设我想将一个实体放入另一个实体

@Entity(tableName = "user")
public class User {

   @PrimaryKey(autoGenerate = true)
   private Long id;

   @ColumnInfo(name = "firstName")
   private String firstName;

   @ColumnInfo(name = "lastName")
   private String lastName;


   //getters & setters
}

ORMLite支持将自己的对象(实体)存储到另一个实体中,并且还包含在一个表中(不同于@Embedded in Room)。但是我发现会议室不支持这样的功能。因此,我的解决方案是将该实体的ID添加到目标实体。 (下面的代码摘自User实体,位于注释上方)

   @ForeignKey(entity = Photo.class, parentColumns = "id", childColumns = "userPhotoId")
   @ColumnInfo(name = "userPhotoId")
   private Long userPhotoId;

   @ForeignKey(entity = Home.class, parentColumns = "id", childColumns = "userHomeId")
   @ColumnInfo(name = "userHomeId")
   private Long userHomeId;

此外,我应该添加带有@Ignore注释的实体,如

   @Ignore
   private Photo userPhoto;

   @Ignore
   private House userHome;

然后我有一些用于数据管理的方法。

现在我正在使用这种方式设置数据。我认为这是一个非常复杂的解决方案。

public void insertUser(@NonNull User user) {
    new AsyncTask<User, Void, Void>() {

        @Override
        protected Void doInBackground(User... users) {
            User newUser = users[0];

            Photo photo = newUser.getUserPhoto();
            House home = newUser.getUserHome();
            Long photoId = dao.insert(photo);
            Long houseId = dao.insert(home);

            newUser.setUserPhotoId(photoId);
            newUser.setUserHouseId(houseId);

            dao.insert(newUser);
            return null;
        }
    }.execute(user);
}

关于获取数据逻辑,我正在使用观察者。

LiveData<User> userLiveData = dao.getUserById(userId);
userLiveData.observeForever(new Observer<User>() {
   @Override
   public void onChanged(@Nullable User user) {
   //...
   //the last line will remove an observer before ending.                      
   userLiveData.removeObserver(this);
}

这看起来很简单,但是如果您想从数据库中获取更多数据,它将变得更加复杂。  这不是我想要的。我的想法就像

User user = getUserById(..);
user.getPhoto();
//...
//and working without worries

insertUser(myUser);
//and I am sure that the sub-entities were added automatically without any special logic

如果我的查询返回 LiveData ,我正在寻找的最佳(也是最简单)的解决方案是使用实体从数据库实体发送/接收数据。

或者,如果您有任何更好的经验,我将感谢您提供的有用答复。

感谢任何想法,我认为这可能对许多人有帮助。

1 个答案:

答案 0 :(得分:0)

一个星期后,我找到了解决方案。所以我想分享。 因此,我的建议是将Threads(或Android的AsyncTasks)与ViewModel一起使用,而不要使用LiveDatas。

在下面检查此代码。

public class MyMV extends AndroidViewModel {
    private MutableLiveData<User> userLiveData = new MutableLiveData();

    //main logic for getting data from a db
    public void getUser(long userId) {
       new Thread(()-> {
          //do not use the '.setValue()', a post method will send a result to observers immediately
          userLiveData.postValue(new User(dao.getUserById(userId));
       }).start();
    }

    //UserLiveData getter
    public LiveData<User> getUserData() {
        return userLiveData;
    }
}

让我们转到一个活动或UI上的某个地方

//an observer is something like listener
myVM.getUserData().observe(this, user -> {
  //here we can work with user
});

如果您对视图模型有疑问,可以检查documentation