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

Для чего нужна аннотация Dao в Room?

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

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

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

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

Аннотация @Dao в Room: назначение и применение

@Dao — это одна из трёх ключевых аннотаций в архитектуре Room (наряду с @Entity и @Database). Она обозначает класс, который содержит методы для доступа к данным в базе данных. DAO расшифровывается как Data Access Object — паттерн, который инкапсулирует всю логику работы с БД.

Основное назначение

@Dao аннотация служит следующим целям:

1. Определение интерфейса доступа к БД

@Dao
interface UserDao {
    @Insert
    suspend fun insertUser(user: User)
    
    @Query("SELECT * FROM users WHERE id = :userId")
    suspend fun getUserById(userId: Int): User
    
    @Update
    suspend fun updateUser(user: User)
    
    @Delete
    suspend fun deleteUser(user: User)
}

2. Инкапсуляция SQL запросов Все операции с БД сконцентрированы в одном месте, не разбросаны по разным Activity/ViewModel.

3. Автоматическая генерация кода Room аннотационный процессор анализирует методы @Dao и генерирует реализацию во время компиляции.

Типы операций в @Dao

@Query — произвольные SQL запросы (SELECT, UPDATE, DELETE)

@Query("SELECT * FROM users WHERE name LIKE :searchQuery")
fun searchUsers(searchQuery: String): List<User>

@Query("SELECT COUNT(*) FROM users")
fun getUserCount(): Int

@Insert — вставка данных

@Insert
fun insertUser(user: User): Long  // Возвращает row id

@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertOrUpdateUser(user: User)

@Update — обновление существующих строк

@Update
fun updateUser(user: User)  // Обновляет по primary key

@Delete — удаление строк

@Delete
fun deleteUser(user: User)  // Удаляет по primary key

Преимущества использования @Dao

1. Type Safety — компилятор проверяет корректность SQL запросов и типов

// Ошибка при компиляции, если колонки не совпадают
@Query("SELECT nonexistent_field FROM users")
fun getBroken(): List<User>  // Не скомпилируется!

2. Асинхронность встроена

@Dao
interface UserDao {
    @Query("SELECT * FROM users")
    suspend fun getAllUsers(): List<User>  // Coroutine
    
    @Query("SELECT * FROM users")
    fun getAllUsersFlow(): Flow<List<User>>  // Reactive
}

3. Разделение ответственности

  • DAO отвечает за доступ к данным
  • Repository добавляет бизнес-логику
  • ViewModel управляет UI состоянием

Полный пример архитектуры

// 1. Entity
@Entity(tableName = "users")
data class User(
    @PrimaryKey val id: Int,
    val name: String,
    val email: String
)

// 2. DAO
@Dao
interface UserDao {
    @Query("SELECT * FROM users")
    suspend fun getAllUsers(): List<User>
    
    @Insert
    suspend fun insertUser(user: User)
}

// 3. Database
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

// 4. Repository
class UserRepository(private val userDao: UserDao) {
    suspend fun getUsers(): List<User> = userDao.getAllUsers()
}

// 5. ViewModel
class UserViewModel(private val repository: UserRepository) : ViewModel() {
    val users = viewModelScope.launch {
        repository.getUsers()
    }
}

Best practices

  • Используй suspend функции для асинхронности с Coroutines
  • Предпочитай Flow для Reactive — автоматические обновления при изменении данных
  • Структурируй DAO логически — разные сущности в разные DAO
  • Избегай сложных запросов в @Query — логику в Repository
  • Используй type converters для сложных типов данных

@Dao — это краеугольный камень Room, который делает работу с БД типобезопасной, удобной и подходящей для современной Android разработки с Coroutines и Reactive подходом.