当前位置: 首页 > news >正文

Android-Kotlin基础(Jetpack④-Room)

Room 是 Jetpack 提供的一个 ORM(对象关系映射)库,简化了 Android 中的 SQLite 数据库操作,无需编写复杂的 SQL 语句就能实现数据的增删改查。

一、添加依赖

在 build.gradle(Module 级别)中添加以下依赖

dependencies {// Room 核心库implementation "androidx.room:room-runtime:2.5.2"// 编译器(kapt 用于 Kotlin)kapt "androidx.room:room-compiler:2.5.2"// Kotlin 扩展(可选,提供协程支持)implementation "androidx.room:room-ktx:2.5.2"
}

二、核心组件

Room 有 3 个核心组件:
Entity:对应数据库中的表(用 @Entity 注解)
Dao:数据访问对象,定义增删改查方法(用 @Dao 注解)
Database:数据库持有者,管理连接(用 @Database 注解)

三、完整代码实现

1. 创建 Entity(数据模型类)
import androidx.room.Entity
import androidx.room.PrimaryKey// 定义数据库表(表名默认是类名,也可自定义)
@Entity(tableName = "users")
data class User(// 主键,autoGenerate = true 表示自增@PrimaryKey(autoGenerate = true) val id: Int = 0,val name: String,val age: Int
)
2. 创建 Dao(数据访问接口)
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import kotlinx.coroutines.flow.Flow@Dao
interface UserDao {// 插入数据@Insertsuspend fun insert(user: User)// 更新数据@Updatesuspend fun update(user: User)// 删除数据@Deletesuspend fun delete(user: User)// 查询所有数据(返回 Flow,数据变化时自动通知)@Query("SELECT * FROM users ORDER BY id DESC")fun getAllUsers(): Flow<List<User>>// 根据 ID 查询@Query("SELECT * FROM users WHERE id = :id")suspend fun getUserById(id: Int): User?
}
3. 创建 Database 类
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import android.content.Context// 定义数据库,包含的表(entities)和版本号(version)
@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {// 提供 Dao 实例abstract fun userDao(): UserDao// 单例模式,避免重复创建数据库连接companion object {@Volatileprivate var INSTANCE: AppDatabase? = nullfun getDatabase(context: Context): AppDatabase {return INSTANCE ?: synchronized(this) {val instance = Room.databaseBuilder(context.applicationContext,AppDatabase::class.java,"user_database"  // 数据库名称).build()INSTANCE = instanceinstance}}}
}
4. 在 ViewModel 中使用
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launchclass UserViewModel(private val userDao: UserDao) : ViewModel() {// 将 Flow 转换为 LiveData,供 UI 观察val allUsers = userDao.getAllUsers().asLiveData()// 插入用户(在协程中执行,避免阻塞主线程)fun insertUser(user: User) {viewModelScope.launch {userDao.insert(user)}}// 更新用户fun updateUser(user: User) {viewModelScope.launch {userDao.update(user)}}// 删除用户fun deleteUser(user: User) {viewModelScope.launch {userDao.delete(user)}}
}
5. 在 Activity 中使用
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.roomdemo.databinding.ActivityMainBindingclass MainActivity : AppCompatActivity() {private lateinit var binding: ActivityMainBindingprivate lateinit var userViewModel: UserViewModeloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)// 获取数据库实例val db = AppDatabase.getDatabase(this)// 创建 ViewModeluserViewModel = ViewModelProvider(this)[UserViewModel::class.java]// 观察用户列表变化,更新 RecyclerViewuserViewModel.allUsers.observe(this) { users ->// 这里可以更新 RecyclerView适配器// adapter.submitList(users)}// 点击按钮添加用户binding.btnAdd.setOnClickListener {val name = binding.etName.text.toString()val age = binding.etAge.text.toString().toIntOrNull() ?: 0if (name.isNotEmpty()) {userViewModel.insertUser(User(name = name, age = age))}}}
}

上面的 Room 示例代码遵循了 Android 推荐的MVVM 架构模式。

MVVM 是一种软件架构模式,广泛应用于 Android、iOS 等客户端开发中,核心是通过分层解耦,让代码更易于维护、测试和扩展。其名称由三个核心部分的首字母组成:Model(模型)、View(视图)、ViewModel(视图模型)

Model:管数据(存、取、处理)。
View:管界面(展示、交互)。
ViewModel:管逻辑(连接 View 和 Model,处理业务)。

viewModelScope 是 Jetpack ViewModel 库中专门为 ViewModel 设计的协程作用域(Coroutine Scope),用于在 ViewModel 中安全地启动和管理协程,避免内存泄漏和生命周期问题。

http://www.lryc.cn/news/613386.html

相关文章:

  • RepoCoder:仓库级代码补全的迭代检索生成框架解析与应用前沿
  • 前缀和
  • 网卡名eth1、em1 、eno1、ens1 的区别
  • C++ vector 扩容时到底发生了什么?
  • 纯本地AI知识库搭建:DeepSeek-R1+AnythingLLM全流程
  • priority_queue的使用和模拟
  • Kotlin中String的==相等比较符
  • C语言sprintf、strcmp、strcpy、strcat函数详解:字符串操作的核心工具
  • 「日拱一码」045 机器学习-因果发现算法
  • 力扣238:除自身之外数组的乘积
  • LeetCode算法日记 - Day 4: 三数之和、四数之和
  • 力扣300:最长递增子序列
  • 优选算法 力扣 LCR 179. 查找总价格为目标值的两个商品 双指针降低时间复杂度 C++题解 每日一题
  • Cesium粒子系统模拟风场动态效果
  • 【Zephyr】02_从零教你开发芯片级ADC驱动(HAL层篇)
  • 第三章:【springboot】框架介绍MyBatis
  • 恒虚警检测(CFAR)仿真:杂波边缘与多目标场景分析
  • 在新建word中使用以前文件中的列表样式
  • java中override和overload的区别
  • Java 大视界 -- Java 大数据在智能安防门禁系统中的人员行为分析与异常事件预警(385)
  • AR技术:制造业质量控制的“智能革新”
  • Redis最新安装教程(WindowsLinux)
  • Kubernetes(k8s)之Service服务
  • SpringBoot的优缺点
  • 【更新被拒绝,因为推送的一个分支的最新提交落后于其对应的远程分支。】
  • VLMEvalKit使用记录
  • 公开致歉声明
  • P1690 贪婪的 Copy
  • idea工具maven下载报错:PKIX path building failed,配置忽略SSL检查
  • 量子计算入门 | 量子力学的发展