赞
踩
对于 Room 框架 来说 , 使用 Java 语言 开发和使用 Kotlin 语言 开发 , 需要在 build.gradle 构建脚本 中进行不同的配置 , 主要有以下两个配置不同 :
应用的插件区别 :
plugins {
id 'com.android.application'
}
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}
导入依赖库区别 : 如果导入错误 , 就会出现
// 导入 Room 依赖库
implementation 'androidx.room:room-runtime:2.2.5'
// 导入注解处理器 ( Java )
annotationProcessor 'androidx.room:room-compiler:2.2.5'
// 导入 Room 依赖库
implementation 'androidx.room:room-runtime:2.2.5'
// 导入注解处理器 ( Kotlin )
kapt 'androidx.room:room-compiler:2.2.5'
使用 Room 框架 的应用中 , Entity 实体类 对应着 数据库表 , 将 Entity 实体类 定义完成后 , 就意味着 数据库表的结构 已经定义完成 ;
Entity 实体类 需要使用 @Entity 注解进行修饰 , 该注解可以 传入 tableName 参数 , 该 tableName 参数的作用是定义数据库表的名称 ;
@Entity(tableName = "student")
class Student {
}
定义主键 , 使用 @PrimaryKey 注解修饰主键 , 设置 autoGenerate = true 参数 可以令 主键自增 ;
数据库表 列信息 使用 @ColumnInfo 注解定义 , 该注解中的参数 :
/**
* @PrimaryKey 设置主键 autoGenerate 为自增
* @ColumnInfo name 设置列名称 / typeAffinity 设置列类型
*/
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)
var id: Int = 0
定义普通字段 , 只需要使用 @ColumnInfo
注解修饰字段即可 , 通过 name = "name"
设置数据库表名称 , typeAffinity = ColumnInfo.TEXT
设置该列的类型为 String 类型 ;
/**
* 姓名字段
* 数据库表中的列名为 name
* 数据库表中的类型为 TEXT 文本类型
*/
@ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT)
lateinit var name: String
如果 有些字段 不需要设置为数据库表列 , 仅用于业务逻辑中使用 , 不需要插入数据库中 , 使用 @Ignore
修饰该字段即可 ;
/**
* 有些属性用于做业务逻辑
* 不需要插入到数据库中
* 使用 @Ignore 注解修饰该属性字段
*/
@Ignore
lateinit var studentInfo: String
使用 @Ignore 注解标注构造函数后 , Room 框架就不会使用该构造方法了 ;
下面的 3 个构造函数中 ,
constructor(id: Int, name: String, age: Int)
构造函数 ;constructor(name: String, age: Int)
和 constructor(id: Int)
构造函数 ;/** * 默认的构造方法给 Room 框架使用 */ constructor(id: Int, name: String, age: Int) { this.id = id this.name = name this.age = age } /** * 使用 @Ignore 注解标注构造函数后 * Room 就不会使用该构造方法了 * 这个构造方法是给开发者使用的 */ @Ignore constructor(name: String, age: Int) { this.name = name this.age = age } /** * 使用 @Ignore 标签标注后 * Room 就不会使用该构造方法了 * 这个构造方法是给开发者使用的 */ @Ignore constructor(id: Int) { this.id = id }
定义的 Dao 数据库访问对象接口 是一个 interface 接口 , 使用 @Dao 注解修饰该接口 ;
/**
* 数据库访问对象接口 / 使用 @Dao 注解修饰
* 提供数据库的增删改查方法
*/
@Dao
interface StudentDao {
向数据库中插入数据 , 使用 @Insert 注解修饰对应的抽象方法 ;
/**
* 向数据库表中插入元素
*/
@Insert
fun insert(student: Student)
从数据库中删除数据 , 使用 @Delete 注解修饰对应的抽象方法 ;
/**
* 从数据库表中删除元素
*/
@Delete
fun delete(student: Student)
更新数据库中的数据 , 使用 @Update 注解修饰对应的抽象方法 ;
/**
* 修改数据库表元素
*/
@Update
fun update(student: Student)
查询数据库中的数据 , 使用 @Query 注解修饰对应的抽象方法 ;
注解中可以设置字符串参数 , 该字符串参数就是查询的 SQL 语句 , 使用 冒号 :
可访问传入的参数 ;
/**
* 查询数据库表
*/
@Query("select * from student")
fun query(): List<Student>
/**
* 根据传入的 id 查询数据库表
* 在注解中使用 :id 调用参数中的 id: Int
*/
@Query("select * from student where id = :id")
fun query(id: Int): List<Student>
定义的 RoomDatabase 数据库实例类 是一个 抽象类 , 需要继承 RoomDatabase 抽象类 , 同时要使用 @Database
注解修饰 ,
@Database(entities = [Student::class], version = 1, exportSchema = false)
abstract class StudentDatabase: RoomDatabase() {
在该抽象类中定义抽象方法 , 获取 数据库访问 对象 ,
/**
* 获取 数据库访问 对象
* 这是必须要实现的函数
*/
abstract fun studentDao(): StudentDao
将该类设置成单例类 , 在单例类对象初始化时 , 创建数据库 ;
companion object { lateinit var instance: StudentDatabase fun inst(context: Context): StudentDatabase { if (!::instance.isInitialized) { synchronized(StudentDatabase::class) { // 创建数据库 instance = Room.databaseBuilder( context.applicationContext, StudentDatabase::class.java, "student_database.db") .allowMainThreadQueries() // Room 原则上不允许在主线程操作数据库 // 如果要在主线程操作数据库需要调用该函数 .build() } } return instance; } }
初始化数据库代码 :
// 创建数据库
instance = Room.databaseBuilder(
context.applicationContext,
StudentDatabase::class.java,
"student_database.db")
.allowMainThreadQueries() // Room 原则上不允许在主线程操作数据库
// 如果要在主线程操作数据库需要调用该函数
.build()
首先 , 获取 RoomDatabase 数据库实例类 , 调用其单例的获取函数即可 , 调用该函数 , 即可创建对应的数据库 ;
// 获取 StudentDatabase
var studentDatabase: StudentDatabase = StudentDatabase.inst(this)
然后 , 获取 数据库访问对象 Dao , 通过 RoomDatabase 数据库实例类 的抽象方法获取 ;
// 获取数据库访问对象
var studentDao: StudentDao = studentDatabase.studentDao()
最后 , 使用 Dao 数据库访问对象 , 进行数据库访问操作 , 推荐在线程中访问数据库 ;
thread(start = true) { // 插入数据 var s1 = Student("Tom", 18) var s2 = Student("Jerry", 16) studentDao.insert(s1) studentDao.insert(s2) // 查询数据 var students = studentDao.query() Log.i("MainActivity", "数据库查询结果 ( 插入后首次查询 ) : " + students) // 更新数据 , 将学生年龄都设置为 20 for (i in 0.. students.size - 1) { students[i].age = 20 studentDao.update(students[i]) } students = studentDao.query() Log.i("MainActivity", "数据库查询结果 ( 修改后查询结果 ) : " + students) // 删除数据 var s_delete = Student(1) // 删除的元素只需要传入 id 即可 studentDao.delete(s_delete) students = studentDao.query() Log.i("MainActivity", "数据库查询结果 ( 删除后查询结果 ) : " + students) }
在 build.gradle 构建脚本中 , 主要是导入 Kotlin 插件 , 和 Kotlin 注解插件 ;
如果使用 Java 语言开发 , 则不需要导入这两个插件 ;
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
导入 Room 依赖库 和 编译时生成代码的 注解处理器 ;
// 导入 Room 依赖库
implementation 'androidx.room:room-runtime:2.2.5'
// 导入注解处理器 ( Kotlin )
kapt 'androidx.room:room-compiler:2.2.5'
// 导入注解处理器 ( Java )
//annotationProcessor 'androidx.room:room-compiler:2.2.5'
完整代码如下 :
plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' id 'kotlin-kapt' } android { namespace 'kim.hsl.roomdemo' compileSdk 32 defaultConfig { applicationId "kim.hsl.roomdemo" minSdk 21 targetSdk 32 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } viewBinding { // 启用 ViewBinding enabled = true } } dependencies { implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'com.google.android.material:material:1.5.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.3' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' // 导入 Room 依赖库 implementation 'androidx.room:room-runtime:2.2.5' // 导入注解处理器 ( Kotlin ) kapt 'androidx.room:room-compiler:2.2.5' // 导入注解处理器 ( Java ) //annotationProcessor 'androidx.room:room-compiler:2.2.5' }
package kim.hsl.roomdemo import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.Ignore import androidx.room.PrimaryKey /** * 定义数据库表 Entity 实体 / 同时定义数据库表 和 对鹰的实体类 * 设置该数据类对应数据库中的一张数据表, 表名为 student * 该数据库表中的数据对应一个 Student 类实例对象 */ @Entity(tableName = "student") class Student { /** * @PrimaryKey 设置主键 autoGenerate 为自增 * @ColumnInfo name 设置列名称 / typeAffinity 设置列类型 */ @PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER) var id: Int = 0 /** * 姓名字段 * 数据库表中的列名为 name * 数据库表中的类型为 TEXT 文本类型 */ @ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT) lateinit var name: String /** * 年龄字段 * 数据库表中的列名为 age * 数据库表中的类型为 INTEGER 文本类型 */ @ColumnInfo(name = "age", typeAffinity = ColumnInfo.INTEGER) var age: Int = 0 /** * 有些属性用于做业务逻辑 * 不需要插入到数据库中 * 使用 @Ignore 注解修饰该属性字段 */ @Ignore lateinit var studentInfo: String /** * 默认的构造方法给 Room 框架使用 */ constructor(id: Int, name: String, age: Int) { this.id = id this.name = name this.age = age } /** * 使用 @Ignore 注解标注构造函数后 * Room 就不会使用该构造方法了 * 这个构造方法是给开发者使用的 */ @Ignore constructor(name: String, age: Int) { this.name = name this.age = age } /** * 使用 @Ignore 标签标注后 * Room 就不会使用该构造方法了 * 这个构造方法是给开发者使用的 */ @Ignore constructor(id: Int) { this.id = id } override fun toString(): String { return "Student(id=$id, name='$name', age=$age)" } }
使用 @Dao 注解修饰接口类 ;
分别使用 @Insert , @Delete , @Update , @Query 注解 修饰对应的 增加 , 删除 , 修改 , 查询 等 函数 ;
完整代码 :
package kim.hsl.roomdemo import androidx.room.Dao import androidx.room.Delete import androidx.room.Insert import androidx.room.Query import androidx.room.Update /** * 数据库访问对象接口 / 使用 @Dao 注解修饰 * 提供数据库的增删改查方法 */ @Dao interface StudentDao { /** * 向数据库表中插入元素 */ @Insert fun insert(student: Student) /** * 从数据库表中删除元素 */ @Delete fun delete(student: Student) /** * 修改数据库表元素 */ @Update fun update(student: Student) /** * 查询数据库表 */ @Query("select * from student") fun query(): List<Student> /** * 根据传入的 id 查询数据库表 * 在注解中使用 :id 调用参数中的 id: Int */ @Query("select * from student where id = :id") fun query(id: Int): List<Student> }
RoomDatabase 数据库实例类 需要继承 RoomDatabase 抽象类 , 使用 @Database 注解修饰 该抽象类 ;
其中需要 定义 获取 数据库访问 对象 的抽象函数 ;
将该类定义成 单例类 , 在单例对象初始化时 , 创建数据库 ;
完整代码 :
package kim.hsl.roomdemo import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase @Database(entities = [Student::class], version = 1, exportSchema = false) abstract class StudentDatabase: RoomDatabase() { /** * 获取 数据库访问 对象 * 这是必须要实现的函数 */ abstract fun studentDao(): StudentDao companion object { lateinit var instance: StudentDatabase fun inst(context: Context): StudentDatabase { if (!::instance.isInitialized) { synchronized(StudentDatabase::class) { // 创建数据库 instance = Room.databaseBuilder( context.applicationContext, StudentDatabase::class.java, "student_database.db") .allowMainThreadQueries() // Room 原则上不允许在主线程操作数据库 // 如果要在主线程操作数据库需要调用该函数 .build() } } return instance; } } }
首先 , 获取 数据库实例类 StudentDatabase ;
然后 , 获取 数据库访问对象接口 StudentDao ;
最后 , 调用 数据库访问对象接口 StudentDao 的一系列方法访问数据库 ;
完整代码 :
package kim.hsl.roomdemo import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import kim.hsl.roomdemo.databinding.ActivityMainBinding import kotlin.concurrent.thread class MainActivity : AppCompatActivity() { lateinit var binding: ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(getLayoutInflater()) setContentView(binding.root) // 获取 StudentDatabase var studentDatabase: StudentDatabase = StudentDatabase.inst(this) // 获取数据库访问对象 var studentDao: StudentDao = studentDatabase.studentDao() thread(start = true) { // 插入数据 var s1 = Student("Tom", 18) var s2 = Student("Jerry", 16) studentDao.insert(s1) studentDao.insert(s2) // 查询数据 var students = studentDao.query() Log.i("MainActivity", "数据库查询结果 ( 插入后首次查询 ) : " + students) // 更新数据 , 将学生年龄都设置为 20 for (i in 0.. students.size - 1) { students[i].age = 20 studentDao.update(students[i]) } students = studentDao.query() Log.i("MainActivity", "数据库查询结果 ( 修改后查询结果 ) : " + students) // 删除数据 var s_delete = Student(1) // 删除的元素只需要传入 id 即可 studentDao.delete(s_delete) students = studentDao.query() Log.i("MainActivity", "数据库查询结果 ( 删除后查询结果 ) : " + students) } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。