realm @android

24
NHN NEXT 차용빈 BabyMoment Team Study Realm

Upload: -

Post on 13-Aug-2015

465 views

Category:

Software


2 download

TRANSCRIPT

NHN����������� ������������������  NEXT����������� ������������������  ����������� ������������������  차용빈

BabyMoment����������� ������������������  Team����������� ������������������  Study

Realm

: Android & iOS 를 위한 데이터베이스

Realm

Realm

• 모바일 SQLite을 대신할 새로운 데이터베이스

• 모바일을 위한 디자인

• 객체/모델-지향 (ORM은 아님)

• ACID 지원

• Thread Model 지원

Realm

Realm 설치하기 (Android Studio)

Maven

1. 의존 저장소로 jcenter를 사용하는지 확인

repositories { jcenter() }

Realm

Realm 설치하기 (Android Studio)

Maven

2. 프로젝트 의존성 부분에 아래의 내용 추가

dependencies { compile ‘io.realm:realm-android:0.81.1’

}

Realm

Realm 데이터 모델Realm 데이터 모델은 Java Bean 모델을 따름 RealmObject를 상속하고 Realm 주석 프로세서가 프록시 클래스를 생성

public class User extends RealmObject {

@PrimaryKey private String name; private int age;

@Ignore private int sessionId;

기본키: 필드 타입이 문자열이거나 정수(short, int, long)이어야 함 여러 필드(혼합 키)를 기본 키로 사용할 수는 없음

속성 무시: 필드가 디스크에 저장되지 않도록 할 수 있음

Realm

Realm 데이터 모델

// Standard getters & setters generated by your IDE… public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getSessionId() { return sessionId; } public void setSessionId(int dontPersist) { this.sessionId = sessionId; } }

Realm

Realm 데이터 쓰기모든 쓰기 오퍼레이션(추가, 수정, 삭제)은 반드시 쓰기 트랜잭션 내에서 이루어져야 함.

// Obtain a Realm instance Realm realm = Realm.getInstance(this);

realm.beginTransaction(); User user = realm.createObject(User.class); user.setName("John"); user.setEmail("[email protected]"); realm.commitTransaction();

객체 생성

Realm

Realm 데이터 쓰기객체를 커밋하는 대신에 되돌릴려면 쓰기 트랜잭션을 간단하게 취소할 수 있음.

realm.beginTransaction(); User user = realm.createObject(User.class);

// ...

realm.cancelTransaction();

Realm

Realm 데이터 쓰기수동으로 realm.beginTransaction(), realm.commitTransaction(),

realm.cancelTransaction()을 관리하는 대신에 자동으로 begin/commit을

관리하고 에러가 발생했을 때 cancel 하도록 지원

realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { User user = realm.createObject(User.class); user.setName("John"); user.setEmail("[email protected]"); } });

(트랜잭션 블록)

Realm

Realm 쿼리John 혹은 Peter라는 이름을 가진 모든 사용자를 쿼리하기 위해서는

// Build the query looking at all users: RealmQuery<User> query = realm.where(User.class);

// Add query conditions: query.equalTo("name", "John"); query.or().equalTo("name", "Peter");

// Execute the query: RealmResults<User> result1 = query.findAll();

Realm

Realm 쿼리Fluent interface를 사용

RealmResults<User> result2 = realm.where(User.class) .equalTo("name", "John") .or() .equalTo("name", "Peter") .findAll();

Realm

Realm 쿼리Realm 쿼리는 다음과 같은 쿼리를 지원합니다.

• 조건 • 수식어 • 논리 연산자 • 정렬

• 연속 쿼리 • 집합 • 이터레이션 • 삭제

Realm

Realm 객체 닫기

Realm을 사용한 후 Realm 객체를 닫는게 중요

Realm 인스턴스는 레퍼런스 카운팅됩니다. 하나의 쓰레드에서

getInstance()를 두 번 호출하면 사용이 끝난 후 close()도 두 번 호출해야

합니다. 어떠한 쓰레드가 실행될지 걱정없이 Runnable 클래스를 구현하면

됩니다. 간단하게 getInstance()로 시작해서 close()로 끝냅니다

Realm

Realm 객체 닫기UI 쓰레드를 대상으로 한다면 onDestroy() 메소드에서 realm.close()을 호

출하고, AsyncTask를 대상으로 하면 아래의 패턴이 좋음.

protected Long doInBackground(Context... contexts) { Realm realm = null; try { realm = Realm.getInstance(contexts[0]);

// ... Use the Realm instance } finally { if (realm != null) { realm.close(); } } }

Realm

Realm 관계Realm에서 관계는 대부분 속도 면에서 부담이 없고 관계를 표현하는 내부

구현은 메모리 사용에 상당히 효율적임.

public class Email extends RealmObject { private String address; private boolean active; // ... setters and getters left out } public class Contact extends RealmObject { private String name; private Email email; // ... setters and getters left out }

Realm

Realm 관계

N : 1 관계

public class Contact extends RealmObject { private Email email; // Other fields… }

각 contact는 0 혹은 1 개의 email(Email 인스턴스)을 갖습니다.

보통 이러한 구현은 1 : 1 관계가 일반적입니다.

Realm

Realm 관계

N : N 관계

public class Contact extends RealmObject { private RealmList<Email> emails; // Other fields… }

RealmList는 기본적으로 RealmObject의 컨테이너이고 Java의 List와 유

사합니다. 서로 다른 RealmList 동일한 객체를 두 번(혹은 이상) 사용할 수

있습니다

Realm

Realm JSONJSON JSONObject으로 표현되거나 String InputStream으로 표현된 데이

터를 직접적으로 RealmObject로 추가할 수 있음.

// Insert from a string realm.beginTransaction(); realm.createObjectFromJson(City.class, "{ city: \"Copenhagen\", id: 1 }"); realm.commitTransaction();

// Insert multiple items using a InputStream InputStream is = new FileInputStream(new File("path_to_file")); realm.beginTransaction(); try { realm.createAllFromJson(City.class, is); realm.commitTransaction(); } catch (IOException e) { realm.cancelTransaction(); }

Realm

Realm NotificationListener를 추가해서 사용하는 UI 혹은 다른 쓰레드가 Realm이 변경될 때

감지할 수 있음.

realm.addChangeListener(new RealmChangeListener() { @Override public void onChange() { // ... do something with the updates (UI, etc.) ... } });

Realm

Realm 암호화Realm 파일은 512-bit 암호화 키를 Realm.getInstance() 호출에 전달하여

암호화된 상태로 저장

byte[] key = new byte[64]; new SecureRandom().nextBytes(key); Realm realm = Realm.getInstance(this, key);

// ... use the Realm as normal ...

이 기능을 통해 디스크의 모든 데이터를 AES-256 암호화를 사용하여 쉽게

암호화, 복호화할 수 있음.

Realm

Realm GSONGson gson = new GsonBuilder() .setExclusionStrategies(new ExclusionStrategy() { @Override public boolean shouldSkipField(FieldAttributes f) { return f.getDeclaringClass().equals(RealmObject.class); }

@Override public boolean shouldSkipClass(Class<?> clazz) { return false; } }) .create();

String json = "{ name : 'John', email : '[email protected]' }"; User user = gson.fromJson(json, User.class);

Realm

Realm RetrofitRetrofit은 내부적으로 GSON을 사용하므로 JSON 데이터에서

RealmObject로 역직렬화할 필요성이 있다면 GsonConverter 설정

(앞 슬라이드에서의 Gson 설정 후 아래 설정 내용 추가)

RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint("https://api.github.com") .setConverter(new GsonConverter(gson)) .build();

GitHubService service = restAdapter.create(GitHubService.class);

Realm

Realm RetrofitRetrofit은 자동적으로 객체를 Realm에 추가하지 않으며 수동으로

realm.copyToRealm() 메소드를 사용해서 추가해야 함.

GitHubService service = restAdapter.create(GitHubService.class); List<Repo> repos = service.listRepos("octocat");

// Copy elements from Retrofit to Realm to persist them. realm.beginTransaction(); List<Repo> realmRepos = realm.copyToRealm(repos); realm.commitTransaction();