기사 디렉토리
1. Room 프레임워크 사용의 핵심 포인트
1. build.gradle 빌드 스크립트 구성 지침
Room 프레임워크 의 경우 Java 언어 와 Kotlin 언어를 사용한 개발을 위해 build.gradle 빌드 스크립트 에서 서로 다른 구성을 만들어야 하며 주로 다음 두 가지 구성이 있습니다.
- 다른 플러그인이 적용됩니다.
- 종속 라이브러리를 가져오는 다양한 방법
애플리케이션 플러그인
적용된 플러그인 차이점:
- Java 언어를 사용하여 개발하는 경우 Android 플러그인 만 가져오면 됩니다 .
plugins {
id 'com.android.application'
}
- Kotlin 언어 개발을 사용하는 경우 Android 플러그인을 기반으로 kotlin 및 kotlin-kapt 플러그인을 추가로 가져와야 합니다 .
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
}
의존성 가져오기
종속 라이브러리 가져오기의 차이점: 가져오기가 잘못되면 표시됨
- Java 언어 개발을 사용하는 경우 annotationProcessor를 사용하여 주석 프로세서를 가져와서 컴파일 중에 코드를 생성 해야 합니다 .
// 导入 Room 依赖库
implementation 'androidx.room:room-runtime:2.2.5'
// 导入注解处理器 ( Java )
annotationProcessor 'androidx.room:room-compiler:2.2.5'
- Kotlin 언어 개발을 사용하는 경우 컴파일 중에 코드를 생성하려면 kapt를 사용하여 주석 프로세서를 가져와야 합니다 .
// 导入 Room 依赖库
implementation 'androidx.room:room-runtime:2.2.5'
// 导入注解处理器 ( Kotlin )
kapt 'androidx.room:room-compiler:2.2.5'
2. 엔터티 엔터티 클래스 정의
Room 프레임워크를 사용하는 애플리케이션에서 Entity 엔터티 클래스는 데이터베이스 테이블에 해당하며 , Entity 엔터티 클래스가 정의된 후에는 데이터베이스 정의되었음을 의미합니다.
@Entity 주석
Entity 엔터티 클래스 는 데이터베이스 테이블의 이름을 정의하는 데 사용되는 tableName 매개 변수에 전달될 수 있는 @Entity 주석으로 수정해야 합니다.
@Entity(tableName = "student")
class Student {
}
@PrimaryKey 주석
기본 키를 정의하고 @PrimaryKey 주석을 사용하여 기본 키를 수정하고 autoGenerate = true 매개변수를 설정하여 기본 키가 자동 증가되도록 합니다.
데이터베이스 테이블 열 정보는 @ColumnInfo 주석을 사용하여 정의되며 이 주석의 매개변수는 다음과 같습니다.
- name = "id"는 데이터 테이블의 열 이름을 정의합니다 .
- typeAffinity = ColumnInfo.INTEGER는 열 필드 유형이 int 정수임을 정의합니다 .
/**
* @PrimaryKey 设置主键 autoGenerate 为自增
* @ColumnInfo name 设置列名称 / typeAffinity 设置列类型
*/
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)
var id: Int = 0
@ColumnInfo 주석
일반 필드를 정의하려면 주석을 사용하여 필드를 수정 하기 만 하면 됩니다 .데이터베이스 테이블 이름을 설정하고 열 유형을 문자열 유형으로 설정하십시오.@ColumnInfo
name = "name"
typeAffinity = ColumnInfo.TEXT
/**
* 姓名字段
* 数据库表中的列名为 name
* 数据库表中的类型为 TEXT 文本类型
*/
@ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT)
lateinit var name: String
@주석 무시
수정된 필드
일부 필드가 데이터베이스 테이블 열로 설정될 필요가 없는 경우 비즈니스 로직에서만 사용되며 데이터베이스에 삽입할 필요가 없으며 필드를 수정하는 데만 사용하십시오 .@Ignore
/**
* 有些属性用于做业务逻辑
* 不需要插入到数据库中
* 使用 @Ignore 注解修饰该属性字段
*/
@Ignore
lateinit var studentInfo: String
수정자 기능
@Ignore 주석을 사용하여 생성자를 표시한 후 Room 프레임워크는 생성자를 사용하지 않습니다.
다음 세 가지 생성자 중
- Room 프레임워크는
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
}
3. Dao 데이터베이스 액세스 개체 인터페이스 정의
@Dao 주석
정의된 Dao 데이터베이스 액세스 개체 인터페이스는 @Dao 주석으로 수정된 인터페이스 인터페이스입니다 .
/**
* 数据库访问对象接口 / 使用 @Dao 注解修饰
* 提供数据库的增删改查方法
*/
@Dao
interface StudentDao {
@삽입 주석
데이터베이스에 데이터를 삽입하려면 @Insert 주석을 사용하여 해당 추상 메소드를 수정하십시오.
/**
* 向数据库表中插入元素
*/
@Insert
fun insert(student: Student)
@삭제 주석
데이터베이스에서 데이터를 삭제하려면 @Delete 주석을 사용하여 해당 추상 메소드를 수정하십시오.
/**
* 从数据库表中删除元素
*/
@Delete
fun delete(student: Student)
@업데이트 주석
데이터베이스의 데이터를 업데이트하려면 @Update 주석을 사용하여 해당 추상 메소드를 수정하십시오.
/**
* 修改数据库表元素
*/
@Update
fun update(student: Student)
@Query 주석
데이터베이스의 데이터를 쿼리하려면 @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>
4. RoomDatabase 데이터베이스 인스턴스 클래스 정의
정의된 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;
}
}
데이터베이스 코드를 초기화합니다.
- 먼저 Room.databaseBuilder 함수를 호출하고 RoomDatabase.Builder 개체를 만들고 Context 컨텍스트, StudentDatabase 클래스 개체 및 데이터베이스 이름과 같은 매개 변수를 전달합니다.
- 그런 다음 RoomDatabase.Builder 개체의 빌드 함수를 호출하여 데이터베이스를 만듭니다.
- 참고: Room은 원칙적으로 메인 스레드에서 데이터베이스 작업을 허용하지 않습니다. 메인 스레드에서 데이터베이스를 운영 하려면 RoomDatabase.Builder # allowMainThreadQueries 함수를 호출하여 메인 스레드 작업을 허용해야 합니다.
// 创建数据库
instance = Room.databaseBuilder(
context.applicationContext,
StudentDatabase::class.java,
"student_database.db")
.allowMainThreadQueries() // Room 原则上不允许在主线程操作数据库
// 如果要在主线程操作数据库需要调用该函数
.build()
5. Room 프레임워크를 호출하여 데이터베이스에 액세스
먼저 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)
}
2. 전체 코드 예제
1. build.gradle 빌드 스크립트
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'
}
2. 엔티티 엔티티 클래스 코드
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)"
}
}
3. Dao 데이터베이스 액세스 개체 인터페이스 코드
@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>
}
4. RoomDatabase 데이터베이스 인스턴스 클래스 코드
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;
}
}
}
5. 활동 구성 요소에서 Room 프레임워크를 호출하여 데이터베이스에 액세스합니다.
먼저, 데이터베이스 인스턴스 클래스 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)
}
}
}