В этой статье хочу рассказать как быстро и просто подключить библиотеку Room в свое android приложение.
Зависимости
Заходим в build.gradle своего приложения и добавляем следующие зависимости: Актуальную версию можно взять на сайте maven (room-ktx и room-runtime):
implementation "androidx.room:room-ktx:2.5.0"
implementation "androidx.room:room-runtime:2.5.0"
Entities. Сущности
Для работы с базой данных необходимо создать "сущности", которые будут являться нашими таблицами в базе.
@Entity(tableName = "Exercise")
data class ExerciseEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "exercise_id")
val exerciseId: Int = 0,
@ColumnInfo(name = "name", index = true)
val name: String,
)
Аннотация @Entity означает, что данный класс является таблицей в базе. С помощью "tableName" мы можем явно указать имя таблицы.
Первичный ключ мы можем указать с помощью аннотации @PrimaryKey. AutoGenerate показывает, что ключи будут генерироваться автоматически.
Если мы хотим, чтобы имена полей в таблице отличались от имен полей класса то в аннотации @ColumnInfo прописываем name и явно указываем желаемое имя для поля таблицы.
DAO. Доступ к сущностям в базе
Далее, нам необходимо как-то взаимодействовать с нашими сущностями в базе данных. Для того, чтобы иметь возможность получить список сущностей из базы, удалять и добавлять сущности в базу, нужно создать интерфейс доступа Dao:
@Dao
interface ExerciseDao {
}
Добавим в наш интерфейс метод, с помощью которого сможем вытащить все из таблицы Exercise:
@Query("SELECT * FROM Exercise")
suspend fun getAllExercises(): List<ExerciseEntity>
Далее, добавим метод, с помощью которого сможем добавлять Exercise в нашу таблицу:
@Insert
fun insertExercises(vararg exerciseEntities: ExerciseEntity)
Метод, чтобы удалить Exercise из базы:
@Delete
fun deleteExercises(vararg exerciseEntities: ExerciseEntity)
Полностью класс DAO выглядит так:
@Dao
interface ExerciseDao {
@Query("SELECT * FROM Exercise")
suspend fun getAllExercises(): List<ExerciseEntity>
@Insert
fun insertExercises(vararg exerciseEntities: ExerciseEntity)
@Delete
fun deleteExercises(vararg exerciseEntities: ExerciseEntity)
}
RoomDatabase. Класс создания базы данных
Итак, сущности мы создали, доступ к ним определили, осталось написать класс инициализации нашей базы данных. Так как создание базы данных, процесс дорогостоящий, нужно быть очень внимательными.
Для начала создадим абстрактный класс AppDatabase и поместим в него companion object с наименованием нашей базы и ее инстансом:
abstract class AppDatabase : RoomDatabase() {
companion object {
private const val TAG = "exercise.db"
private var instance: AppDatabase? = null
}
}
Далее напишем оператор invoke и функцию buildDatabase, для создания базы данных:
companion object {
private const val TAG = "workouts.db"
@Volatile
private var instance: AppDatabase? = null
private val LOCK = Any()
operator fun invoke(context: Context): AppDatabase {
return instance ?: synchronized(LOCK) {
instance ?: buildDatabase(context).also { instance = it }
}
}
private fun buildDatabase(context: Context): AppDatabase {
return Room.databaseBuilder(context, AppDatabase::class.java, TAG).build()
}
}
Не забудем добавить аннотацию @Database с нашей сущностью ExerciseEntity и версией бд. Внутри класса нужно указать интерфейс доступа к сущности. Полный фрагмент AppDatabase выглядит так:
@Database(
entities = [ ExerciseEntity::class ],
version = 1
)
abstract class AppDatabase : RoomDatabase() {
abstract fun exerciseDao(): ExerciseDao
companion object {
private const val TAG = "exercise.db"
@Volatile
private var instance: AppDatabase? = null
private val LOCK = Any()
operator fun invoke(context: Context): AppDatabase {
return instance ?: synchronized(LOCK) {
instance ?: buildDatabase(context).also { instance = it }
}
}
private fun buildDatabase(context: Context): AppDatabase {
return Room.databaseBuilder(
context,
AppDatabase::class.java, TAG
).build()
}
}
}
Обращение к базе данных
Все готово. Теперь мы можем обратиться к нашей базе из любого места в приложении. Например, наполнить таблицу Exercise:
val db = AppDatabase(context)
val exercises = listOf(
ExerciseEntity(name = "Классические отжимания"),
ExerciseEntity(name = "Отжимания на трицепс"),
ExerciseEntity(name = "Приседания"),
)
db.exerciseDao().insertExercises(*exercises.toTypedArray())