アプリで取得した情報をデータベースに保存したい
こうした悩みを解決します。
Roomとは
Roomとは、sqliteをより簡単に、より便利に活用できるようにしたAndroid推奨のローカルデータベース運用するためのライブラリです。
詳細は公式を参照ください。
全体のイメージ
①エンティティでテーブルの列を定義
②DAO(テーブルを操作するSQL文の入った関数)を作成
③先ほど作成したエンティティとDAOを含めた形でデータベースを作成
④メインアクティビティにてデータベースインスタンスを取得
⑤必要に応じてDAOのメソッドを呼び出してテーブル内を操作
大きくわけてこれら5ステップです。設計においても①→⑤の順番で実装していきます。
では、例によって、下記Android公式と見比べながらいきましょう。
①エンティティでテーブルの列を定義
データベースのテーブルの列情報の定義を書くのがエンティティです。
例えばentity.ktというファイルにして、MainActivityと同じフォルダに作成して下記のように書きます。
@Entity
data class User(
@PrimaryKey(autoGenerate = true)
val id: Int,
val firstName: String,
val lastName: String
)
Userというクラスにid, firstname, lastnameの3項目(列のことでカラムともいう)が入っています。
②DAO(テーブルを操作するSQL文の入った関数)を作成
DAOはdata access objectの略で、データベースを制御するのがDAOです。
中身はデータベースを操作するSQL文とそれを実行する関数宣言で構成されます。
例えばdao.ktというファイルにして、MainActivityと同じフォルダに作成して下記のように書きます。
@Dao
interface UserDao {
@Insert
fun insertAll(vararg users: User)
@Update
fun updateUsers(vararg users: User)
@Delete
fun delete(user: User)
@Query("SELECT * FROM user")
fun getAll(): List<User>
}
エンティティでも書きましたが、アノテーションつけてそこにクエリを記述するといった使い方をします。
③エンティティとDAOを含めた形でデータベースを作成
テーブルカラム情報が入ったエンティティ、データベース操作するSQLが入ったDAOを含めたデータベースを作成します。
例えばdatabase.ktというファイルにして、MainActivityと同じフォルダに作成して下記のように書きます。
// Annotates class to be a Room Database with a table (entity) of the Word class
@Database(entities = [User::class), version = 1, exportSchema = false)
public abstract class UserDatabase : RoomDatabase() {
abstract fun UserDao(): UserDao
companion object {
// Singleton prevents multiple instances of database opening at the same time.
@Volatile
private var INSTANCE: UserDatabase ? = null
fun getDatabase(context: Context): UserDatabase {
// if the INSTANCE is not null, then return it,
// if it is, then create the database
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(context.applicationContext,
WordRoomDatabase::class.java, "word_database"
).build()
INSTANCE = instance
// return instance
instance
}
}
}
}
この関数はほとんどコピペで動きます。
databaseアノテーションで紐づけるエンティティを追加、抽象関数として作成したDAOを紐づけてます。
getDatabase関数はデータベースのインスタンスがあればそれを返す、無ければword_databaseという名称のデータベースを作成してそれを返します。詳細は公式を見てもらえればと思いますが、
ここまででRoomデータベースの設計は完了です。
MainActivity.ktフォルダと同階層にentityファイル、daoファイル、databaseファイルの3つが追加で存在していますか。
もしなければ抜け洩れてますので、再度上から読み直すとよいです。
④メインアクティビティにてデータベースインスタンスを取得
メインアクティビティでデータベースを取得します。
onCreate直下でデータベースのインスタンスを取得するサンプルです。
UserDatabaseクラスのgetDatabase関数からデータベースのインスタンスを取得し、database変数に格納しています。
データベースのインスタンスに内包しているDAOも別途変数にいれます。
これでメインアクティビティでデータベースが触れるようになりました!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//Room用
val database = UserDatabase.getDatabase(this) // データベースの取得
val userDao = database.userDao() // DAOの取得
~~~
⑤必要に応じてDAOのメソッドを呼び出してテーブル内を操作
たとえばボタンを押したらデータ追加するとか。
(下記サンプルだと毎回 tatepro, himenoしか入らない)
var dbbtn = findViewById<Button>(R.id.dbbtn)
dbbtn.setOnClickListener {
val add_user = User(0, "tatepro", "himeno")
// Userの追加
userDao.insertAll(add_user)
}
まとめ
①エンティティでテーブルの列を定義
②DAO(テーブルを操作するSQL文の入った関数)を作成
③先ほど作成したエンティティとDAOを含めた形でデータベースを作成
④メインアクティビティにてデータベースインスタンスを取得
⑤必要に応じてDAOのメソッドを呼び出してテーブル内を操作
大きくわけてこれら5ステップです。設計においても①→⑤の順番で実装していきます。
コメント