はじめに
最近、新規開発中のアプリでSQLiteとRoomを導入する機会がありました。導入にあたって学習した内容を備忘録としてまとめておこうと思います。
SQLiteとは?
SQLiteは、軽量でサーバーレスのリレーショナルデータベース管理システム(RDBMS)です。データベース全体が1つのファイルに保存され、アプリケーションに直接組み込んで使用します。Androidアプリでは、ローカルストレージ用データベースとして広く使われています。
特徴
・SQL文を直接記述してデータ操作を行う
・軽量でサーバーレス
・低レベルで柔軟だが、データ操作に冗長なコードが必要
Roomとは?
Roomは、Googleが提供するSQLiteの抽象化ライブラリです。SQLiteの扱いを簡単かつ安全にするための仕組みを提供します。
特徴
・SQLiteの機能を利用しながら、簡潔で安全なコードが書ける
・コンパイル時にSQLやスキーマの検証を行い、エラーを防ぐ
・LiveDataやFlowを利用したリアクティブデータ処理をサポート
実際にコードを見て比較する
Roomを使う前(SQLiteを直接操作する場合)
val dbHelper = object : SQLiteOpenHelper(context, "my-database", null, 1) {
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)")
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {}
}
val db = dbHelper.writableDatabase
// データ挿入
val values = ContentValues().apply {
put("id", 1)
put("name", "John Doe")
put("age", 25)
}
db.insert("users", null, values)
// データ取得
val cursor = db.rawQuery("SELECT * FROM users WHERE id = ?", arrayOf("1"))
if (cursor.moveToFirst()) {
val name = cursor.getString(cursor.getColumnIndex("name"))
val age = cursor.getInt(cursor.getColumnIndex("age"))
println("$name, $age")
}
cursor.close()
db.close()
問題点
・SQL文を手動で記述
・型安全性が低い
・コードが冗長
・保守性が低い
Roomを使った場合
エンティティ定義
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "users")
data class User(
@PrimaryKey val id: Int,
val name: String,
val age: Int
)
DAO定義
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
@Dao
interface UserDao {
@Insert
fun insert(user: User)
@Query("SELECT * FROM users WHERE id = :userId")
fun getUserById(userId: Int): User
}
データベース定義
import androidx.room.Database
import androidx.room.RoomDatabase
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
実行コード
val db = Room.databaseBuilder(
context,
AppDatabase::class.java,
"my-database"
).build()
val userDao = db.userDao()
// データ挿入
userDao.insert(User(1, "John Doe", 25))
// データ取得
val user = userDao.getUserById(1)
println("${user.name}, ${user.age}")
まとめ
Roomを使うことで、安全性・保守性・効率性が大幅に向上します。
・SQLiteを直接操作する場合は柔軟性が高いものの、コードが複雑でミスが起きやすい。
・Roomは、SQLiteを利用したアプリ開発を簡略化し、特にモダンなAndroidアプリ開発において推奨される選択肢です。
SQLiteを直接使うのは古い手法になりつつあり、Roomを活用することで効率的にデータベース操作を行うことができます!