Hyeyeon blog

[Android] Kotlin - Realm 본문

개발/Android

[Android] Kotlin - Realm

Hyeyeon.P 2019. 1. 11. 09:16
반응형

Realm DB 내장 데이터베이스 라이브러리 [Reference]

(1) 데이터 모델

- '데이터 컨테이너' 모델을 사용하여 Realm에 객체로 저장 (ORM이 아님)

(2) Realm

- Realm의 데이터베이스 컨테이너의 인스턴스

- Realm은 단일 애플리케이션 차원의 DB가 아님

: 하나의 애플리케이션에서 여러 Realm을 사용하여 데이터를 구성/저장

- Realm은 테이블이 아님 

: 전형적으로 테이블은 한 종류의 데이터만 저장하지만, Realm은 여러 종류의 객체를 저장할 수 있음

(3) 특징

- lazy loading

- Realm Object에 대한 호출 Thread를 유지해야 함

- 라이브러리 크기가 큼 


1. .gradle 추가

// build.gradle (Module:app)
apply plugin: 'realm-android'
realm {
    syncEnabled = true
    kotlinExtensionsEnabled = true
}

// build.gradle (Project: .. )
buildscript {
    dependencies {
        classpath "io.realm:realm-gradle-plugin:5.8.0"
    }
}

2. 사용할 객체에 RealmObject 상속

- open class로 선언해야함   (cannot inherit from final .. 발생) 

open class Dog : RealmObject() {
   var name: String = ""
   var age: Int = 0
}
open class Person : RealmObject() {
    @PrimaryKey
    var  id : Int = 0
    var name: String = ""
    var dogs: RealmList = RealmList() // Declare one-to-many relationships
}

3. Realm 초기화

// Use them like regular java objects var dog = Dog() dog.name = "Rex" dog.age = 1 // Initialize Realm (just once per application) Realm.init(context) // Get a Realm instance for this thread var realm = Realm.getDefaultInstance()


4. Object 저장

- copyToRealm():  새로운 Realm 객체를 생성 (이미 같은 값의 기본키를 갖는 객체가 있으면 Exception 발생);

     unmanaged 객체, 즉 POJO 인스턴스를 복사해서 managed 인스턴스를 생성(자동으로 Proxy객체도 생성해서 넘겨줌)

- copyToRealmOrUpdate(): 같은 값의 기본키를 가진 객체가 있으면 업데이트를, 없으면 객체를 생성

- createObject(): 새로운 managed 인스턴스를 생성

4-1. commitTransaction()

// Persist your data in a transaction realm.beginTransaction() // Persist unmanaged objects val managedDog = realm.copyToRealm(dog) // Create managed objects directly var person = realm.createObject(Person::class.java)

person.dogs.add(managedDog) realm.commitTransaction()

4-2. executeTransaction()

- 자동으로 begin/commit/cancel을 처리해줌

realm.executeTransaction { 

bgRealm ->     val managedDog = bgRealm.copyToRealm(dog)

    var person = bgRealm.createObject(Person::class.java)     person.dogs.add(managedDog)

bgRealm.copyToRealm(person) }

4-3. executeTransactionAsync()

- 비동기 트랜잭션으로, background thread에서 realm이 트랜잭션을 처리함

- UI thread의 blocking을 피하고 싶을 때 사용할 수 있음

realm.executeTransactionAsync({ // Execute bgRealm -> var managedDog = realm.copyToRealm(dog) var person = bgRealm.createObject(Person::class.java) person.dogs.add(managedDog)

bgRealm.copyToRealm(person) }, { // onSuccess realm.close() }, { // onError throwable -> realm.close(( }) }


5. Object 조회 [Reference]

- lessThan/ lessThenOrEqualTo/ greaterThan/ graterThenOrEqualTo

- equalTo/ notEqualTo 

ex) equalTo("name", "Jill") // (필드 명, 비교 값)

- in: 해당 필드의 값이 리스트의 값과 일치

ex) in("name", new String[]{"Jill", "William", "Trillian"})

- isEmpty/ isNotEmpty

- isNull/ isNotNull

val puppies: RealmResults<Dog> = realm.where(Dog::class.java).lessThan("age", 2).findAll()


6. Object 업데이트 

- 변경을 원하는 필드에 값을 set  

realm.where(Dog::class.java).equalTo("age", 2).findFirst().name = "John"


7. Realm close [Reference]

- 네이티브 메모리 해제와 파일 서술자를 다루기 위해 Closable 구현

- 하나의 스레드에서 getInstance()가 호출된 횟수만큼 close()가 호출되어야 함

- UI 스레드가 대상일 경우, onDestory()에서 close() 호출

realm.close()


8. 기타

- autoIncrement를 지원하지 않아서 직접 구현해줘야 함 [참고]

- primaryKey를 갖고있는 객체는 createObject()로 구현

Can't commit a non-existing write transaction in.. : beginTransaction() 없이 commitTransaction() 호출 시 발생

- @Ignore : 해당 필드를 제외시키고 싶을 경우 사용

- Kakao Map과 함께 사용 할 경우 추가 [참고]

android {
    //...
    packagingOptions {
        exclude "lib/arm64-v8a/librealm-jni.so"
    }
    //...
}

Failed resolution of: Lcom/google/android/gms/common/R$string; .. 발생 시, realm을 최신 버전으로 변경 [릴리즈 버전 참고]

- Object의 getter/setter 지원하지 않음 (select 시, 객체의 setter 호출X)- primaryKey를 갖고있는 객체는 createObject()로 구현

- 디버깅 시 proxy 값은 보이지만 실제 객체에는 값이 안보이는 경우 => Realm.copyToRealm 사용 

val puppies: RealmResults<Dog> = realm.where(Dog::class.java).lessThan("age", 2).findAll() // ...findAll().toList() 호출하는 경우, 값이 없음 val list = realm.copyFromRealm(puppies)


[참고 및 출처]

[Realm 내부 구조와 동작 원리 자세히 살펴보기]

[Realm Documentation]

[Kotlin과 Realm 써보기]

[Realm 의 마법을 이루는 원리, Realm Java의 바이트 코드 조작]

[Realm Naming Policy]


728x90
Comments