使用 Room 库获取最近插入的行 ID
Fetch recently inserted row id using Room library
我正在使用房间持久性库来更新数据库。我被困在想获取最近插入记录的 ID 的位置。
我知道只要 return 类型用于插入方法 returns id。但是我通过视图模型访问这个 Dao 方法。
我的DAO方法如下:
//MyDao
@Insert
long insert(RecordItem record);
通过执行以下操作从存储库访问此方法:
//MyRepository
public class MyRepository {
private MyDao myDao;
public MyRepository(@NonNull Application application) {
MainDatabase mainDatabase = MainDatabase.getInstance(application);
myDao = mainDatabase.myDao();
}
public void insert(RecordItem record) {
MainDatabase.dbWriteExecutor.execute(() -> {
myDao.insert(record);
});
}
}
然后从视图模型调用存储库方法如下:
//MyViewModel
public void insert(RecordItem record) {
repository.insert(record);
}
最后是视图模型方法:
//MyActivity
myViewModel.insert(record);
我的问题是,我不知道如何通过 viewmodel 方法得到 long returned。我尝试在存储库中这样做
//MyRepository
public class MyRepository {
private MyDao myDao;
private long id;
public MyRepository(@NonNull Application application) {
MainDatabase mainDatabase = MainDatabase.getInstance(application);
myDao = mainDatabase.myDao();
}
public long insert(RecordItem record) {
MainDatabase.dbWriteExecutor.execute(() -> {
id = myDao.insert(record);
});
return id;
}
}
以及随后对 viewmodel 方法的更改。
但是,它 returns 0,我想这是因为插入方法是在不同的线程上执行的,并且 id 在到达语句后立即被 returned(纠正我,如果我错了)。
提前致谢。
您可以通过以下方式解决您的问题:
创建回调接口如下:
public interface DbInsertCallback {
void onInsert(long insertedItemId);
}
然后在您的存储库上使用此接口 insert(RecordItem record)
方法如下:
public class MyRepository {
// ... Some repo code ...
public void insert(RecordItem record, DbInsertCallback callback) {
MainDatabase.dbWriteExecutor.execute(() -> {
long id = myDao.insert(record);
callback.onInsert(id);
});
}
// ... Rest of repo code ...
}
并且还在调用者站点上进行必要的更改 (即 ViewModel 和 Activity) 以提供此回调的对象 class 作为参数。要实现此接口,您可以创建该接口的对象以及实现,或者根据上下文传递它,例如提供 this
.
你也可以使用 RxJava 来解决这个问题,其中插入方法将 return Single<Long>
.
@Insert
Single<long> insert(RecordItem item)
然后在调用插入时调用 subscribe
以获取 returning id
或使用 flatMap
进行任何使用 RxJava 的进一步操作。
myDao.insert(record).subscribeWith(new DisposableSingleObserver<long>() {
@Override
public void onSuccess(long id) {
// handle the id
}
@Override
public void onError(Throwable e) {
// handle the error case
}
}
我建议您深入了解 RxJava,因为它使异步编程更加自然且更易于使用,而且 Room 也开箱即用地实现了它。
我正在使用房间持久性库来更新数据库。我被困在想获取最近插入记录的 ID 的位置。
我知道只要 return 类型用于插入方法 returns id。但是我通过视图模型访问这个 Dao 方法。
我的DAO方法如下:
//MyDao
@Insert
long insert(RecordItem record);
通过执行以下操作从存储库访问此方法:
//MyRepository
public class MyRepository {
private MyDao myDao;
public MyRepository(@NonNull Application application) {
MainDatabase mainDatabase = MainDatabase.getInstance(application);
myDao = mainDatabase.myDao();
}
public void insert(RecordItem record) {
MainDatabase.dbWriteExecutor.execute(() -> {
myDao.insert(record);
});
}
}
然后从视图模型调用存储库方法如下:
//MyViewModel
public void insert(RecordItem record) {
repository.insert(record);
}
最后是视图模型方法:
//MyActivity
myViewModel.insert(record);
我的问题是,我不知道如何通过 viewmodel 方法得到 long returned。我尝试在存储库中这样做
//MyRepository
public class MyRepository {
private MyDao myDao;
private long id;
public MyRepository(@NonNull Application application) {
MainDatabase mainDatabase = MainDatabase.getInstance(application);
myDao = mainDatabase.myDao();
}
public long insert(RecordItem record) {
MainDatabase.dbWriteExecutor.execute(() -> {
id = myDao.insert(record);
});
return id;
}
}
以及随后对 viewmodel 方法的更改。
但是,它 returns 0,我想这是因为插入方法是在不同的线程上执行的,并且 id 在到达语句后立即被 returned(纠正我,如果我错了)。
提前致谢。
您可以通过以下方式解决您的问题:
创建回调接口如下:
public interface DbInsertCallback {
void onInsert(long insertedItemId);
}
然后在您的存储库上使用此接口 insert(RecordItem record)
方法如下:
public class MyRepository {
// ... Some repo code ...
public void insert(RecordItem record, DbInsertCallback callback) {
MainDatabase.dbWriteExecutor.execute(() -> {
long id = myDao.insert(record);
callback.onInsert(id);
});
}
// ... Rest of repo code ...
}
并且还在调用者站点上进行必要的更改 (即 ViewModel 和 Activity) 以提供此回调的对象 class 作为参数。要实现此接口,您可以创建该接口的对象以及实现,或者根据上下文传递它,例如提供 this
.
你也可以使用 RxJava 来解决这个问题,其中插入方法将 return Single<Long>
.
@Insert
Single<long> insert(RecordItem item)
然后在调用插入时调用 subscribe
以获取 returning id
或使用 flatMap
进行任何使用 RxJava 的进一步操作。
myDao.insert(record).subscribeWith(new DisposableSingleObserver<long>() {
@Override
public void onSuccess(long id) {
// handle the id
}
@Override
public void onError(Throwable e) {
// handle the error case
}
}
我建议您深入了解 RxJava,因为它使异步编程更加自然且更易于使用,而且 Room 也开箱即用地实现了它。