以下是一个使用 Kotlin 和 Android Jetpack Room 的完整示例,涵盖 实体定义 → DAO 接口 → 数据库构建 → MVVM 集成 的全流程,采用协程和 Flow 实现异步操作与数据监听。
1. 添加依赖(build.gradle.kts)
dependencies {
val roomVersion = "2.7.2"
implementation("androidx.room:room-runtime:$roomVersion")
kapt("androidx.room:room-compiler:$roomVersion") // Kotlin 注解处理
implementation("androidx.room:room-ktx:$roomVersion") // 协程支持
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.0") // ViewModel 协程
}
2. 定义实体类(Entity)
@Entity(tableName = "notes")
data class Note(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
val title: String,
val content: String,
@ColumnInfo(name = "created_at")
val createdAt: Long = System.currentTimeMillis()
)
-
@Entity:声明数据库表名 -
@PrimaryKey:自增主键 -
@ColumnInfo:自定义列名(可选)
3. 定义 DAO 接口
@Dao
interface NoteDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(note: Note)
@Update
suspend fun update(note: Note)
@Delete
suspend fun delete(note: Note)
@Query("SELECT * FROM notes ORDER BY createdAt DESC")
fun getAllNotes(): Flow<List<Note>> // 使用 Flow 实时监听数据变化
@Query("SELECT * FROM notes WHERE title LIKE :query")
suspend fun searchNotes(query: String): List<Note>
}
-
协程支持:所有写操作(Insert/Update/Delete)使用
suspend -
Flow 监听:查询返回
Flow,数据变化时自动更新 UI
4. 构建数据库类
@Database(entities = [Note::class], version = 1, exportSchema = false)
abstract class NoteDatabase : RoomDatabase() {
abstract fun noteDao(): NoteDao
companion object {
@Volatile
private var INSTANCE: NoteDatabase? = null
fun getDatabase(context: Context): NoteDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
NoteDatabase::class.java,
"note_database.db"
).build()
INSTANCE = instance
instance
}
}
}
}
-
单例模式:避免重复打开数据库连接
-
@Volatile+synchronized:确保线程安全
5. 实现 Repository 层(数据抽象)
class NoteRepository(private val noteDao: NoteDao) {
val allNotes: Flow<List<Note>> = noteDao.getAllNotes()
suspend fun insert(note: Note) = noteDao.insert(note)
suspend fun update(note: Note) = noteDao.update(note)
suspend fun delete(note: Note) = noteDao.delete(note)
suspend fun search(query: String) = noteDao.searchNotes(query)
}
职责分离:ViewModel 不直接操作数据库,通过 Repository 中转
6. 创建 ViewModel
class NoteViewModel(application: Application) : AndroidViewModel(application) {
private val repository: NoteRepository
val allNotes: Flow<List<Note>>
init {
val dao = NoteDatabase.getDatabase(application).noteDao()
repository = NoteRepository(dao)
allNotes = repository.allNotes
}
fun insert(note: Note) = viewModelScope.launch(Dispatchers.IO) {
repository.insert(note)
}
fun delete(note: Note) = viewModelScope.launch(Dispatchers.IO) {
repository.delete(note)
}
}
-
协程作用域:
viewModelScope自动管理生命周期,避免内存泄漏 -
后台线程:使用
Dispatchers.IO执行数据库操作
7. 在 Activity 中使用(UI 层)
class MainActivity : AppCompatActivity() {
private val viewModel: NoteViewModel by viewModels {
NoteViewModelFactory(NoteDatabase.getDatabase(this).noteDao())
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 监听数据变化并更新 UI
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.allNotes.collect { notes ->
notesAdapter.submitList(notes)
}
}
}
// 添加新笔记
binding.fabAdd.setOnClickListener {
val note = Note(title = "新笔记", content = "内容...")
viewModel.insert(note)
}
}
}
// ViewModelFactory(用于依赖注入)
class NoteViewModelFactory(private val dao: NoteDao) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return NoteViewModel(Application(), NoteRepository(dao)) as T
}
}
-
生命周期感知:
repeatOnLifecycle确保只在界面活跃时收集数据 -
RecyclerView 适配器:使用
ListAdapter自动处理数据差异
552

被折叠的 条评论
为什么被折叠?



