Room Database

Assist·2023년 5월 29일
0

Android

목록 보기
17/24

오늘은 Room database에 대해 공부해보고 적용해 보는 시간을 가져보려고 합니다.

일단 Room Database 이란?

Room DataBase

이전에 제가 학교에 다닐때 약간 메세지를 전송 하고 받는 메세지 앱 같은걸 구현한적이 있습니다.
그때는 서버가 없어서
A ->B 메세지 전송시 핸드폰에 메세지를 저장했습니다.
그때 썼던게 MySQL 이었던 기억이 있습니다.

그럼 왜 MySql 이라는 대중적인놈이 있는데 왜 RoomDatabase을 사용할까 를 알아 봤습니다

왜 Room Database 인가

  • 쿼리 검증
    mySQL 을 사용할때를 곰곰히 생각해보면
    일단 한번 APP을 돌려놓고 예외 상황이 생겼는지 체크 했던 무식한 방법을 저는 썼던거 같습니다
    (제가 무식한거지 다른사람은 아닙니다)
    그러나 Roomdatabase 는 코드를 개발할떄 쿼리문의 오타나 오류를 찾아줍니다.

  • LiveData 와 Rxjava 사용가능

  • 스키마가 바뀌었을 때 영향 받는 SQL 쿼리를 직접 바꾸지 않아도 된다.

  • 상용구 코드 없이 DB 객체를 자바 객체에 매핑한다.

    이렇게 가 있는거 같습니다. LiveData 와 Rxjava 사용가능 에서 구글에서 적극 권장한다는 느낌을 받았습니다.

RoomDatabase을 사용하자

일단 Roomdatabase을 사용하려면 라이브러리를 다운 받아야 한다.
https://developer.android.com/training/data-storage/room?hl=ko

여기를 가서 다운을 받아보자.

와중에 개발자 가이드 문서를 보다보니 이런 안내 메세지가 있다. 싱글톤으로 구현하라 알겠습니다 한번 해봐야지요

일단 MainApplication 을 만들어 봅시다.

class MainApplication : Application() {
    companion object{
        lateinit var appContext : Context
    }

    override fun onCreate() {
        super.onCreate()
        appContext = applicationContext
    }

}

이러한 클래스를 만들어주고

Mainfest 파일에

  <application
        android:name=".MainApplication"
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"

의 name에 MainApplication을 지정해 줬습니다.

@Database(
    entities = [
        FavoriteBookList :: class ,
        SearchList :: class
    ],
    version = 1
)

abstract class AppdataBase : RoomDatabase() {
    abstract fun dataDao () : DataDao

    companion object{
        const val TABLE_SEARCH_LIST = "searchList"
        const val TABLE_FAVORITE_BOOK = "favoriteBook"
        @Volatile
        private var instance : AppdataBase ? = null

 
        fun getInstance() : AppdataBase{
            instance ?: synchronized(this){
                instance = Room.databaseBuilder(MainApplication.appContext ,
                    AppdataBase :: class.java,
                    "database")
                    .allowMainThreadQueries()
                    .fallbackToDestructiveMigration()
                    .build()
            }
            return instance!!
        }

    }
}

그후 검색어를 저장을 위한 table 와 즐겨찾기 책 table 을 만들었습니다. 싱글톤으로 만들었습니다.
참고로 @Volatile 이란?

  • Volatile
    이 변수는 메인 메모리에만 적재할꺼야 라는 선언입니다.
    -일반 변수는 Thread가 읽다가 cpu cash에 저장을 합니다. 단 멀티 Thread 경우 각각 읽어온 변수 값이 cpu cash에 다른 값을 집어 넣을수 있기 때문에 그것을 막기위해 이변수는 메인 메모리에 하나만 저장해서 읽어올꺼야 라는 선언입니다.

자 그럼 저장할 객체를 만들어 봅시다

@Entity(
    tableName = AppdataBase.TABLE_SEARCH_LIST
)
data class SearchList(
    @PrimaryKey var time : String ,
    @ColumnInfo var search : String
)
-------------------------------------------------------
@Entity(
    tableName = AppdataBase.TABLE_FAVORITE_BOOK
)

data class FavoriteBookList(
    @PrimaryKey var time  : String,
    @ColumnInfo var title : String,
    @ColumnInfo var writer : String ,
    @ColumnInfo var link : String
)

제가 만든 객체들입니다. 제가 Datatbase을 만들때 table의 식별키를 만들어야 한다 라고 배웠던 기억이 있습니다.

그래서 보면
검색 기록 같은 경우는 사용자가 검색을 했던시간(@PrimaryKey var time : String)
책같은 경우는 발행 시간 (@PrimaryKey var time : String) 으로 했습니다.

왜 이걸로 했냐 시간 같은 경우는
검색 기록 같은 경우는 밀리세컨드 까지 기록을 해서 겹칠일이 없고
발행일자도 분초 까지 나와 겹칠일이 없다고 생각했습니다

PrimaryKey는 겹치는게 없어야 합니다

자 그럼 객체도 만들었으니 insert delete 도 만들어 봐야지요?

@Dao
interface DataDao {

    @Insert
    fun insertSearchList(data : SearchList)

    @Insert
    fun insertFavoriteBook(data : FavoriteBookList)

    @Query("SELECT * FROM ${AppdataBase.TABLE_SEARCH_LIST}")
    fun getSearchList() : List<SearchList>

    @Query("SELECT * FROM ${AppdataBase.TABLE_FAVORITE_BOOK}")
    fun getFavoriteBookList() : List<FavoriteBookList>
}

간단 하지요? insert 같은 경우는 @Insert 만 넣어주면 되고
원하는 데이터가 있으면 @Query을 작성해서 저런식으로 Table 이름만 넘겨 주면 됩니다.

여기서 주의할 점은 @Dao 을 꼭 써 줘야 합니다. 안그럼 빌드도 못합니다

자 그럼 결과는?

잘 저장된거 같습니다.
그럼 여기까지 읽어주셔서 감사합니다

profile
안드로이드만 좋아하는 특이한 개발자

0개의 댓글

관련 채용 정보