Получить недавно вставленный идентификатор строки с помощью библиотеки комнаты - PullRequest
2 голосов
/ 25 мая 2020

Я использую библиотеку сохраняемости помещения для обновления базы данных. Я застрял в точке, где я хочу получить идентификатор недавно вставленной записи.

Я знаю, что использование long, поскольку возвращаемый тип для метода вставки возвращает идентификатор. Но я обращаюсь к этому методу 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);
        });
    }
}

И метод репозитория вызывается из viewmodel следующим образом:

//MyViewModel
public void insert(RecordItem record) {
    repository.insert(record);
}

И, наконец, метод viewmodel как:

//MyActivity
myViewModel.insert(record);

Моя проблема в том, что я не знаю, как я могу получить длинный возврат через метод viewmodel. Я пробовал сделать это в репозитории

//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;
    }
}

и последующие изменения в методе модели просмотра.

Однако он возвращает 0, что, как я полагаю, происходит, поскольку метод вставки выполняется в другом потоке и id возвращается, как только достигается инструкция (поправьте меня, если я ошибаюсь).

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 26 мая 2020

Вы также можете использовать Rx Java для этой проблемы, где метод вставки вернет Single<Long>.

@Insert
Single<long> insert(RecordItem item)

Затем при вызове вставки вы вызываете subscribe, чтобы получить возвращаемый id или используйте flatMap для любых дальнейших действий, используя Rx Java.

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
    }
}

Я предлагаю вам взглянуть на Rx Java дальше по строке, так как это делает асинхронное программирование намного более естественным и простым to work with Room также реализует это из коробки.

1 голос
/ 26 мая 2020

Вы можете подойти к следующему решению вашей проблемы:

Создайте интерфейс обратного вызова, как показано ниже:

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(() -> {
            int id = myDao.insert(record);
            callback.onInsert(id);
        });
    }

    // ... Rest of repo code ...
}

А также внесите необходимые изменения на вызывающем сайте (т.е. ViewModel и Activity) , чтобы также предоставить объект этого класса обратного вызова в качестве параметра. Чтобы реализовать этот интерфейс, вы можете либо создать объект этого интерфейса вместе с реализацией, либо передать его контекстно, например, предоставив this.

...