目录
3. 创建 DAO 接口: 创建一个用于访问笔记数据的 DAO 接口
5.userRoom的写法(简单写一下,不使用Adapter等操作了)
前言
以前学过Room的设计模式,但是有关细节处理方面有些忘记了,比如一些注解为何这样写什么的,现在我忘记了还真答不上来,在这里重拾一下过去的知识,以便更好的学接下来的有关Room进阶的知识。
一、Room的设计模式
-
实体(Entity): 定义数据库中的表结构。每个实体类对应数据库中的一个表,类中的每个字段对应表中的一个列。通常,实体类使用
@Entity
注解进行标记,并且每个实体类需要定义一个主键。 -
数据访问对象(DAO): 提供用于访问数据库的方法。每个 DAO 类都包含一组用于执行 CRUD 操作(创建、读取、更新、删除)的方法。DAO 类通常使用
@Dao
注解进行标记,并且可以使用 Room 提供的各种注解来定义查询、更新和删除方法。 -
数据库(Database): 是 Room 库的核心组件,表示应用程序的数据库。数据库类应该是抽象类,并且通常会扩展 RoomDatabase。在数据库类中,您需要定义与数据库相关联的实体列表,并提供一个方法来获取与数据库关联的 DAO
:Room是使用SQLite 数据库的持久性库的,为体现这种解耦的设计模式,我们进行了必要封装使用,使程序看的更加简洁明了,也更容易维护不易出错。
比如一个人来图书馆借书:
1.李华(要借三本书,需要借一个月),这李华name, 书本数量number,借书事件monthtime这会被封装成一个实体(Entity)
2.李华接下来要去操作平台或者手机进行借书的相关流程(登记),这就是数据访问对象(DAO)
3.整个书源和相关平台管理等就是数据库(Database)
二、实际操作(附代码,相关说明在注解中)
1.引入Gradle 依赖(官网推荐配置)
代码如下(示例):
implementation "androidx.room:room-runtime:2.6.1" kapt "androidx.room:room-compiler:2.6.1" implementation "androidx.room:room-ktx:2.6.1"
2.实体类(Entity)
代码如下(示例):
@Entity(tableName = "notes")//实体类中使用 @Entity注解时指定数据库表的名称为 "notes" data class Note( @PrimaryKey(autoGenerate = true)//id设置为主键,并自动增长 val id: Long = 0, val title: String, val content: String )
3. 创建 DAO 接口: 创建一个用于访问笔记数据的 DAO 接口
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query@Dao
interface NoteDao {//调用方可以通过调用
getAllNotes()
方法来获取数据库中所有笔记的列表//返回一个
List<Note>
类型的列表,具体的实现注解已经完成了
@Query("SELECT * FROM notes")
fun getAllNotes(): List<Note>@Insert
fun insert(note: Note)
}
4.声明数据库类:
创建一个继承自 RoomDatabase
的抽象类(RoomDatabase
是 Android 中用于管理和访问 Room 数据库的抽象类。继承其中然后实现其中的方法),并在其中声明数据库版本和实体列表,获得数据库的操作,而且一般设计为单例模式。
@Database(entities = [Note::class], version = 1, exportSchema = false) //这个注解用于声明数据库的信息,如实体类信息,版本信息 //AppDatabase类被声明为抽象类的主要原因是为了定义数据库的结构,而不提供数据库的具体实现 abstract class AppDatabase : RoomDatabase() { abstract fun noteDao() : NoteDao //提供NoteDao的抽象方法 companion object {//companion object中的成员在类的级别上是静态的,且只访问一次 private var instance: AppDatabase ?= null //等会用来接收创建实例的 fun getInstance(context: Context) : AppDatabase { return instance ?: synchronized(this){ //是空就创建数据库(单例模式) Room.databaseBuilder(context, AppDatabase::class.java, "db_feng") .build().also { instance = it }// 使用 also 函数将构建的数据实 // 赋值给 instance变量,并返实例 } } } }
5.userRoom的写法(简单写一下,不使用Adapter等操作了)
package com.example.applicationflow
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import com.example.applicationflow.Entity1.Note
import com.example.applicationflow.db2.AppDatabase
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class UserRoom : AppCompatActivity() {
private lateinit var db : AppDatabase
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_user_room)
db = AppDatabase.getInstance(applicationContext)
findViewById<Button>(R.id.buttonAddNote).setOnClickListener{
addNote()
displayNotes()
}
}
private fun addNote(){
val title = findViewById<EditText>(R.id.editTextTitle).text.toString()//获取布局编辑框内容
val context = findViewById<EditText>(R.id.editTextContent).text.toString()
//在主线程上执行了数据库操作,而 Room 不允许在主线程上执行长时间运行的数据库操作,使用协程
CoroutineScope(Dispatchers.IO).launch {
Log.d("feng", "hua")
db.noteDao().insert(Note(title = title, content = context))
}
}
//回到主线程
private fun displayNotes() {
CoroutineScope(Dispatchers.Main).launch {
try {
val notes = withContext(Dispatchers.IO) {
db.noteDao().getAllNotes() // 在 IO 线程中获取笔记数据
}
val noteTextList = notes.joinToString("\n") { "${it.title}: ${it.content}" } // 将笔记数据转换为一个字符串
val textView = findViewById<TextView>(R.id.textViewNotes)
textView.text = noteTextList
Log.d("feng", "jian")
//applicationContext 是应用程序级别的上下文,可以在整个应用程序范围内访问
Toast.makeText(applicationContext, "显示成功", Toast.LENGTH_SHORT).show()
} catch (e: Exception) {
// 错误处理
Toast.makeText(applicationContext, "显示失败:${e.message}", Toast.LENGTH_SHORT).show()
}
}
}
}
6.结果显示
总结
还是要多复习,多练练一些细节,不懂的多查查,特别官网上的最新解释,有时能解释你的困惑,有安卓方面的大佬可以多指点一下我这个菜鸟。