房间在数据库中使用自己的对象(实体中的子实体)
Room working with own objects in a database (sub-entities in entity)
我一直在研究这段时间,以找出解决这个问题的最佳和最简单的方法。
假设我想将一个实体放入另一个实体
@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 支持将自己的对象(实体)存储到另一个实体中,并且它还包含在 table 中(不像 @Embedded in Room)。但是我发现房间不支持这样的东西。所以我的解决方案是将该实体的 ID 添加到目标实体。 (下面的代码是从评论上方的用户实体中截取的)
@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;
然后我有用于数据管理的 getter 和 setter。
我现在就是用这种方式设置数据的。在我看来,这是一个非常复杂的解决方案。
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
如果我的查询 return LiveData秒。
或者如果您有任何更好的体验,我将不胜感激。
感谢您的任何想法,我认为这可能对很多人都有帮助。
一周后我找到了解决方案。所以我想分享一下。
所以我的建议是将 Threads(或 AsyncTasks for Android)与 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;
}
}
让我们移动到 activity 或 UI
上的某处
//an observer is something like listener
myVM.getUserData().observe(this, user -> {
//here we can work with user
});
如果您在使用视图模型时遇到问题,可以查看 documentation。
我一直在研究这段时间,以找出解决这个问题的最佳和最简单的方法。 假设我想将一个实体放入另一个实体
@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 支持将自己的对象(实体)存储到另一个实体中,并且它还包含在 table 中(不像 @Embedded in Room)。但是我发现房间不支持这样的东西。所以我的解决方案是将该实体的 ID 添加到目标实体。 (下面的代码是从评论上方的用户实体中截取的)
@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;
然后我有用于数据管理的 getter 和 setter。
我现在就是用这种方式设置数据的。在我看来,这是一个非常复杂的解决方案。
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
如果我的查询 return LiveData秒。
或者如果您有任何更好的体验,我将不胜感激。
感谢您的任何想法,我认为这可能对很多人都有帮助。
一周后我找到了解决方案。所以我想分享一下。 所以我的建议是将 Threads(或 AsyncTasks for Android)与 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;
}
}
让我们移动到 activity 或 UI
上的某处//an observer is something like listener
myVM.getUserData().observe(this, user -> {
//here we can work with user
});
如果您在使用视图模型时遇到问题,可以查看 documentation。