
Android Studio(Kotlin)でのアプリ作成でデータベース(SQLite)を Room を使って利用してみます。あらかじめ用意されたデータベースファイルを読み込んでみます
説明用のコードは Android Developper にある「SQLの基本」のスターターコードを基本にしました
- SQLite の操作を Room を介して行います
- データベースの処理部分にコルーチン(coroutine)を使います
データベースの操作は非同期で
- アプリでデータベースを操作すると、結果が返ってくるまで時間がかかることがあります。
- 時間のかかる処理でアプリがフリーズしたように見えないよう、非同期で処理を行うようにします
- 今回は非同期の処理にコルーチン(coroutine)を使ってみます
コルーチン(coroutine)とは
- 非同期の処理を簡単に記述できる方法です
- GlobalScope.launch{ ・・・ } のようにすると、launch 内の処理は非同期で実行されます
- コルーチン内で利用する関数に suspend をつけるとメインの処理をブロックせずに、中断・再開によって効率よく処理されるようです
データベースを使う手順
- アプリの build.gradle に Room , Coroutine を使うための設定(依存関係)を追加します
- 最初に読み込む SQLite のデータベースファイルを用意
- エンティティ(テーブル)のクラスを作成
- データベース操作用のクラス(DAOクラス)を作成
- データベース生成用のクラス を作成
- データベースを利用するためのコードの記述
設定やコードは、お決まりと思って真似してみますね
build.gradle の設定
Android Studio でアプリのプロジェクトを開いたら、build.gradle(アプリ)に次の行を追加します
dependencies {
def room_version = '2.3.0'
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1'
・・・
}
最初に読み込む SQLite のデータベースファイルを用意
- 今回は、スターターコードにあらかじめ用意されている sql_basics.db を使います
- SQLite のデータベースは、あらかじめ Windows 版の SQLite などで作成しておくことができます
- 用意したデータベースファイルは、Android Studio の assets/database に置きます
エンティティ(テーブル)のクラスの作成
- ここでは SQLite の park テーブルを、CaliforniaPark クラスとして作成しています
- SQLite でのテーブル名と、Room で扱うクラス名が同じときは @Entity の tableName を省略できます
- SQLite でのカラム名と、Room で扱うプロパティ名が同じときは @ColumnInfo の name は省略できます
- つまり、クラス名やプロパティ名は、データベースのテーブル名とカラム名に一致させておくと記述は楽になります
- 尚、大文字と小文字が違っても同じとみなします
@Entity(tableName = "park") data class CaliforniaPark( @PrimaryKey(autoGenerate = true) val id: Int, @ColumnInfo(name = "name") val name: String, @ColumnInfo(name = "city") val city: String, @ColumnInfo(name = "area_acres") val acres: Int, @ColumnInfo(name = "park_visitors") val visitors: Int?, @ColumnInfo(name = "established") val established: Long, @ColumnInfo(name = "type") val type: String )
データベース操作用のクラス(DAOクラス)の作成
- ここでは CaliforniaPark クラス(エンティティ)を操作するための CaliforniaParkDao インタフェースを作成しています
- データベースを操作するクエリーを、Kotlin の関数に結び付けます
- コルーチン内で使う関数なので、suspend を付けておきます
@Dao
interface CaliforniaParkDao {
@Insert
suspend fun insertAll(parks: List<CaliforniaPark>)
@Query("SELECT * FROM park")
suspend fun getAll(): List<CaliforniaPark>
}
データベース生成用のクラス の作成
- データベースのインスタンスを生成する AppDatabase クラスを作成します
- データベースのインスタンスを返す getDatabase() メソッドを含みます
- CaliforniaParkDao を返す californiaParkDao() メソッドを含みます
- アプリで使うデータベースファイルの名前は app_database としています
- 最初にデータを設定するのに使う SQLite データベースは sql_basics.db です。createFromAsset(“database/sql_basics.db”) として設定します
- このコードはテンプレ的に使います
@Database(entities = arrayOf(CaliforniaPark::class), version = 1)
abstract class AppDatabase: RoomDatabase() {
abstract fun californiaParkDao(): CaliforniaParkDao
companion object {
@Volatile
private var INSTANCE: AppDatabase? = null
fun getDatabase(
context: Context
): AppDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context,
AppDatabase::class.java,
"app_database"
)
.createFromAsset("database/sql_basics.db")
.build()
INSTANCE = instance
instance
}
}
}
}
データベースを利用するためのコード
- 今回は MainActivity.kt からデータベースを利用してみます
- AppDatabase の getDatabase() でデータベースのインスタンスを取得します
- データベースインスタンスの californiaParkDao() メソッドを使って、CaliforniaParkDao の getAll() を呼び出します
- getAll() は、エンティティ(CaliforniaPark)で関連付けられた park テーブル(SQLiteデータベース)のデータを、リストとして返します
class MainActivity : AppCompatActivity() { ・・・ override fun onCreate(savedInstanceState: Bundle?) { ・・・ GlobalScope.launch { AppDatabase.getDatabase(applicationContext).californiaParkDao().getAll().forEach { Log.d("MainActivity","${it.name}") } } }