Android Room Tutorial: アプリ データでの作業方法を簡素化する

情報はおそらく、ユーザーがアプリを信頼するための最も重要なリソースです。 アプリ開発者にとっては、その情報はユーザーが誰であるかを教えてくれるので、良いユーザー エクスペリエンス (UX) を提供する力を与えてくれます。 また、この情報にビジネスルールを適用することで、アプリが持つべき振る舞いを定義することができます。 この情報は機密性が高く、ユーザーの個人情報を暴露する可能性があるため、その完全性、プライバシー、適切な保管を保証するために、正しく取り扱うことが非常に重要です。 この Android Room チュートリアル内では、Room を使用することで、データの整合性とセキュリティを確保しながら、このデータをより簡単に操作する方法を紹介します。 Room は Android Architecture Components の一部です。

Do You Need Room?

Android で情報を持続的に格納することについて話すとき、最も重要で「簡単」な選択肢は、プレーンな SQLite を使用することです。 しかし、SQLite を使用して優れたデータベース実装を行うには、真の価値を提供しない多くのコードを生成することを意味します。 オブジェクト リレーショナル マッピング (ORM) を使用することもできますが、データベースを手動で定義および作成し、SQLiteOpenHelper をサブクラス化し、コントラクト クラスを作成する必要があります。

そこで質問ですが、このプロセスをすべて簡略化する方法はないのでしょうか。 答えは、「はい、Room があなたの解決策です」です。

A Closer Look at Room and How It Works

Room は、Android Architectural Components で最も重要なツールの 1 つです。 Google I/O 2016 でリリースされたこのツールは、Android アプリで情報を保存および操作するための強力なツールです。 データを扱うための非常に簡単な方法を提供し、常にそのセキュリティと整合性を保証します。

Room は ORM ではなく、SQLite データベースをより簡単に作成および操作できるようにするライブラリ全体です。 アノテーションを使用することで、データベース、テーブル、および操作を定義することができます。 Room は、これらのアノテーションを SQLite 命令/クエリに自動的に変換し、データベース エンジンに対応する操作を実行します。 Room データベース内のテーブルを表します。 Entityでアノテーションする必要があります。

– DAO: データベースにアクセスするためのメソッドを含むインターフェイスです。 Dao.

– Databaseでアノテーションされる。 データベースを表現する。 SQLiteデータベースへの接続を保持するオブジェクトであり、すべての操作はこのオブジェクトを介して実行される。 アノテーションは @Database である。

Roomアーキテクチャはこのようになっています。

Android Room architecture

Too Much Talk-Let’s Look at an Example

この Android Room チュートリアルに飛び込もうではありませんか。 ジムの日課を保存するアプリを作成する必要があると想像してください。 以下に示すように、データベース内に 4 つのエンティティを用意するつもりです。 すべてのサンプル コードは Kotlin を使用して書かれています (Kotlin を知らない、またはもっと学びたい場合は、それに関する私の記事を読んでください)。

最初に行う必要があるのは、gradle ファイルを更新することです。 以下のような感じになっているはずです。

apply plugin: 'com.android.application'apply plugin: 'kotlin-android'apply plugin: 'kotlin-android-extensions'apply plugin: 'kotlin-kapt'android { //.. Omitted since it is not relevant for the example}dependencies { //... some dependencies were omitted due to they are not relevant for the example def room_version = "2.2.0-rc01" implementation "androidx.room:room-runtime:$room_version" kapt "androidx.room:room-compiler:$room_version" compile 'com.google.code.gson:gson:2.2.4' implementation 'io.reactivex.rxjava2:rxandroid:2.0.2' implementation 'io.reactivex.rxjava2:rxjava:2.1.17'}

Room の 3 つの主要なコンポーネントをそれぞれ見て、分析してみましょう。

Entities

この例では、4 つのエンティティを使用するつもりです。 Gender、Exercise、Routine、Traineeの4つのエンティティを使用します。kt

訓練生の性別を表す

@Entitydata class Gender( @PrimaryKey(autoGenerate = true) val id: Int? = null, val name: String)

注意事項:

– データベースのエンティティを表すすべてのクラスは @Entity

– @PrimaryKey(autoGenerate = true) という注釈で、ID がエンティティの主キーでデータベース エンジンによって自動生成されるべきことを示すことになります。

Exercise.kt

ルーチンの一部であるエクササイズを表します。

@Entitydata class Exercise( @PrimaryKey(autoGenerate = true) val exerciseId: Int, val name: String, val repetitions:Int, @ColumnInfo(name = "machine_name") val machineName: String, val liftedWeight: Int)

注意事項:

– デフォルトでは、ルームではフィールド名がデータベースの列名として使用されます。 列を別の名前にしたい場合は、フィールドに @ColumnInfo アノテーションを追加します。

Routine.kt

基本的に、一緒に運動ルーチンを作成する演習のコンテナー。

@Entity(tableName = "traineeRoutine")data class Routine( @PrimaryKey(autoGenerate = true) val routineId: Int, @ColumnInfo(name = "due_day") val dueDay: Date, @TypeConverters(ListConverter::class) val exercises: List)

注意事項:

– クラスに @Entity が付けられたとき、テーブル名はクラス名と同じ名前になる。 別の名前を使用したい場合は、@Entity アノテーションと一緒に tableName プロパティを追加する必要があります。

– @TypeConverters アノテーションは、タイプがカスタム クラス、リスト、日付タイプ、または Room と SQL がシリアライズする方法を知らないその他のタイプであるプロパティを宣言するときに使用する必要があります。 この場合、クラス・フィールド・レベルでアノテーションを使用し、そのフィールドだけがそれを使用できるようにします。

Trainee.kt

これは、ルーチンの所有者を表します。

@Entity(indices = , foreignKeys = , childColumns = )])data class Trainee( @PrimaryKey(autoGenerate = true) val id: Int, val name: String, val age: Int, val gender: Int?, @Embedded val routine: Routine)

DAOs

データ アクセス オブジェクト (DAOs) は、Room 実装時にデータにアクセスするために使用されます。 各 DAO は、データを操作する (挿入、更新、削除、または取得) ための一連のメソッドを含まなければなりません。

DAO は、インターフェイスまたは抽象クラスとして実装することができます。 この例では、インターフェイスを使用しています。

GenderDao.kt@Daointerface GenderDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertGender(gender: Gender) @Update fun updateGender(gender: Gender) @Delete fun deleteGender(gender: Gender) @Query("SELECT * FROM Gender WHERE name == :name") fun getGenderByName(name: String): List @Query("SELECT * FROM Gender") fun getGenders(): List}

– すべての DAO は @Dao でアノテーションされなければなりません。

– @Insert、@Update、または @Delete でアノテーションされた関数はパラメーターとして目的のクラスのインスタンスを受け取る必要があり、それぞれ挿入、更新、または削除したいオブジェクトを表しています。

– 挿入または更新操作の場合、onConflict プロパティを使用して、操作の競合が発生したときにどうするかを示すことができます。 使用可能な戦略は次のとおりです。 REPLACE、ABORT、FAIL、IGNORE、および ROLLBACK。

– 1 つ以上のエンティティから特定の情報を取得したい場合、@Query で関数をアノテーションし、SQL スクリプトをパラメーターとして提供することが可能です。 実際の SQLite データベースへの接続を保持します。

AppDatabase.kt@Database(entities = , version = 1)@TypeConverters(DateTypeConverter::class)abstract class AppDatabase : RoomDatabase() { abstract fun exerciseDao(): ExerciseDao abstract fun genderDao(): GenderDao abstract fun routineDao(): RoutineDao abstract fun traineeDao(): TraineeDao companion object { var INSTANCE: AppDatabase? = null fun getAppDataBase(context: Context): AppDatabase? { if (INSTANCE == null){ synchronized(AppDatabase::class){ INSTANCE = Room.databaseBuilder(context.applicationContext, AppDatabase::class.java, "myDB").build() } } return INSTANCE } fun destroyDataBase(){ INSTANCE = null } }}

ここで注意すること:

– これは RoomDatabase を継承する必要がある抽象クラスです。

– これは @Database で注釈する必要があり、データベースを構成するすべてのクラス (これらのすべてのクラスは @Entity で注釈しなければならない) でエンティティ リストを受信します。 また、データベースのバージョンも提供する必要があります。

– @Database アノテーションに含まれる各エンティティに対して、抽象関数を宣言する必要があります。 この関数は、対応する DAO (@Dao でアノテーションされたクラス) を返さなければなりません。

– 最後に、データベースのシングルトン インスタンスを取得するメソッド getAppDataBase に静的にアクセスするためのコンパニオン オブジェクトを宣言します。

DateTypeConverter.ktclass DateTypeConverter { @TypeConverter fun fromTimestamp(value: Long?): Date? { return if (value == null) null else Date(value) } @TypeConverter fun dateToTimestamp(date: Date?): Long? { return date?.time }}

Using the Room Database

では、作成したばかりの Room データベースの使用方法について、非常に簡単な例を見てみましょう。

MainActivity.ktclass MainActivity : AppCompatActivity() { private var db: AppDatabase? = null private var genderDao: GenderDao? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Observable.fromCallable({ db = AppDatabase.getAppDataBase(context = this) genderDao = db?.genderDao() var gender1 = Gender(name = "Male") var gender2 = Gender(name = "Female") with(genderDao){ this?.insertGender(gender1) this?.insertGender(gender2) } db?.genderDao()?.getGenders() }).doOnNext({ list -> var finalString = "" list?.map { finalString+= it.name+" - " } tv_message.text = finalString }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe() }}

何をしているかというと、

-データベースとGenderDaoのインスタンスを取得します。

-2つのGenderインスタンスを作成する。

– 作成した 2 つのインスタンスをデータベースに挿入します。

– データベースに問い合わせて、データベースに格納されているすべての性別を取得します。

– データベースから取得したすべての性別の名前をマージし、その値を TextView のテキストに設定します。

Room to Do More with Less

Room は Android Architectural Components における重要な要素の 1 つです。 これは、データのセキュリティと整合性を常に確保し、永続的な情報を扱うための非常に堅牢なフレームワークを提供します。 また、開発者に使いやすさを提供し、読みやすく、説明しやすいコードを書くことができます。 より少ないコードでより多くのことを行い、ユーザー データのセキュリティを確保したいのであれば、アプリケーションの永続化レイヤーとして Room を使用すべきです。 Android で Room を使用してデータベースを作成および使用するために知っておくべきことは、ほぼすべてです。 このプロジェクトの全コードは、ここから入手できます。 この Android Room チュートリアルをお読みいただき、ありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。