我在ANDROID应用程序中使用ROOM + RXJAVA作为SQLITE数据库。
我有一个问题。我需要插入一条新记录,但在此之前查询更多信息。
我使用 Maybe、Single 和 Completable。
我需要执行以下操作:
1 个查询。需要查出牛的ID:
@Query("SELECT " + COW_COLUMN_ID + " FROM " + TABLE_COW
+ " WHERE " + COW_COLUMN_RFID + " = :rfid ")
Maybe<Integer> getIdCowByRFID(String rfid);
2查询。我需要创建一个权重并将生成的牛 ID 添加到其中
@Insert
Maybe<Long> insert(WeightingDbEntity weighting);
如何正确做?将异步查询嵌套在另一个异步查询中并不完全正确。请告诉我。
如果你进行同步查询,那么就没有问题,因为1个查询的结果已经可用,如果需要的话,执行2个查询。在这种情况下,我是否需要向ROOM添加同步查询(allowMainThreadQueries)?或者我应该采取不同的做法?如何将 2 个 Maybe 查询合并为一个并以事务模式(@Transaction)执行?
我在这里读到:https://developer.android.com/reference/android/arch/persistence/room/Transaction
但是这个例子是关于同步查询的。以及如何使用 Maybe 正确地做到这一点?
使用带注释的
@Dao
而不是 abstract class
(因为后者不允许带有主体的方法)。如果您随后使用 interface
和
@Query("")
注释放在具有可以调用先前定义的方法的主体的方法之前。
带有空查询的 @Transaction
@Query
和
insert
位于同一个抽象类中(简化了问题),那么你可以得到类似的东西(注意我从未使用过 RXJava):-getIdCowByRFID
以下是显示上述技术的屏幕截图,其中包含
@Query("")
@Transaction
Maybe<Long> doBoth(String rfid, WeightingDbEntity w) {
Maybe<Integer> id = getIdCowByRFID;
.... do whatever needs to be done/checked
return insert(w);
}
注解类,
@Dao
抽象类,其中包含检索 @Database
类的方法(以便编译将检查这些方法)。尽管底层 @Dao
带注释的类不同:-
这是我的 DAO:
@Entity
也许这样更好:
@Insert
public abstract Maybe<Long> insert(WeightingDbEntity weighting);
@Query("SELECT MAX(" + WEIGHTING_COLUMN_ID + ") FROM " + TABLE_WEIGHTING
+ " WHERE " + WEIGHTING_COLUMN_COW_ID + " = :id")
public abstract Maybe<Integer> getMaxIdFromWeightingByCowId(int id);
@Transaction
public Maybe<Long> addWeighting(int idCow, String date, float weight, float weightGain, String description){
getMaxIdFromWeightingByCowId(idCow).subscribe(new MaybeObserver<>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onSuccess(@NonNull Integer idCow) {
WeightingDbEntity weightingDbEntity = new WeightingDbEntity(idCow, weight, weightGain, date, description);
insert(weightingDbEntity);
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
}
或者如果我想在另一个线程中得到结果
@Insert
public abstract Long insertSync(WeightingDbEntity weighting);
@Query("SELECT MAX(" + WEIGHTING_COLUMN_ID + ") FROM " + TABLE_WEIGHTING
+ " WHERE " + WEIGHTING_COLUMN_COW_ID + " = :id")
public abstract int getMaxIdFromWeightingByCowId(int id);
@Transaction
public Long addWeighting(int idCow, String date, float weight, float weightGain, String description){
long idCow = getMaxIdFromWeightingByCowId(idCow);
// Here will be check for idCow
WeightingDbEntity weightingDbEntity = new WeightingDbEntity(idCow, weight, weightGain, date, description);
insert(weightingDbEntity);
}
我有 2 个实体:
牛
@Query("SELECT MAX(" + WEIGHTING_COLUMN_ID + ") FROM " + TABLE_WEIGHTING
+ " WHERE " + WEIGHTING_COLUMN_COW_ID + " = :id")
public abstract int getMaxIdFromWeightingByCowIdSync(int id);
@Query("SELECT " + WEIGHTING_COLUMN_NUM + " FROM " + TABLE_WEIGHTING
+ " WHERE " + WEIGHTING_COLUMN_ID + " = :id")
public abstract int getNumWeightingByIdSync(int id);
@Insert
public abstract Maybe<Long> insert(WeightingDbEntity weighting);
@Transaction
public Maybe<Long> addWeighting(int idCow, String date, float weight, float weightGain){
int maxIdWeighting = getMaxIdFromWeightingByCowIdSync(idCow);
if (maxIdWeighting > 0) {
int num = getNumWeightingByIdSync(maxIdWeighting);
if (num > 0) {
return insert(new WeightingDbEntity(num + 1, idCow, weight, weightGain, maxIdWeighting, date));
}
}
return Maybe.empty();
}
公共类 CowDbEntity {
@Entity(tableName = TABLE_COW)
....
重量
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = COW_COLUMN_ID)
private int id;
@ColumnInfo(name = COW_COLUMN_RFID)
private String rfid;
@ColumnInfo(name = COW_COLUMN_EAR_TAG)
private String earTag;
@ColumnInfo(name = COW_COLUMN_GROUP)
private String group;
@ColumnInfo(name = COW_COLUMN_TYPE)
private String type;
@ColumnInfo(name = COW_COLUMN_NAME)
private String name;
@ColumnInfo(name = COW_COLUMN_IP_SERVER)
private String ipServer;
@ColumnInfo(name = COW_COLUMN_IS_DELETE)
private boolean isDelete;
...
我也使用DAO:
对于牛
public class WeightingDbEntity {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = WEIGHTING_COLUMN_ID)
private int id;
@ColumnInfo(name = WEIGHTING_COLUMN_NUM, defaultValue = "0")
private int num;
@ColumnInfo(name = WEIGHTING_COLUMN_COW_ID)
private int cowId;
@ColumnInfo(name = WEIGHTING_COLUMN_FIXED_WEIGHT)
private float fixedWeight;
@ColumnInfo(name = WEIGHTING_COLUMN_WEIGHT_GAIN, defaultValue = "0")
private float weightGain;
@ColumnInfo(name = WEIGHTING_COLUMN_PREV_RECORD, defaultValue = "0")
private int prevRecord;
@ColumnInfo(name = WEIGHTING_COLUMN_DATE)
private String date;
@ColumnInfo(name = WEIGHTING_COLUMN_WEIGHT_SERVER_ID, defaultValue = "0")
private int idWeightServer;
公共接口 CowDao {
@Dao
...
和重量
@Query("SELECT * FROM " + TABLE_COW)
List<CowDbEntity> getAll();
@Transaction
@Query("SELECT * FROM " + TABLE_COW)
List<CowWithHistories> getAllCowWithHistories();
@Transaction
@Query("SELECT * FROM " + TABLE_COW)
List<CowWithWeightings> getAllCowWithWeightings();
@Insert
long insert(CowDbEntity cow);
@Update
int update(CowDbEntity cow);
@Delete
void delete(CowDbEntity cow);
@Query("SELECT EXISTS (SELECT " + COW_COLUMN_GROUP
+ " FROM " + TABLE_COW
+ " WHERE " + COW_COLUMN_GROUP + " = :group)")
boolean isGroupExist(String group);
@Query("SELECT DISTINCT " + COW_COLUMN_EAR_TAG + " FROM " + TABLE_COW)
List<String> readEarTags();
公共接口WeightingDao {
@Dao
...
我有一个问题。我需要做类似的事情:
@Query("SELECT * FROM " + TABLE_WEIGHTING)
List<WeightingDbEntity> getAll();
@Query("SELECT * FROM " + TABLE_WEIGHTING + " WHERE " + WEIGHTING_COLUMN_ID + " = :id")
WeightingDbEntity getById(long id);
@Transaction
@Query("SELECT * FROM " + TABLE_WEIGHTING)
List<WeightingWithComment> getAllWeightingWithComments();
@Insert
long insert(WeightingDbEntity weighting);
@Update
int update(WeightingDbEntity weighting);
@Delete
void delete(WeightingDbEntity weighting);
或
@Transaction
insertWeightAndCow(CowDbEntity cow, WeightingDbEntity weighting) {
insert(cow);
insert(weighting);
}
但是查询属于不同的类别。我不知道如何做得更好。