반응형
    
    
    
  DAO 작성
이제 이전 글에서 작성한 모델에 접근할 수 있게 해주는 DAO(Data Access Object)를 작성해야 한다.
DAO는 DB와 프로그램 사이의 인터페이스 역할을 수행하여, Model을 DB에 쉽게 저장하고 불러올 수 있도록 해주는 클래스다.
Item엔 Alarm의 FK가 있기 때문에 Alarm DAO부터 작성했다.
AlarmDAO.kt
class AlarmDAO(val context: Context) {
    fun insert(alarm: Alarm): Int {
        val db = DBHelper(context)
        val result = db.insert(Alarm.TableInfo.TABLE_NAME, ContentValues().apply {
            put(Alarm.TableInfo.COLUMN_NAME_FILE_PATH, alarm.filePath)
            put(Alarm.TableInfo.COLUMN_NAME_VOLUME, alarm.volume)
            put(Alarm.TableInfo.COLUMN_NAME_REPEAT_TIMES, alarm.repeatTimes)
            put(Alarm.TableInfo.COLUMN_NAME_INTERVAL, alarm.interval)
        })
        return result
    }
    fun selectAll(): List<Alarm> {
        val db = DBHelper(context)
        val cursor = db.selectAll(Alarm.TableInfo.TABLE_NAME)
        val list: ArrayList<Alarm> = ArrayList()
        while(cursor.moveToNext()) {
            val id = cursor.getInt(0)
            val filePath = cursor.getString(1)
            val volume = cursor.getInt(2)
            val repeatTimes = cursor.getInt(3)
            val interval = cursor.getInt(4)
            val alarm = Alarm(id, filePath, volume, repeatTimes, interval)
            Log.d(TAG, "selectAll: $alarm")
            list.add(alarm)
        }
        return list
    }
    fun select(whereClause: String): Alarm? {
        val db = DBHelper(context)
        val cursor = db.select(Alarm.TableInfo.TABLE_NAME, whereClause)
        if(cursor.moveToNext()) {
            val id = cursor.getInt(0)
            val filePath = cursor.getString(1)
            val volume = cursor.getInt(2)
            val repeatTimes = cursor.getInt(3)
            val interval = cursor.getInt(4)
            val alarm = Alarm(id, filePath, volume, repeatTimes, interval)
            Log.d(TAG, "selectAll: $alarm")
            return alarm
        }
        else {
            return null
        }
    }
    fun update(alarm: Alarm) {
        val db = DBHelper(context)
        val values = ContentValues().apply {
            put(Alarm.TableInfo.COLUMN_NAME_FILE_PATH, alarm.filePath)
            put(Alarm.TableInfo.COLUMN_NAME_VOLUME, alarm.volume)
            put(Alarm.TableInfo.COLUMN_NAME_REPEAT_TIMES, alarm.repeatTimes)
            put(Alarm.TableInfo.COLUMN_NAME_INTERVAL, alarm.interval)
        }
        db.update(Alarm.TableInfo.TABLE_NAME, values, "${BaseColumns._ID} = ?", alarm.id.toString())
    }
    fun delete(id: Int) {
        val db = DBHelper(context)
        db.delete(Alarm.TableInfo.TABLE_NAME, "${BaseColumns._ID} = ?", id.toString())
    }
}
작성한 함수의 역할은 다음과 같다.
- insert: Alarm 객체를 입력받아 DB에 Insert 한다. 입력된 객체의 ID를 반환한다.
 - selectAll: Alarm 테이블의 모든 행을 List<Alarm>으로 변환하여 반환한다.
 - select: where 조건문을 입력받아 조회된 행들 중 가장 첫번째를 Alarm 형태로 반환한다.
 - update: Alarm 객체를 입력받고, 입력 받은 객체의 ID에 해당하는 행을 입력받은 데이터로 바꾼다.
 - delete: ID를 입력받아 해당 ID의 행을 삭제한다.
 
이제 DBHelper에 일일히 쿼리를 날리지 않아도 된다.
작성한 DAO를 사용해 다음과 같이 DB에 저장하고 불러올 수 있다.
val alarmDAO = AlarmDAO(context)
val alarm1 = Alarm("Test1", 1, 1, 1) 
alarmDAO.insert(alarm1)
ItemDAO엔 Alarm 변수가 들어가있는데, 이를 AlarmDAO를 통해 조회해줬다.
ItemDAO.kt
class ItemDAO(val context: Context) {
    fun insert(item: Item): Int {
        val db = DBHelper(context)
        val result = db.insert(Item.TableInfo.TABLE_NAME, ContentValues().apply {
            put(Item.TableInfo.COLUMN_NAME_ITEM, item.name)
            put(Item.TableInfo.COLUMN_NAME_ENABLE, if(item.enabled) 1 else 0)
            put(Item.TableInfo.COLUMN_NAME_FK_ITEM_ALARM, item.alarm?.id.toString())
        })
        return result
    }
    fun selectAll(): List<Item> {
        val db = DBHelper(context)
        val cursor = db.selectAll(Item.TableInfo.TABLE_NAME)
        val list: ArrayList<Item> = ArrayList()
        val alarmDAO = AlarmDAO(context)
        while(cursor.moveToNext()) {
            val id = cursor.getInt(0)
            val name = cursor.getString(1)
            val isEnabled = cursor.getInt(2) == 1
            var alarm: Alarm? = null
            if(cursor.getString(3).lowercase(Locale.getDefault()) != "null") {
                alarm = alarmDAO.select("${BaseColumns._ID} = ${cursor.getInt(3)}")
            }
            list.add(Item(id, name, isEnabled, alarm))
        }
        return list
    }
    fun select(whereClause: String): Item? {
        val db = DBHelper(context)
        val cursor = db.select(Item.TableInfo.TABLE_NAME, whereClause)
        val alarmDAO = AlarmDAO(context)
        if(cursor.moveToNext()) {
            val id = cursor.getInt(0)
            val name = cursor.getString(1)
            val isEnabled = cursor.getInt(2) == 1
            var alarm: Alarm? = null
            if(cursor.getString(3).lowercase(Locale.getDefault()) != "null") {
                alarm = alarmDAO.select("${BaseColumns._ID} = ${cursor.getInt(3)}")
            }
            return Item(id, name, isEnabled, alarm)
        }
        else {
            return null
        }
    }
    fun update(item: Item) {
        val db = DBHelper(context)
        val values = ContentValues().apply {
            put(Item.TableInfo.COLUMN_NAME_ITEM, item.name)
            put(Item.TableInfo.COLUMN_NAME_ENABLE, if(item.enabled) 1 else 0)
            put(Item.TableInfo.COLUMN_NAME_FK_ITEM_ALARM, item.alarm?.id.toString())
        }
        db.update(Item.TableInfo.TABLE_NAME, values, "${BaseColumns._ID} = ?", item.id.toString())
    }
    fun delete(id: Int) {
        val db = DBHelper(context)
        db.delete(Item.TableInfo.TABLE_NAME, "${BaseColumns._ID} = ?", id.toString())
    }
}
select와 selectAll 함수에 각 개체마다 alarm을 불러와서 저장하도록 구현했다.
이제 item만 조회해도 alarm도 같이 조회되어 똑같은 일을 두번 하지 않아도 된다.
다음 시간엔 테스트 코드를 작성해야겠다.
반응형
    
    
    
  'Projects > It's My Waye' 카테고리의 다른 글
| [It's My Waye] 7. 메인화면 UI 구현 (DrawerLayout) (0) | 2022.01.23 | 
|---|---|
| [It's My Waye] 6. DB 기능 구현 - 테스트 코드 작성 (0) | 2022.01.23 | 
| [It's My Waye] 4. DB 기능 구현 - Model 작성 (0) | 2022.01.22 | 
| [It's My Waye] 3. DB 기능 구현 - DBHelper (0) | 2022.01.22 | 
| [It's My Waye] 2. 기능, DB 및 UI 설계하기 (0) | 2022.01.06 |