使用列值从 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
//}
})
我的房间数据库中有两个 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
//}
})