[Jetpack] Room フレームワークを使用して、Android プラットフォーム上の SQLite データベースにアクセスします (依存関係をインポート | Entity エンティティ クラスを定義 | Dao データベース アクセス オブジェクト インターフェイスを定義 | データベース インスタンス クラスを定義)





1. Room フレームワークを使用する際のポイント




1. build.gradle ビルド スクリプトの構成手順


Room フレームワークの場合Java言語とKotlin言語を使用した開発用にbuild.gradle ビルド スクリプトでさまざまな構成を行う必要があります。主に次の 2 つの構成があります。

  • さまざまなプラグインが適用されます。
  • 依存ライブラリをインポートするさまざまな方法。

アプリケーションプラグイン

適用されたプラグインの違い:

  • 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.Entityエンティティクラスを定義する


Roomフレームワークを使用したアプリケーションでは、 Entity エンティティ クラスがデータベーステーブルに対応します。Entity エンティティ クラスが定義されると、データベース定義されたことになります。


@Entity アノテーション

Entity エンティティ クラスは、 @Entity アノテーションを使用して変更する必要があります。このアノテーションは、データベース テーブルの名前を定義するために使用されるtableName パラメーターに渡すことができます。

@Entity(tableName = "student")
class Student {
    
    
}

@PrimaryKey アノテーション

主キーを定義し、@PrimaryKey アノテーションを使用して主キーを変更し、autoGenerate = true パラメーターを設定して主キーを自動インクリメントします。

データベース テーブルの列情報は @ColumnInfo アノテーションを使用して定義され、このアノテーションのパラメータは次のとおりです。

  • name = "id" はデータテーブルの列名を定義します。
  • typeAffinity = ColumnInfo.INTEGER は、フィールドの型が int integer であることを定義します。
    /**
     * @PrimaryKey 设置主键 autoGenerate 为自增
     * @ColumnInfo name 设置列名称 / typeAffinity 设置列类型
     */
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)
    var id: Int = 0

@ColumnInfo アノテーション

通常のフィールドを定義するには、アノテーションを使用してフィールドを変更するだけでよく、データベースのテーブル名を設定し、列の型を文字列型に設定します。@ColumnInfoname = "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 フレームワークはコンストラクターを使用しなくなります。

次の 3 つのコンストラクターのうち、

  • 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 アノテーションを使用して、対応する抽象メソッドを変更します。

    /**
     * 修改数据库表元素
     */
    @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 オブジェクトの build 関数を呼び出してデータベースを作成します。
  • 注: 原則として、Room ではメイン スレッドでのデータベース操作は許可されていません。メイン スレッドでデータベースを操作したい場合は、 RoomDatabase.Builder # allowedMainThreadQueries 関数を呼び出してメイン スレッドの操作を許可する必要があります。
                    // 创建数据库
                    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 言語を使用して開発する場合は、これら 2 つのプラグインをインポートする必要はありません。

    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)
        }


    }
}

おすすめ

転載: blog.csdn.net/han1202012/article/details/130568567