首页 > 解决方案 > Android Room SQlite MVVM:在 var 中插入和捕获 PK 后返回 PK 以传递给其他活动

问题描述

试图让插入返回 PK,以便我可以在 var 中捕获它并将其传递给其他活动。

道:

 @Dao public interface NoteDao {
 @Insert
 long insert(Note note);

存储库:

private MutableLiveData<Long> noteInsertedLiveData = new MutableLiveData();
private NoteDao noteDao;
private LiveData<List<Note>> allNotes;


public NoteRepository(Application application) {

    NoteDatabase database = NoteDatabase.getInstance(application);
    noteDao = database.noteDao();
    allNotes = noteDao.getAllNotes2();
}

public void insert(OnTaskCompleted onTaskCompleted, Note note) {

    new InsertAsyncTask(noteDao, onTaskCompleted).execute(note);

}
public LiveData<Long> getNoteInsertedLiveData() {
    return noteInsertedLiveData;
}

异步:

  private static class InsertNoteAsyncTask extends AsyncTask<Note, Void, Long> {


    private long sqCbtId = -1;
    private NoteDao noteDao;
    private OnTaskCompleted onTaskCompleted;


    private InsertNoteAsyncTask(NoteDao noteDao, OnTaskCompleted onTaskCompleted) {
        this.noteDao = noteDao;
        this.onTaskCompleted = onTaskCompleted;
    }

    @Override
    protected Long doInBackground(Note... notes) {

        return noteDao.insert(notes[0])
    }

    @Override
    protected void onPostExecute(Long result) {

        onTaskCompleted.onTaskCompleted(result);
    }
}

查看型号:

public long insert(Note note){
sqCbtId = repository.insert(note); return sqCbtId; }

活动 :

Note note = new Note(userId, therapistId, automaticThoughtString, distortions, challengeThoughtString, alternativeThoughtString, postedWorkout);
sqCbtId = noteViewModel.insert(note);

实体:

@Entity(tableName = "note_table")
public class Note {

@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "cbtId")
private long sqCbtId;

@NonNull
@ColumnInfo(name = "userId")
private int userId;

@NonNull
@ColumnInfo(name = "therapistId")
private int therapistId;

@NonNull
@ColumnInfo(name = "automaticThought")
private String automaticThought;

@NonNull
@ColumnInfo(name = "distortions")
private int distortions;

@NonNull
@ColumnInfo(name = "challengeThought")
private String challengeThought;

@NonNull
@ColumnInfo(name = "alternativeThought")
private String alternativeThought;

@NonNull
@ColumnInfo(name = "postedWorkout")
private String postedWorkout;

我在这一行有一个错误:

新的 InsertAsyncTask(noteDao, onTaskCompleted).execute(note)

它指出 InsertASyncTask 不能应用于参数(naoteDao,onTaskCompleted)

标签: androidsqlitemvvmandroid-sqliteandroid-room

解决方案


SQLite 和 Room 的@Insert实现返回插入行的行 ID。如果主键不是自动生成的,您已经知道它,只要插入的没有返回-1,这表示错误。如果主键是自动生成的,则需要再次查询。

由于您的主键类型为long,即INTEGER对于 SQLite,rowId 成为该行的主键。看到这个:https ://www.sqlite.org/rowidtable.html

因此,在这种情况下,您无需再次查询主键。只需使用返回的 rowId @Insert(如果不是-1)。

您的代码错误:

sqCbtId = note.getSqCbtId(); return sqCbtId;

这是sqCbtId从您刚刚插入数据库的对象中获取的。不会为此对象生成 id。它存储在数据库中。从AsyncTask's获取 idonPostExecute

代码:(忽略任何编译错误或拼写错误,不是在 IDE 上编写的:P)

class ViewModel
{
    private MutableLiveData<Long> noteInsertedLiveData = new MutableLiveData();

    public long insert(Note note) {

        new InsertNoteAsyncTask(noteDao, new InsertNoteAsyncTask.Listener {
            @override
            void onNoteInserted(Long sqCbtId) {
                noteInsertedLiveData.setValue(sqCbtId);
            }
        }).execute(note);
        sqCbtId = note.getSqCbtId(); return sqCbtId; 

    }

    public LiveData<Long> getNoteInsertedLiveData() {
        return noteInsertedLiveData;
    }

    private static class InsertNoteAsyncTask extends AsyncTask<Note, Void, Long> {

        private long sqCbtId = -1;
        private NoteDao noteDao;
        private Listener listener;

        private InsertNoteAsyncTask(NoteDao noteDao, Listener listener) {
            this.noteDao = noteDao; 
            this.listener = listener;
        }

        @Override
        protected Long doInBackground(Note... notes) {
        sqCbtId = noteDao.insert(notes[0]);
        return sqCbtId;
        }

        @Override
        protected void onPostExecute(Long result) {
            listener.onNoteInserted(result);
        }

        interface Listener {
            void onNoteInserted(Long sqCbtId);
        }
    }
}

在您的活动中

noteViewModel.getNoteInsertedLiveData().observe(this, /** add Observer here to get update on id after every insert in db **/);


Note note = new Note(userId, therapistId, automaticThoughtString, distortions, challengeThoughtString, alternativeThoughtString, postedWorkout);
noteViewModel.insert(note);


推荐阅读