我想返回插入的行ID以使用它来更新同一行中的某些值
@Entity(tableName = "course")
public class Course {
@PrimaryKey(autoGenerate = true)
private int id;
private String firebaseId;
}
@Dao
public interface CourseDao {
@Insert(onConflict = REPLACE)
long insertCourse(Course course);
@Query("UPDATE course SET firebaseId = :firebaseId WHERE id = :id")
void updateFirebaseId(int id, String firebaseId);
}
问题是我无法将Id返回主线程
public class Repository {
private static final Object LOCK= new Object();
private static Repository sInstance;
private final CourseDao mCourseDao;
private final AppExecutors mAppExecutors;
public void insertCourse(final Course course) {
mAppExecutors.diskIO().execute(new Runnable() {
@Override
public void run() {
mCourseDao.insertCourse(course);
}
});
}
public void updateCourse(final Course course) {
mAppExecutors.diskIO().execute(new Runnable() {
@Override
public void run() {
mCourseDao.updateCourse(course);
}
});
}
}
我尝试使用liveData但插入
时不支持Error:(34, 20) error: Methods annotated with @Insert can return either void, long, Long, long[], Long[] or List<Long>.
插入完成后是否可以返回课程的ID而无需编写单独的选择查询?
答案 0 :(得分:2)
LiveData
不支持 insert
。
我觉得有两种方法可以在后台线程中执行insert
操作,并将结果(long
)发送回Activity:
使用LiveData
,我个人喜欢这种方法:
public class Repository {
private LiveData<Long> insertedId = MutableLiveData()
public void insertCourse(final Course course) {
mAppExecutors.diskIO().execute(new Runnable() {
@Override
public void run() {
Long id = mCourseDao.insertCourse(course);
insertId.setValue(id);
}
});
}
}
使用Rx
:
return Single.fromCallable(() -> mCourseDao.insertCourse(course));
在这里,您可以在Single<Long>
Activity
。
醇>
注意:Repository
会将Long
返回给ViewModel
,而ViewModel
中会有LiveData
和setValue
的内容。
答案 1 :(得分:0)
我是用Java做到的
在需要ID的环境中:
let result = [{
"category": "Social Media",
"sub_category": "Facebook"
},
{
"category": "Social Media",
"sub_category": "Instagram"
},
{
"category": "Tech",
"sub_category": "Angular"
},
{
"category": "Tech",
"sub_category": "Javascript"
}
];
let data = {};
result.forEach((row) => {
if (!data[row.category]) {
data[row.category] = [];
}
if (!data[row.category].includes(row.sub_category)) {
data[row.category].push(row.sub_category);
}
});
console.log(data);
具有存储库的构造函数。...{}
public class MyIdClass {
ArrayList<Integer> someIds = new ArrayList<>(); //this could be a primitive it doesn't matter
在抽象类 MyDao中:(我无法承受足够的压力……,请使用更灵活的ABSTRACT CLASS DAO)
@FunctionalInterface //desugaring... normal interfaces are ok I guess?
public interface GetIdFromDao {
void getId(long id);
}
public void insertSomething(
Something something
) {
someRepository.insertSomething(
something,
id -> someIds.add((int)id) //lambda replacement, I think method reference cannot be done because of (int) casting, but if Array is type long it could be done.
);
}
}
在内部存储库中,如果您使用@Insert(onConflict = OnConflictStrategy.IGNORE)
protected abstract long protectedInsertSomething(Something something);
public void insert(
Something something,
MyIdClass.GetIdFromDao getIdFromDao
) {
//get long id with insert method type long
long newSomethingId = protectedInsertSomething(something);
getIdFromDao.getId(newSomethingId);
}
,则实际上可以通过VarAgrs,甚至是侦听器,传递所有内容,但请确保按照插入顺序将它们重铸,并使用Object类型或公共祖先类型。 / p>
AsyncTask<X, Y, Z>
也使用(Something) object[0];
(MyIdClass.GetIdFromDao) object[1];
new InsertAsyncTask<>(dao).execute(
something, //0
getIdFromDao //1
)
,什么也没发生
现在,如果您想进一步互动,可以将LiveData连接到侦听器,或构造Factory ViewModel ... 一个抽象的工厂ViewModel ...将会很有趣。 但是我相信DataBinding具有一个Observable视图模型,我认为它可以使用(?)...我真的不知道。