文章目录
- Room概述
- Room的使用
- 一、在gradle.build中添加依赖库
- kotlin
- Java
- 创建实体类
- 创建抽象Dao层接口
- 创建DataBase层
- 使用创建的
- 查看数据库
- 总结:
这篇文章会告诉你如何在Android中通过kotlin或者Java来实现数据持久化
Room概述
处理大量结构化数据的应用可极大地受益于在本地保留这些数据。最常见的使用场景是缓存相关的数据,这样一来,当设备无法访问网络时,用户仍然可以在离线状态下浏览该内容。
Room 持久性库在 SQLite 上提供了一个抽象层,以便在充分利用 SQLite 的强大功能的同时,能够流畅地访问数据库。具体来说,Room 具有以下优势:
- 提供针对 SQL 查询的编译时验证。
- 提供方便注解,可最大限度减少重复和容易出错的样板代码。
- 简化了数据库迁移路径。
Room 包含三个主要组件:
- 数据库类,用于保存数据库并作为应用持久性数据底层连接的主要访问点。
- 数据实体,用于表示应用的数据库中的表。
- 数据访问对象(DAO),为您的应用提供在数据库中查询、更新、插入和删除数据的方法。
数据库类为应用提供与该数据库关联的 DAO 的实例。反过来,应用可以使用 DAO 从数据库中检索数据,作为关联的数据实体对象的实例。此外,应用还可以使用定义的数据实体更新相应表中的行,或者创建新行供插入。图 1 说明了 Room 的不同组件之间的关系。
Room的使用
一、在gradle.build中添加依赖库
kotlin
需要先在build.gradle.kts中添加kapt插件
- build.gradle(app)
alias(libs.plugins.jetbrainsKotlinKapt)
- 项目的build.gradle.kts中也需要添加
plugins {alias(libs.plugins.jetbrainsKotlinKapt) apply false
}
然后再app的gradle中添加如下依赖
//room依赖val room_version = "2.6.1"implementation("androidx.room:room-runtime:$room_version")// To use Kotlin annotation processing tool (kapt)kapt("androidx.room:room-compiler:$room_version")
Java
添加插件:
plugins {id 'org.jetbrains.kotlin.kapt'
}
添加依赖:
def room_version = "2.6.1"implementation "androidx.room:room-runtime:$room_version"annotationProcessor "androidx.room:room-compiler:$room_version"// To use Kotlin annotation processing tool (kapt)kapt "androidx.room:room-compiler:$room_version"
创建实体类
1.创建User实体类
@Entity(tableName = "user2")
data class User(@ColumnInfo(name = "username")var userName: String? = null,@ColumnInfo(name = "password")var userPassword: String? = null) {@PrimaryKey(autoGenerate = true)@ColumnInfo(name = "id")var id: Int = 0
}
2.添加注解:
- 默认情况下,Room 将类名称用作数据库表名称。如果您希望表具有不同的名称,请设置 @Entity 注解的 tableName 属性。
- Room 默认使用字段名称作为数据库中的列名称。如果您希望列具有不同的名称,请将 @ColumnInfo 注解添加到该字段并设置 name
属性。- 每个 Room 实体都必须定义一个主键,用于唯一标识相应数据库表中的每一行。执行此操作的最直接方式是使用 @PrimaryKey
为单个列添加注解(注意:如果您需要 Room 为实体实例分配自动 ID,请将 @PrimaryKey 的 autoGenerate
属性设为 true。)- 默认情况下,Room 会为实体中定义的每个字段创建一个列。 如果某个实体中有您不想保留的字段,则可以使用 @Ignore
为这些字段添加注解
创建抽象Dao层接口
interface UserDao {@Query("SELECT * FROM user2")fun getAll(): List<User>@Deletefun delete(user: User)@Updatefun updateUsers(vararg users: User)//这个注解表示如果数据已在数据库中存在增进行替换@Insert(onConflict = OnConflictStrategy.REPLACE)fun insert(users: List<User>)@Insert(onConflict = OnConflictStrategy.REPLACE)fun insert(user: User)//返回User的id值,判断是否添加成功@Insert(onConflict = OnConflictStrategy.REPLACE)fun insertReturnId(user: User) : Long@Query("SELECT * FROM user2 WHERE username = :userName AND password = :userPassword")fun queryUser(userName: String, userPassword: String): User?
}
创建DataBase层
这里通过单例双重验证进行创建
//这里exportSchema
@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class UserDataBase : RoomDatabase() {companion object {private var instance: UserDataBase? = nullfun getInstance(context: Context): UserDataBase? {if (instance == null) {synchronized(Companion::class.java) {if(null == instance) {instance = Room.databaseBuilder(context, UserDataBase::class.java, "user.db").addMigrations().allowMainThreadQueries()//表示允许在主线程中进行数据库的操作.build()}}}return instance}}abstract fun getUserDao(): UserDao
}
注:可能会报 Schema export directory is not provided to the annotation processor异常
有两种方式解决:
1.在Database注解中添加 exportSchema = false
2.在app的build.gradle中的defaultConfig下添加以下配置
javaCompileOptions {annotationProcessorOptions {arrayOf("room.schemaLocation" to "$projectDir/schemas")}
}
- 该类必须带有 @Database 注解,该注解包含列出所有与数据库关联的数据实体的 entities 数组。
- 该类必须是一个抽象类,用于扩展 RoomDatabase。
- 对于与数据库关联的每个 DAO 类,数据库类必须定义一个具有零参数的抽象方法,并返回 DAO 类的实例。
使用创建的
val userDataBase = UserDataBase.getInstance(this)//在子线程中去运行userDataBase?.runInTransaction {val userDao: UserDao = db.userDao()val users = userDao.getAll()
}
查看数据库
通过Android Studio自带的工具就能够查看
或者在Device Explorer中的data/data/包名下的databases目录中,将db文件拉出来用其他数据库工具查看
总结:
Room基本用法已经讲完了,更多详细内容请看 官方文档:https://developer.android.google.cn/training/data-storage/room?hl=zh-cn#groovy
像数据库持久化的其他开源框架还有LitPal等
LitePal介绍
参考文章:
Android-第十三节04Room框架详解
Room 的引入及使用