android - 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)
解决方案
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);
推荐阅读
- java - 为什么我的凯撒加密问题没有运行?
- vue.js - 如何在Vuetify中持续一段时间后创建淡入淡出警报?
- r - 根据其他元素更新 .SD 组中的最后一个元素
- json - 如何将数组传递给同时接受 XML 和 JSON 有效负载的 Web API POST 方法?
- php - 将作曲家 json 转换为 .php 文件
- javascript - 如何在 Js 中将变量设为静态?
- javascript - Typescript:将接口类型序列化为类数组
- python - 是否有可能更pythonic?
- c# - 如何显示 XML 文件的特定部分?
- arrays - 在数据构建之前启动 Swift View