使用 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 也开箱即用地实现了它。