04 realm 더 자세히

23
0 Realm Realm - 더 자세히 Made by 이종찬

Transcript of 04 realm 더 자세히

Page 1: 04   realm 더 자세히

0

RealmRealm - 더 자세히

Made by 이종찬

Page 2: 04   realm 더 자세히

1

01RealmConfiguration

Page 3: 04   realm 더 자세히

2

01 RealmConfigurationRealm을 설정하기 위해 사용하는 RealmConfiguration 객체에 대해서 알아보자.

1. Realm 데이터베이스 파일의 위치, 이름, 스키마버전 등을설정하기 위해 사용하는 객체

2. RealmConfiguration 객체에 realm 에 대한 설정을 먼저 한 후Realm 객체를 생성한다.

3. RealmConfiguration 객체는 빌더 패턴에 의해 생성된다.4. 여러 개의 RealmConfiguration 객체를 쓰는 것도 가능하다.

1 RealmConfiguration 생성하기

RealmConfiguration config = new RealmConfiguration.Builder(context).build();// 최소한의 설정만 할 때 사용. 파일의 이름은 default.realm 으로 들어간다.

RealmConfiguration config = new RealmConfiguration.Builder(context).name("myrealm.realm").encryptionKey(getKey()).schemaVersion(42).modules(new MySchemaModule()).migration(new MyMigration()).build();

// Realm 파일은 Context.getFilesDir()에 위치하면 이름은 "myrealm.realm"입니다.

Page 4: 04   realm 더 자세히

3

빌더 패턴 (builder pattern)

1. 복합 객체의 생성 과정과 표현 방법을 분리하여 동일한 생성 절차에서서로 다른 표현 결과를 만들 수 있게 하는 패턴이다.

2. 합성할 객체들의 표현이 서로 다르더라도 생성 절차에서이를 지원해야할 때 사용한다.

3. 조건에 따라서 각각 다른 빌더 클래스를 이용, 다른 연산을 수행하고객체를 생성하는 부분과 세부 알고리즘을 분리하는 패턴이다.

Realm에 적용된 이유를 알아보자. ( * 주의 : 단순 제 생각 입니다. * )

RealmConfiguration을 통해 Realm을 설정할 때 사용자 마다 다양한 설정값을줄 수 있다. (이름만 주거나, 스키마버전만 주거나 등등)

이 때 각각에 대한 설정을 좀더 쉽게 구성하게 해주는 패턴이빌더 패턴이기에 Realm에서는 RealmConfiguration의 생성을Builder 패턴으로 했을거라고 판단된다.

Page 5: 04   realm 더 자세히

4

Realm을 설정하기 위해 사용하는 RealmConfiguration 객체에 대해서 알아보자.

2 Realm 인스턴스 얻기

RealmConfiguration config = new RealmConfiguration.Builder(context).build();// 최소한의 설정만 할 때 사용. 파일의 이름은 default.realm 으로 들어간다.

RealmConfiguration config = new RealmConfiguration.Builder(context).name("myrealm.realm").encryptionKey(getKey()).schemaVersion(42).modules(new MySchemaModule()).migration(new MyMigration()).build();

// Realm 파일은 Context.getFilesDir()에 위치하면 이름은 "myrealm.realm"입니다.

Realm realm = Realm.getInstance(config); // 설정을 사용합니다.

1. 생성했던 RealmConfiguration 객체를 사용하여 Realm인스턴스를 얻는다.2. Realm인스턴스는 싱글톤 패턴으로 생성된다. 그렇기 때문에매 스레드마다 정적 생성자는 동일한 인스턴스를 반환한다.

01 RealmConfiguration

Page 6: 04   realm 더 자세히

5

싱글톤 패턴 (singleton pattern)

1. 객체가 단 하나면 충분하다고 판단 될 때 사용하는 패턴이다.2. 자바의 static 키워드를 사용하며 메모리 관리면에서 효율적인 패턴이다.

public class Singleton {private static Singleton singleton = new Singleton();

private Singleton() { } //private로 선언이 되어있기 때문에 사용할 수 없다.

public static Singleton getInstance(){return singleton;

} //getInstance를 사용해서만 객체를 얻어올 수 있다.}

Singleton s1 = Singleton.getInstance();Singleton s2 = Singleton.getInstance();System.out.println( s1 == s2 ); //true가 반환된다.

3. 생성자는 private로 선언하여 사용 할 수 없도록 한다.4. 객체의 생성은 한 번만 하고 같은 객체만을 반환하기 때문에객체는 항상 하나만 생성되어 있다.

Page 7: 04   realm 더 자세히

6

싱글톤 패턴 (singleton pattern)

Realm에 적용된 이유를 알아보자. ( * 주의 : 단순 제 생각 입니다. * )

Thread 1A Realm 객체1

Thread 2A Realm 객체2

쓰기 중

쓰기 불가능

1. 2개의 쓰레드에 동일한 realm A에 대한 객체가 2개가 각각 존재한다고 하자.2. Thread1 에서 쓰기를 작업 중이면 Transaction에 의해 Thread2는

쓰기 작업을 할 수가 없다.3. Thread1 의 쓰기 작업이 끝났을 때 Thread2가 쓰기 작업을 할 수 있다. Thread1과 Thread2는 같은 Realm을 사용하기 때문에 한 번에 하나씩만쓰기 작업이 가능하다. 객체를 두 개 가지고 있는 것은 메모리 낭비이다.

메인 메모리 디스크

A Realm

Page 8: 04   realm 더 자세히

7

싱글톤 패턴 (singleton pattern)

Realm에 적용된 이유를 알아보자. ( * 주의 : 단순 제 생각 입니다. * )

Thread 1

Thread 2

쓰기 중

쓰기 불가능

1. 메인 메모리 상에 singleton 패턴을 이용하여 Realm을 객체화 시켜둔다.2. 각 쓰레드에서는 A Realm에 대한 객체를 생성하지 않고 singleton에서

생성한 객체를 참조만 하고 있는다.3. 쓰기는 Transaction에 의해 하나 씩만 가능하므로 문제가 생기지 않는다. 메모리 관리면에서 훨씬 효율적이다.

메인 메모리

디스크

A Realm

A Realm 객체(singleton)

Page 9: 04   realm 더 자세히

8

Realm을 설정하기 위해 사용하는 RealmConfiguration 객체에 대해서 알아보자.

3 여러 개의 RealmConfiguration 쓰기

RealmConfiguration myConfig = new RealmConfiguration.Builder(context).name("myrealm.realm").schemaVersion(2).setModules(new MyCustomSchema()).build();

RealmConfiguration otherConfig = new RealmConfiguration.Builder(context).name("otherrealm.realm").schemaVersion(5).setModules(new MyOtherSchema()).build();

Realm myRealm = Realm.getInstance(myConfig);Realm otherRealm = Realm.getInstance(otherConfig);

1. 여러 개의 Realm파일을 만들고 싶을 때는 여러 개의 Configuration을사용하면 된다.

2. 이런 방법에서는 각 설정값을 Realm마다 독립적으로 제어할 수 있다.

01 RealmConfiguration

Page 10: 04   realm 더 자세히

9

Realm을 설정하기 위해 사용하는 RealmConfiguration 객체에 대해서 알아보자.

4 DefaultConfiguration으로 저장

public class MyApplication extends Application {@Overridepublic void onCreate() {

super.onCreate();// Context.getFilesDir()에 "default.realm"란 이름으로 Realm 파일이 위치한다RealmConfiguration config = new RealmConfiguration.Builder(this).build();Realm.setDefaultConfiguration(config);

}}public class MyActivity extends Activity {

@Overrideprotected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);Realm realm = Realm.getDefaultInstance();// ... 무엇을 합니다 ... realm.close();

}}

1. 커스텀 Application 클래스에 기본 설정을 넣으면다른 클래스에서 사용이 가능하다.

01 RealmConfiguration

Page 11: 04   realm 더 자세히

10

01Realm

Page 12: 04   realm 더 자세히

11

02 RealmAndroid에서 Realm을 사용하는 법을 알아보자.

1. 저번에 했잖아…?01 주차에서 알아본 Realm은 Realm 자체에 대해서 간단히알아본 것이고 이번에는 Android에서 Realm 파일은어떻게 생성하고 사용하는 방법을 자세히 알아볼 것이다.

2. 제일 먼저 했어야 하는 것이 아닌가…?realm 문서상 순서가 밑에 있어서 이제 합니다………

Page 13: 04   realm 더 자세히

12

02 Realm의 종류Realm을 종류 중 가장 기본이 되는 Realm이다.

기본 Realm

RealmConfiguration myConfig = new RealmConfiguration.Builder(context).name("myrealm.realm").build();

Realm myRealm = Realm.getInstance(myConfig);

1. 디스크에 저장되는 가장 기본적인 데이터베이스2. 앞에서 봤던 것 처럼 RealmConfiguration을 설정한 후 객체를 얻어온다.3. 사용법은 그 동안 어느정도 봐왔다.

Page 14: 04   realm 더 자세히

13

02 Realm의 종류메인 메모리에 저장하는 Realm에 대해서 알아보자.

In-memoryRealm

RealmConfiguration myConfig = new RealmConfiguration.Builder(context).name("myrealm.realm").inMemory().build();

Realm myRealm = Realm.getInstance(myConfig);

1. 디스크에 저장하지 않는 인 메모리 Realm이 생성할 수 있다.2. 메모리가 부족하면 디스크를 이용하기는 한다.3. 모든 파일들은 메모리 상에서 생성되고 Realm이 닫히면 삭제된다.4. 디스크에 있는 Realm고 같은 이름의 인 메모리 Realm은 허용되지 않는다.5. 인 메모리 Realm 인스턴스는 어떤 레퍼런스도 가리키지 않을 때

Realm의 모든 데이터를 해제한다.

경우에 따라서는 Serialize나 Parcelable보다 빠른 속도를 낼 수 있을 것으로생각 됩니다. ( 이것 외에는 쓰는 이유를 잘 모르겠습니다. )

Page 15: 04   realm 더 자세히

14

02 Realm의 종류Dynamic Realm에 대해서 알아보자.

DynamicRealm

RealmConfiguration realmConfig = new RealmConfiguration.Builder(context).build();DynamicRealm realm = DynamicRealm.getInstance(realmConfig);// DynamicRealm에서 모든 객체들은 DynamicRealmObjects입니다DynamicRealmObject person = realm.createObject("Person");

// 모든 필드는 문자열로 접근가능합니다.String name = person.getString("name");int age = person.getInt("age");

// 하부의 스키마는 존재하기에 존재하지 않는 필드에 예외를 발생시킵니다person.getString("I don't exist");

// 질의는 여전히 평범하게 동작합니다RealmResults<DynamicRealmObject> persons = realm.where("Person")

.equalTo("name", "John").findAll();

1. Realm을 사용할 때 모델 클래스는 RealmObject의 서브클래스로 정의하여사용한다. 이때 형 안정성에 많은 이점이 있지만 어떤 경우에는 컴파일시점에서 사용이 가능하지 않을 수 있다. 이때 Dynamic Realm을 사용한다.

2. Dynamic Realm은 DynamicRealmObject라는 클래스로 사용하며 모든 필드에대한 접근을 클래스 대신 문자열을 통해 접근한다.

3. Dynamic Realm은 스키마, 마이그레이션, 스키마 버전은 무시한다.4. Dynamic Realm은 안정성과 성능을 포기하고 유연성을 선택하였다.때문에 정말로 유연성이 필요할 때만 사용하는 것을 권장한다.

Page 16: 04   realm 더 자세히

15

03Realm의 사용

Page 17: 04   realm 더 자세히

16

03 Realm의 사용사용을 완료한 Realm 객체를 어떻게 처리하는 방법을 알아보자.

Realm 객체 닫기

1. Realm은 네이티브 메모리 해제와 파일 서술자를 다루기 위해 Closeable을구현한다. 때문에 Realm을 사용한 후 Realm 객체를 닫는 것은 중요하다.

2. Realm 인스턴스는 레퍼런스 카운팅이 된다. 즉 하나의 쓰레드에서getInstance()를 두 번 호출하면 사용이 끝난 후 close()도 두 번 호출해야 한다.

Closeable – java interface1. 자바에서 파일을 다룰 때 사용하는 것으로 판단된다. 파일을 사용하는 객체는claseable이 구현되어 있어 사용을 다 한 후에는 close()를 호출해야 되는 것 같다.

2. Try – catch – finally 문에서 실행되며 자바 7이전 버전에서는 수동으로close()를 호출해 줘야 했다.

3. 자바 7 버전 부터는 try-with-resources 문이 추가되어 자동으로 수동으로close()를 호출하는 작업을 해줄 필요가 없어졌다.

Page 18: 04   realm 더 자세히

17

03 Realm의 사용사용을 완료한 Realm 객체를 어떻게 처리하는 방법을 알아보자.

Realm 객체 닫기

1 UI 쓰레드에서 닫기

1. UI 쓰레드에서는 onDestory()에서 realm.close()를 호출하는 것이 간단하다.

2 Try-with-resource 사용하기

// minSdkVersion >= 19 이상이며 Java >= 7 인 앱에서만 가능하다.try (Realm realm = Realm.getDefaultInstance()) {

// 수동으로 Realm 인스턴스를 닫을 필요가 없습니다}

Page 19: 04   realm 더 자세히

18

03 Realm의 사용사용을 완료한 Realm 객체를 어떻게 처리하는 방법을 알아보자.

Realm 객체 닫기

Looper 쓰레드에서 닫기

public class MyThread extends Thread {private Realm realm;@Overridepublic void run() {

Looper.prepare();try {

realm = Realm.getDefaultInstance();// ... Realm 인스턴스를 사용합니다 ...Lopper.loop();

} finally {if (realm != null)

realm.close();}

}}

3

Page 20: 04   realm 더 자세히

19

03 Realm의 사용사용을 완료한 Realm 객체를 어떻게 처리하는 방법을 알아보자.

Realm 객체 닫기

4 AsyncTask에서 닫기

protected Void doInBackground(Void... params) {Realm realm = null;try {

realm = Realm.getDefaultInstance();// ... Realm 인스턴스를 사용합니다 ...

} finally {if (realm != null)

realm.close();}return null;

}

Page 21: 04   realm 더 자세히

20

03 Realm의 사용사용을 완료한 Realm 객체를 어떻게 처리하는 방법을 알아보자.

Realm 객체 닫기

5 짧게 사용하고 닫기(Thread나 Runnable)

// Realm 인스턴스와 비 Looper 스레드를 실행합니다.Thread thread = new Thread(new Runnable() {

@Overridepublic void run() {

Realm realm = null;try {

realm = Realm.getDefaultInstance();// ... Realm 인스턴스를 사용합니다 ...

} finally {if (realm != null)

realm.close();}

}});

thread.start();

Page 22: 04   realm 더 자세히

21

03 Realm의 사용Realm 파일을 찾는 법을 알아보자.

Realm 파일 찾기

1 Realm 브라우저 사용

1. 현재 Realm 브라우저는 맥OS 에서만 지원되며 다른 운영체제에서는지원되지 않고 있다.

2. Realm 브라우저를 사용하여 Realm 데이터베이스를 읽고 수정이 가능하다.3. 하지만 현재 브라우저는 디바이스에 직접적인 접근을 하지 못한다.4. 때문에 디바이스에서 데이터베이스를 복사를 하여 접근해야한다.

Page 23: 04   realm 더 자세히

22

감사합니다.

정보 출처 : realm.ioppt템플릿 : 홍양홍삼님 블로그