HarmonyOS 鸿蒙Next数据库Room
HarmonyOS 鸿蒙Next数据库Room
Room**
ORM(Object Relational Mapping):也叫对象关系映射。
我们使用的是面向对象的编程语言,则我们使用的数据库是关系型数据库,将面向对象的语言和面向关系的数据库之间建立一种映射关系就是ORM
Room由三部分组成:Entity,Dao,Database
Entity:定义封装实际数据的实体类,每个实体类在数据库中都有对应的表,并且表中的列根据实体类的字段自动生成 Dao:对数据库的各项操作进行封装 Database:定义数据库中的关键信息,包括数据库的版本号,包含的实体类,提供Dao层的访问实例
- 添加插件和依赖
plugins {
...
id("kotlin-kapt")
}
dependencies {
implementation("androidx.room:room-runtime:2.1.0")
kapt("androidx.room:room-compiler:2.1.0")
...
}
- 给每个实体类添加id字段,并且声明为实体类
@Entity //注解声明为实体类
data class User(val firstName:String,val lastName:String,val age:Int){
@PrimaryKey(autoGenerate=true) //添加id字段,@PrimaryKey声明为主键,并且设置为自动生成
var id:Long=0
}
- 创建UserDao接口,声明为Dao
@Dao
interface UserDao {
@Insert
fun insertUser(user: User):Long //添加数据并且返回主键id
@Update
fun updateUser(newUser: User)
@Delete
fun deleteUser(user: User)
//查找数据时或者以非实体类参数来进行增删改时,都必须要用@Query注解,可以动态检查SQL语法,如果有问题就会在编译时期报错
@Query("select * from User")
fun loadAllUsers():List<User>
@Query("delete from User where lastName=:lastName")
fun deleteUserByLastName(lastName:String):Int
@Query("delete from User") //删除表中所有数据
fun deleteAllUsers():Int //返回删除的行数
}
- 定义database:数据库的版本号,包含的实体类,提供Dao层的访问实例
[@Database](/user/Database)(version=1, entities = [User::class])
//必须继承自RoomDatabase,并且声明为抽象类
abstract class AppDatabase:RoomDatabase(){
abstract fun userDao():UserDao //提供抽象方法获取Dao实例
//用单例模式获取AppDatabase的实例
companion object{
private var instance:AppDatabase?=null
@Synchronized
fun getDatabase(context: Context):AppDatabase{
instance?.let{
return it //不为空直接返回
}
//如果为空则利用Room的databaseBuilder构建实例,第一个参数不能用context,否则容易内存泄漏,
//第二个参数是AppDatabse的Class类型,第三个参数是数据库名
return Room.databaseBuilder(context.applicationContext,AppDatabase::class.java,"app_database")
.build().apply { instance=this }
}
}
}
测试
val userDao=AppDatabase.getDatabase(this).userDao()
val user1=User("Tom","Brady",40)
val user2=User("Tom","Hanks",63)
binding.addDataBtn.setOnClickListener {
thread{
user1.id=userDao.insertUser(user1)
user2.id=userDao.insertUser(user2)
}
}
binding.updateDataBtn.setOnClickListener {
thread{
user1.age=42
userDao.updateUser(user1)
}
binding.deleteDataBtn.setOnClickListener {
thread{
userDao.deleteUserByLastName("Hanks")
}
}
binding.queryDataBtn.setOnClickListener {
thread{
for(user in userDao.loadAllUsers()){
Log.d("MainActivity",user.toString())
}
}
由于数据库操作都是属于耗时操作,,Room中默认不允许在主线程中进行数据库操作,所以要开启子线程
但也可以在创建AppDatabase实例的时候就加入allowMainThreadQueries(),建议只在测试环境下使用
return Room.databaseBuilder(context.applicationContext,AppDatabase::class.java,"app_database")
.allowMainThreadQueries()
.build().apply { instance=this }
Room的数据库升级
新增表:
- 创建新的实体类
- 创建对应的Dao接口
- 修改AppDatabase
- 修改版本号,添加class文件
- 增加获得对应Dao的抽象方法
- 实现Migration的匿名类,在其中添加升级逻辑
[@Database](/user/Database)(version=2, entities = [User::class,Book::class]) //此处修改
abstract class AppDatabase: RoomDatabase(){
abstract fun userDao():UserDao
abstract fun bookDao():BookDao //此处修改
companion object{
////此处修改
val MIGRATION_1_2=object:Migration(1,2){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("create table Book(id integer primary key autoincrement not null,name text not null,pages integer not null)") //注意建表语句要和实体类声明一致
//这里Int对应Integer,String对应text
}
}
private var instance:AppDatabase?=null
@Synchronized
fun getDatabase(context: Context):AppDatabase{
instance?.let{
return it
}
return Room.databaseBuilder(context.applicationContext,AppDatabase::class.java,"app_database").addMigrations(MIGRATION_1_2).build().apply { instance=this }
}
}
}
新增列:
- 增加实体类字段
- 修改AppDatabase @Database(version=3, entities = [User::class,Book::class]) //版本改为3 abstract class AppDatabase: RoomDatabase(){ abstract fun userDao():UserDao abstract fun bookDao():BookDao
companion object{
val MIGRATION_2_3=object:Migration(2,3){
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("alter table Book add column author text not null default 'unknown'") //default ‘unknown’表示默认为‘unknown’
}
}
private var instance:AppDatabase?=null
@Synchronized
fun getDatabase(context: Context):AppDatabase{
instance?.let{
return it
}
return Room.databaseBuilder(context.applicationContext,AppDatabase::class.java,"app_database").addMigrations(MIGRATION_2_3).build().apply { instance=this }
}
}
更多关于HarmonyOS 鸿蒙Next数据库Room的实战教程也可以访问 https://www.itying.com/category-93-b0.html
HarmonyOS的Room数据库是鸿蒙Next提供的持久化库,基于SQLite封装,支持Type-Safe API和编译时SQL校验。它包含三个核心组件:
@Entity
- 定义数据表结构@Dao
- 提供增删改查接口@Database
- 配置数据库实例
Room通过注解处理器在编译时生成实现类,支持Observable查询和协程/异步操作。使用时需在build.gradle中配置hvigor依赖:
"dependencies": {
"room-runtime": "...",
"room-compiler": "..."
}
更多关于HarmonyOS 鸿蒙Next数据库Room的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html