Для чего нужна аннотация Dao в Room?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Аннотация @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 подходом.