-
Room DB 사용하기안드로이드 2020. 6. 30. 10:32
Room DB는 SQLite를 이용해 앱 내부 데이터베이스를 구축하고 사용하는 데 도움을 주는 라이브러리이다.
Android 에선 SQLite 라는 DBMS로 데이터를 저장할 수 있다. 물론 Room DB 가 아닌 자체 API만으로도 충분히 데이터베이스에 데이터 저장과 접근이 가능하다.
그럼 왜 Room DB를 쓰는 것일까?
우리가 DB에 저장해야 할 데이터 양이 많다고 가정했을 때, 이 데이터들이 서버가 아닌 로컬에 유지된다면 우리는 서버에 직접 연결해 데이터를 가져오는 것보다 훨씬 빠르게 데이터에 접근할 수 있고, 오프라인 상태일때도 여전히 해당 데이터에 접근이 가능하게 된다.
( 출처 : https://developer.android.com/training/data-storage/room?hl=ko )
SQLite는 위와 같은 작업이 가능하지 않지만, Room DB 라이브러리를 사용하면 데이터를 자동으로 캐싱해줘 위와 같은 이점을 얻을 수 있다.
이 외에도 많은 이점들이 있는 Room DB를 굳이 사용하지 않을 이유도 없지 않을까?
Room DB 는 크게 3가지의 요소로 구성되어(구현할 수) 있다.
- DB
- Table 구조
- DAO
우선 DB에 대해 먼저 알아보자. 여기서 말하는 DB란, DBMS에서 흔히 말하는 DB가 아닌 데이터에 접근하기 위한 시작 및 끝맺음 지점을 말한다. ( Android 공식 문서에선 '기본 액세스 포인트' 라고 설명해 두었네요. 말을 어쩜 저리 잘하는지.. )
말로 설명하면 어려울 수 있으니 예제 코드는 아래와 같다.
@Database(entities = [DB::class], version = 1) abstract class RealDB: RoomDatabase() { abstract fun dbDao(): DBDao companion object { private var INSTANCE: RealDB? = null fun getInstance(context: Context): RealDB? { if (INSTANCE == null) { synchronized(RealDB::class) { INSTANCE = Room.databaseBuilder(context.applicationContext, RealDB::class.java, "db.db") .fallbackToDestructiveMigration() .build() } } return INSTANCE } fun destroyInstance() { INSTANCE = null } } }
위 코드와 같이 데이터 접근을 위한 인스턴스를 가져오고, 지워주는 메서드가 구현되어 있는 RoomDatabase를 확장하는 추상 클래스이다.
두 번째로 Table 구조이다. 이건 말 그대로 Table 구조를 구현해놓은 것이다. 바로 코드를 보자.
@Entity(tableName = "db") class DB(@PrimaryKey var id: Long?, @ColumnInfo(name="title") var title: String?, @ColumnInfo(name="isDone") var isDone: Boolean? ) { constructor(): this(null, "", false) }
이전에 DB에 대해 조금이라도 들어본 사람들은 바로 이해했을 것이다.
먼저 테이블 이름을 정의해주고, PrimaryKey를 지정하고 나머지 컬럼 이름들도 지정해준다.
여기서 알아두면 좋은 점은, 컬럼 이름 지정 뒤에 따로 변수명을 명시해주지 않아도 사용이 가능하다. 예를 들어 위 코드에서는 title로 컬럼 명 지정 후 title 변수를 따로 선언해 주었는데, 이 선언 없이도 title 이라는 변수명을 사용할 수 있다.
마지막으로 세번째, DAO이다. DAO는 Data Access Object의 약자로, 데이터에 접근하는 데 필요한 메서드 및 쿼리가 있는 인터페이스이다.
@Dao interface DBDao { @Query("SELECT * FROM db") fun getAll(): List<DB> @Insert fun insert(db: DB) @Delete fun delete(db: DB) @Update fun update(db: DB) }
우리가 알던 쿼리문을 이용해 데이터에 접근한다. 이를 메서드로 구현해 코드 가독성 향상과 사용에 편리하다는 이점이 있다.
getAll() 메서드처럼 쿼리문을 직접 커스텀 할 수도 있고, INSERT 와 DELETE 같은 구문들은 따로 쿼리문을 적어주지 않아도 위 코드처럼 처리할 수 있다.
이제 사용법에 대해 알아보자.
Room DB 사용시 DB는 메인 쓰레드에서 접근할 수 없다는 점을 인지해야 한다.
메인 쓰레드에서 DB에 접근했을 때, 가져올 데이터가 많거나 DB 접속에 에러가 생겼을 때 사용자가 보는 UI에 이상을 줄 수 있고, 최악의 경우엔 Exception이 나며 비정상 종료가 될 수 있기 때문이다.
아래와 같은 코드로 Room DB를 이용해 데이터에 접근할 수 있다.
private var dbList = listOf<DB>() var realdb = RealDB.getInstance(this) val r = Runnable { dbList = RealDB?.dbDao()?.getAll() } var thread = Thread(r) thread.start()
먼저 데이터들을 저장할 리스트와 DB 객체를 선언하고 DB 객체에는 우리가 DB에서 정의해둔 getInstance() 메서드를 이용해 가져온 인스턴스를 넣어준다.
데이터를 처리할 땐 메인 쓰레드에서 할 수 없으므로 따로 쓰레드를 만들어 해당 쓰레드에서 getAll() 등 메서드를 이용해 데이터를 처리한다.
이렇게 Room DB 의 개념과 사용법에 대해 알아보았다.
분명 SQLite의 기본 API를 사용할 수 있지만, 코드의 가독성과 앱 성능을 위해 Room DB를 사용하는 것을 추천하겠다.
'안드로이드' 카테고리의 다른 글
Android 전화 수신 차단하기 (0) 2020.12.07 안드로이드 서비스 앱 삭제 및 강제종료 방지하기 (5) 2020.08.24 Android Exoplayer 제스쳐 기능 추가 (0) 2020.05.08 [Kotlin] 함수형 프로그래밍 (0) 2020.04.01 Android Exoplayer 플레이리스트 (0) 2020.03.17 댓글