← Назад к вопросам

Как создать БД с помощью Room?

1.0 Junior🔥 242 комментариев
#Android компоненты#Работа с данными

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Создание базы данных с помощью Room Persistence Library

Room — это абстракция над SQLite, предоставляемая Android Jetpack, которая упрощает работу с базой данных, минимизирует шаблонный код и обеспечивает проверку на этапе компиляции. Вот пошаговое руководство по созданию БД с помощью Room.

1. Добавление зависимостей в build.gradle (Module)

Сначала необходимо добавить необходимые зависимости в файл build.gradle уровня модуля:

plugins {
    id("kotlin-kapt")
}

dependencies {
    def room_version = "2.6.1"
    implementation "androidx.room:room-runtime:$room_version"
    kapt "androidx.room:room-compiler:$room_version"
    // Опционально: поддержка Kotlin Extensions и Coroutines
    implementation "androidx.room:room-ktx:$room_version"
}

2. Создание Entity (Сущности)

Entity — это класс, аннотированный @Entity, который представляет таблицу в базе данных. Каждый экземпляр класса — строка в таблице.

@Entity(tableName = "users")
data class User(
    @PrimaryKey(autoGenerate = true)
    val id: Int = 0,
    
    @ColumnInfo(name = "user_name")
    val name: String,
    
    @ColumnInfo(name = "user_age")
    val age: Int,
    
    @ColumnInfo(name = "email")
    val email: String?
)
  • @PrimaryKey помечает первичный ключ, autoGenerate = true позволяет автоматически генерировать ID.
  • @ColumnInfo позволяет задать имя столбца, отличное от имени поля.

3. Создание DAO (Data Access Object)

DAO — это интерфейс или абстрактный класс, аннотированный @Dao, который содержит методы для доступа к базе данных. Room автоматически генерирует реализации.

@Dao
interface UserDao {
    
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertUser(user: User)
    
    @Update
    suspend fun updateUser(user: User)
    
    @Delete
    suspend fun deleteUser(user: User)
    
    @Query("SELECT * FROM users")
    fun getAllUsers(): Flow<List<User>>
    
    @Query("SELECT * FROM users WHERE id = :userId")
    suspend fun getUserById(userId: Int): User?
    
    @Query("DELETE FROM users WHERE name = :userName")
    suspend fun deleteUserByName(userName: String)
}
  • @Insert, @Update, @Delete — готовые операции.
  • @Query позволяет написать произвольный SQL-запрос.
  • Использование suspend функций и Flow обеспечивает работу в Coroutines и реактивное обновление данных.

4. Создание базы данных (Database)

Класс, аннотированный @Database, должен быть абстрактным и наследоваться от RoomDatabase. Он служит точкой доступа к базе данных.

@Database(
    entities = [User::class],
    version = 1,
    exportSchema = true
)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
    
    companion object {
        @Volatile
        private var INSTANCE: AppDatabase? = null
        
        fun getDatabase(context: Context): AppDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    AppDatabase::class.java,
                    "app_database.db"
                )
                .fallbackToDestructiveMigration() // Упрощённая миграция (удаляет и создаёт заново)
                .build()
                INSTANCE = instance
                instance
            }
        }
    }
}
  • entities — список всех Entity-классов базы данных.
  • version — версия схемы БД, необходима для миграций.
  • Singleton-паттерн гарантирует наличие только одного экземпляра базы данных.
  • exportSchema позволяет экспортировать схему в папку schemas для анализа.

5. Использование базы данных в приложении

Создайте экземпляр базы данных в Application классе, ViewModel или Repository.

class UserRepository(private val userDao: UserDao) {
    
    val allUsers: Flow<List<User>> = userDao.getAllUsers()
    
    suspend fun insert(user: User) {
        userDao.insertUser(user)
    }
    
    suspend fun getUser(id: Int): User? {
        return userDao.getUserById(id)
    }
}

// В ViewModel
class UserViewModel(application: Application) : AndroidViewModel(application) {
    private val repository: UserRepository
    
    init {
        val userDao = AppDatabase.getDatabase(application).userDao()
        repository = UserRepository(userDao)
    }
    
    val allUsers: Flow<List<User>> = repository.allUsers
    
    fun insertUser(name: String, age: Int) = viewModelScope.launch {
        repository.insert(User(name = name, age = age))
    }
}

Ключевые преимущества Room

  • Проверка SQL-запросов на этапе компиляции: Ошибки в запросах будут обнаружены сразу, а не во время выполнения.
  • Сокращение шаблонного кода: Room автоматически генерирует реализации DAO.
  • Интеграция с LiveData и Flow: Позволяет создавать реактивные интерфейсы.
  • Миграция базы данных: Встроенные механизмы для управления изменениями схемы.
  • Поддержка отношений между таблицами: Через @Relation и @ForeignKey.

Важные замечания

  • Все операции с базой данных, кроме возвращающих Flow или LiveData, должны выполняться в фоновом потоке (используйте Coroutines, RxJava или Executor).
  • Для сложных миграций используйте Room.databaseBuilder().addMigrations(Migration_1_2).
  • Для тестирования используйте Room.inMemoryDatabaseBuilder().

Таким образом, Room предоставляет мощный, типобезопасный и эффективный способ работы с базой данных SQLite в Android-приложениях, значительно ускоряя разработку и уменьшая количество ошибок.