이번에는 Data Access Object인 DAO를 만들어 볼 것이다.
DAO는 안드로이드에서 DB의 insert, delete, update에 대한 편의성을 제공한다.
Room DB를 사용할 때 코드에서 함수를 정의하고 호출하여 DB를 쿼리한다.
이러한 함수들은 SQL 쿼리들을 매핑한다.
주석(annotation)을 사용하여 DAO에 이러한 매핑을 정의하면 Room이 필요한 코드를 생성한다.
DAO를 DB에 접근하기 위한 인터페이스로 생각하면 된다.
추가로, 쿼리를 생성할 때 컴파일러가 문법 에러를 검사해준다.
(개인적으로 잘못된 컬럼을 조회하는 일은 적어질 거라 생각한다)
sleep-tracker 데이터베이스에 아래 나열한 것들을 해야한다.
- night를 삽입한다.
- 존재하는 night에 종료 시간과 품질 평가를 업데이트한다.
- 키를 통해 특정 night를 가져온다.
- 모든 night를 가져온다.
- 가장 최근의 night를 가져온다.
- 데이터베이스에서 모든 엔트리를 삭제한다.
Step 1. Create the SleepDatabase DAO
1. database 패키지의 SleepDatabaseDao.kt 파일을 연다.
2. SleepDatabaseDao 인터페이스는 @Dao 주석이 포함되어 있다.
모든 DAO는 @Dao 주석을 포함해야 한다.
@Dao
interface SleepDatabaseDao {}
3. 인터페이스의 바디 내부에 @Insert 주석을 추가한다. @Insert 주석 아래에 SleepNight라는 Entity 클래스의 인스턴스를 파라미터로 가진 insert() 함수를 추가한다.
@Insert
fun insert(night: SleepNight)
이렇게 하면, Room은 SleepNight를 데이터베이스에 삽입하는데 필요한 모든 코드를 생성한다.
4. 한 SleepNight를 파라미터로 가지는 update 함수에 @Update 주석을 추가한다. 업데이트되는 파라미터로 전달한 Entity와 동일한 키를 가진 Entity이다. Entity의 모든 속성 또는 일부를 업데이트할 수 있다.
@Update
fun update(night: SleepNight)
아쉽게도 나머지 쿼리문에서는 편의성을 위한 주석이 없으므로 @Query 주석을 사용하여 SQLite 쿼리를 만들어야 한다.
5. Long 타입의 key 파라미터를 가지고 nullable SleepNight Entity를 리턴 타입으로 가지는 함수에 @Query 주석을 추가한다. 그렇게 되면 파라미터가 없다는 에러를 마주하게 된다.
@Query
fun get(key: Long): SleepNight?
6. 쿼리는 @Query 주석에 String 파라미터로 제공되어야 한다. @Query에 SQLite 쿼리를 문자열 파라미터로 추가하여 특정 SleepNight에서 모든 열을 검색한다.
daily_sleep_quality_table의 모든 열을 선택한다.
WHERE 절에서 nightId와 key 파라미터 일치 조건을 추가한다. 쿼리에서 함수의 파라미터를 사용하기 위해 콜론(:)을 사용해야 한다.
("SELECT * from daily_sleep_quality_table WHERE nightId = :key")
7. daily_sleep_quality_table에서 모든 것을 삭제하는 쿼리를 가진 clear 함수와 @Query 주석을 추가한다. 이 쿼리는 테이블 자체를 삭제하는 건 아니다.
@Delete 주석은 아이템 하나를 삭제하고, 이를 사용해 삭제할 항목의 리스트를 제공할 수 있다.
테이블에 뭐가 있는지 가져오거나 알아야 한다는 단점이 있다.
@Delete 주석은 특정 항목을 지우는 데에는 훌륭하지만, 테이블의 모든 항목을 삭제하기에는 비효율적이다.
@Query("DELETE FROM daily_sleep_quality_table")
fun clear()
8. getTonight함수와 @Query를 추가한다. 테이블이 비어있는 경우를 처리할 수 있도록 nullable SleepNight Entity가 리턴되도록 한다.
nightId에 의해 내림차순으로 정렬된 첫 번째 요소를 리턴하기 위해 ORDER BY nightId DESC 을 사용하고, LIMIT1 까지 추가해준다.
@Query("SELECT * FROM daily_sleep_quality_table ORDER BY nightId DESC LIMIT 1")
fun getTonight(): SleepNight?
9. getAllNights 함수와 @Query를 추가한다.
테이블에서 모든 열을 내림차순으로 가져온다.
SleepNight의 리스트를 LiveData로 리턴한다.
Room은 이 LiveData를 계속 업데이트한다. 우리가 명시적으로 데이터를 한 번만 가져오면 된다는 얘기다.
이 프로젝트에서는 LiveData를 import해야 한다.
@Query("SELECT * FROM daily_sleep_quality_table ORDER BY nightId DESC")
fun getAllNights(): LiveData<List<SleepNight>>
10. 눈에 띄는 변경점은 없어도 앱이 에러없이 동작하는 것을 볼 수 있다.
'Android' 카테고리의 다른 글
Android DateRangePicker Custom Settings - 1. Modal (0) | 2023.10.22 |
---|---|
How to Hide keyboard from fragments (0) | 2023.10.08 |
Android BottomSheet Material Theme 적용하기 (0) | 2023.09.15 |
Android BottomNavigationView Uncheck All Items (0) | 2023.09.13 |
Android BottomSheetDialogFragment Scrim 영역 터치 동작 (0) | 2023.09.11 |