GDSC HUFS 3기/Android with Kotlin Team 3

[3팀] 17 Room 데이터베이스

darly213 2021. 11. 30. 00:27

1. Build.gradle

plugins에 아래 코드를 추가한다.

id 'kotlin-kapt'

dependencies에 아래 코드를 추가한다. room 안정화 버전과 추가 implementation은 아래 북마크에서 확인할 수 있다.

https://developer.android.com/jetpack/androidx/releases/room?gclid=CjwKCAiAv_KMBhAzEiwAs-rX1LFTHxUT0JsJbup662m_LJzUcw8w4XYWrW8FEzm23BiFkCW57A7W1xoCSEMQAvD_BwE&gclsrc=aw.ds#kts

		def roomVersion = "2.3.0"

    implementation("androidx.room:room-runtime:$roomVersion")
    annotationProcessor("androidx.room:room-compiler:$roomVersion")

    // To use Kotlin annotation processing tool (kapt)
    kapt("androidx.room:room-compiler:$roomVersion")

2. RoomMemo.kt

import androidx.room.ColumnInfo
import androidx.room.Entity

@Entity(tableName="room_memo")
class RoomMemo {
		@PrimaryKey(autoGenerate=true) // no에 값이 없을 때 자동으로 증가한 숫자를 db에 입력
    @ColumnInfo
    var no: Long? = null
    @ColumnInfo
    var content: String = ""
    @ColumnInfo(name="date")
    var datetime:Long = 0
}

roomMemo 클래스를 database의 table처럼 사용한다. Entity 키워드를 붙여서 tableName을 지정해주고, no, content, datetime을 모두 table의 column으로 사용할 수 있도록 해주었다.

전반적으로 sql처럼 관계형 데이터베이스의 특징을 갖고 있다.

편하게 RoomMemo Class를 활용하기 위해서 생성자를 만들어주어싿.

constructor(content:String, datetime:Long){
        this.content = content
        this.datetime = datetime
    }

3. RecyclerAdapter.kt

class RecyclerAdapter(val roomMemoList:List<RoomMemo>) : RecyclerView.Adapter<Holder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
        val binding = ItemRecyclerBinding.inflate(LayoutInflater.from(parent.context), parent, false)
        return Holder(binding)
    }

    override fun onBindViewHolder(holder: Holder, position: Int) {
        holder.setMemo(roomMemoList.get(position))
    }

    override fun getItemCount(): Int {
        return roomMemoList.size
    }
}

class Holder(val binding: ItemRecyclerBinding) : RecyclerView.ViewHolder(binding.root){
    fun setMemo(roomMemo: RoomMemo){
        with(binding){
            textNo.text = "${roomMemo.no}"
            textContent.text = "${roomMemo.content}"
            val sdf = SimpleDateFormat("yyyy/mm/dd hh:mm")
            val datetime = sdf.format(roomMemo.datetime)
            textDateTime.text = "$datetime"
        }
    }
}

이전의 sqlite와는 다르게 binding을 기반으로 코드를 다시 재가공했다.

 

날짜형태로 변환하는 simple data format 만들기

RoomMemo의 경우는 room에 에너테이션을 써서 사용해야 하기 때문에 

RoomMemo 클래스에서 데이터 클래스 -> 클래스로 변경해야한다. 

따라서 변수를 다 초기화 시켜준다. 

그리고 이 클래스는 table 같이 사용되기 때문에 @Entity 에너테이션을 사용하고 tableName을 room_memo로 설정해준다. 

그런 다음 @ColumnInfo을 사용해 변수 하나하나를 칼럼으로 사용한다고 알려준다. 

* @ColumnInfo는 알리아싱으로 사용해 다른 이름으로 사용할 수가 있다. 

-> 이런 식으로 사용하면 코드에서는 datetime으로 사용하고 데이터베이스에서는 date라는 이름으로 칼럼이 생성된다. 

 

널이 들어왔을 때 숫자가 자동으로 생성해주는 옵션이 있는데 

-이런 식으로 사용하고 no에 Null값이 들어왔을 때 자동 증가된 숫자값을 데이터베이스에 입력해준다.  

 

그리고 생성자를 만들어서 코드를 짧게 사용할 수 있도록 해준다. 

4. RoomMemoDAO interface 만들기

그런 다음 @Dao 을 해주고 3개의 메서드를 생성해준다. 

Insert로 메모가 들어오는데 no값이 겹치게 되면 충돌을 걸러서 업데이트를 해준다

이니테이션을 사용하면 room이 메서드안에 함수를 자동으로 생성해서 사용할 수 있게 해준다. 

-이렇게 만들어주면 RoomMemoDAO 인터페이스는 완료이다. 

 

그 후 실제 룸을 사용할 수 있는 helper 클래스를 작성해준다. 

 

추상 클래스로 만들어주고 @database 이니테이션을 사용하고 내가 사용하는 테이블이 몇개가 있다를 entities = arrayOf(RoomMemo::class)로 알려주고 버전, exportSchema도 설정해준다. 

* 버전을 수정하며 기존의 테이블을 수정해줄 수 있다. 

룸헬퍼는 이 데이터베이스에서 사용할 수 있는 Dao 클래스들을 꺼내서 쓸 수 있게 해준다. 따라서 테이블을 컨트롤할 수 있는 함수의 모음을 룸헬퍼를 통해서 사용한다. 

이렇게 사용하면 roomMemoDAO에 있는 함수를 모두 사용할 수가 있다. 

 

이렇게 바인딩을 연결해주고 룸을 사용할 수 있게끔 helper을 미리 선언해두고 코드안에서 helper에다가 context, 데이터베이스에서 사용되는 helper클래스, 데이터베이스 이름인 room-db을 던져준다. 

 

위 코드처럼 해주면 .build()가 호출되는 순간 RoomHelper을 가지고 사용할 수 있게끔 RoomHelper 클래스를 만들어서 전달해준다. 

 

그 후 데이터베이스에서 메모 리스트를 가져온다. 그런 다음 Recycler Memo에다가 adapter을 연결해준다. 그 후 button이 눌렸을 때를 설정해준다. 

그런 다음 리스트가 초기화되는 걸 만들어준다. 

코드를 쉽게 하기 위해 refreshAdapter()을 생성해서 리스트를 초기화하고, 전체 리스트를 가져오고갱신을 해준다. 

 

이런 식으로 memoAdapter = helper.roomMemoDao()을 미리 선언해서 코드를 줄여줄 수도 있다. 

 

그러고 나서 실행을 하면

이렇게 잘 나오는 것을 확인할 수 있다. 

 

-> editMemo.setText(“”)을 추가해 메모에 입력 후 저장하면 키보드가 초기화되는 함수를 만들 수 있다.