使用列值从 Room 检索数据 - Room

Retrieve data from Room using Column Value - Room

我的房间数据库中有两个 table - 事件和注释。对于我在 RecycleView 中显示的每个事件 - 我有一个 link 来启动该事件的注释。第一次点击 - 创建注释。第二次单击该注释时,我想检索以前的注释然后进行编辑。此外,我通过传递适当的值将相同的 activity 用于已经 edit/create 的新笔记,这有效但使用了 parcelized 笔记。

用于编辑现有事件注意 - 我正在使用 putExtra 方法发送事件 ID(它也存储在注意 table 中 - 不是作为外键)。 DB结构如下(assocId指的是eventId)

视图模型

    fun setNotesByAssocEventId(assocEventId: String): Note {
    return dao.getByAssocEventId(assocEventId)
}

DAO

    @Query("SELECT * FROM notes WHERE assocEventId = :assocEventId")
    fun getByAssocEventId(assocEventId: String): Note

笔记实体

@Entity(tableName = "notes")
        @Parcelize
data class Note(
    //PrimaryKey annotation to declare primary key with auto increment value
    //ColumnInfo annotation to specify the column's name
    @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") var id: Int = 0,
    @ColumnInfo(name = "assocEventId") var assocEventId: String = "",
    @ColumnInfo(name = "title") var title: String = "",
    @ColumnInfo(name = "label") var label: String = "",
    @ColumnInfo(name = "date") var date: String = "",
    @ColumnInfo(name = "time") var time: String = "",
    @ColumnInfo(name = "updatedDate") var updatedDate: String = "",
    @ColumnInfo(name = "updatedTime") var updatedTime: String = "",
    @ColumnInfo(name = "body") var body: String = ""
) : Parcelable

我正在使用下面的代码来 edit/create 新笔记。虽然我能够 create/Edit 笔记。我无法使用 eventId 检索特定事件的节点。当我分配从 ViewModel 返回的注释对象时,我收到的错误之一是注释对象尚未初始化。可能是什么问题?

assocID是使用putExtra得到的事件ID,对应的事件备注要取...

private lateinit var binding: ActivityEditNoteBinding
private lateinit var notesViewModel: NotesViewModel
private lateinit var note: Note
private var assocId: String? = ""
private var isUpdate = false
private val dateChange = DateChange()

var refUsers: DatabaseReference? = null
var firebaseUser: FirebaseUser? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityEditNoteBinding.inflate(layoutInflater)
    setContentView(binding.root)
    assocId = intent.getStringExtra("eventId").toString()

    initView()
    initListener()
}

private fun initView() {

    firebaseUser = FirebaseAuth.getInstance().currentUser

    initViewModel()

    if (assocId != null) {
        findViewById<TextView>(R.id.editNote).text = "Edit Event Note"
        Toast.makeText(this, "EvetnId received", Toast.LENGTH_SHORT).show()
        isUpdate = true
        binding.editNoteDelete.visibility = View.VISIBLE
        notesViewModel.getNotes()
        note = notesViewModel.setNotesByAssocEventId("%${assocId}%")
        binding.editTextTitle.setText(note.title)
        binding.editTextBody.setText(note.body)
        binding.editTextTitle.setSelection(note.title.length)

        //set spinner position
        val compareValue = note.label
        val adapter = ArrayAdapter.createFromResource(
            this, R.array.NoteSpinnerVals,
            android.R.layout.simple_spinner_item
        )

        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
        binding.spLabel.adapter = adapter
        val spinnerPosition = adapter.getPosition(compareValue)
        binding.spLabel.setSelection(spinnerPosition)

    }

}

private fun initViewModel() {
    notesViewModel = ViewModelProvider(this).get(NotesViewModel::class.java)
}


private fun initListener() {
  //  binding.editNoteBack.setOnClickListener(this)
    binding.editNoteSave.setOnClickListener(this)
    binding.editNoteDelete.setOnClickListener(this)
}

private fun deleteNote(note: Note) {
    notesViewModel.deleteNote(note)
    Toast.makeText(this@EditNote, "Note removed", Toast.LENGTH_SHORT).show()
}

private fun showDialog() {

    AwesomeDialog.build(this)
        .position(AwesomeDialog.POSITIONS.CENTER)
        .title("Delete the note?")
        .icon(R.drawable.ic_delete_black)
        .background(R.drawable.background_dialog)
        .onPositive(
            "Yes, delete",
            buttonBackgroundColor = R.drawable.button_bg,
            textColor = ContextCompat.getColor(this, R.color.white)
        ) {
            deleteNote(note)
            val intent = Intent(this, MainActivity::class.java)
            startActivity(intent)
            finish()
        }
        .onNegative(
            "Cancel",
            buttonBackgroundColor = R.drawable.button_bg,
            textColor = ContextCompat.getColor(this, R.color.white)
        ) {

        }

}

ViewModel 代码

    class NotesViewModel(application: Application) : AndroidViewModel(application) {
    private val context = getApplication<Application>().applicationContext
    private val listNotes = MutableLiveData<ArrayList<Note>>()
    private var dao: NoteDao

    init {
        val database = AppDatabase.getDatabase(context)
        dao = database.getNoteDao()
    }

    fun setNotes() {
        val listItems = arrayListOf<Note>()

        listItems.addAll(dao.getAll())
        listNotes.postValue(listItems)
    }

    fun setNotesByType(label: String) {
        val listItems = arrayListOf<Note>()

        listItems.addAll(dao.getByLabel(label))
        listNotes.postValue(listItems)
    }

    fun setNotesByTitle(title: String) {
        val listItems = arrayListOf<Note>()

        listItems.addAll(dao.getByTitle(title))
        listNotes.postValue(listItems)
    }

    fun setNotesByAssocEventId(assocEventId: String): Note {
        return dao.getByAssocEventId(assocEventId)
    }

    fun insertNote(note: Note) {
        dao.insert(note)
    }

    fun updateNote(note: Note) {
        dao.update(note)
    }

    fun deleteNote(note: Note) {
        dao.delete(note)
    }

    fun getNotes(): LiveData<ArrayList<Note>> {
        return listNotes
    }

}

DAO中的方法需要稍微改动一下

@Query("SELECT * FROM notes WHERE assocEventId = :assocEventId")
    fun getByAssocEventId(assocEventId: String): Note

应该是

@Query("SELECT * FROM notes WHERE assocEventId LIKE :assocEventId")
    fun getByAssocEventId(assocEventId: String): LiveData<List<Note>>

为了支持通配符搜索,"%${assocId}%",LIKE关键字。

只获得一张Note

@Query("SELECT * FROM notes WHERE assocEventId LIKE :assocEventId LIMIT 1")
    fun getByAssocEventId(assocEventId: String): LiveData<Note>

在视图模型中

fun setNotesByAssocEventId(assocEventId: String): LiveData<Note>{
     return dao.getByAssocEventId(assocEventId)
   }

在activity

notesViewModel.setNotesByAssocEventId("%${assocId}%").observe(this, {
   if(it!=null){
     //if you using for single note only
   }

   //if(it.isNotEmpty()){
     //if you using for list
   //}
})