Realm Blog

Realm 자바 0.83 — Null 지원!

이 버전으로 읽거나 쓴 Realm 파일은 더 이상 이전 Realm 버전에서 열 수 없습니다. 이전에 출시된 앱에 이 업데이트를 적용할 때는 주의하세요!

이 릴리즈는 가장 많은 요청을 받은 Realm 기능 널 값 지원을 포함합니다. 이 웹 사이트와 메이븐에서 Realm 자바를 받을 수 있습니다.

호환성 주의사항

이 릴리즈부터 String, Date, byte[]의 기본 값은 null이 가능합니다. (Realm 자바의 예전 버전에서는 어떤 필드도 null 값을 가질 수 없었죠.) 기존 앱들은 모델 클래스를 변경하거나 새 기능을 지원하기 위한 명시적인 이전 절차를 제공해야 합니다. 이후 내용을 더 자세히 읽어주세요.

널 값 지원을 위해 Realm 하부의 스토리지 엔진에서 파일 포맷을 변경하였습니다. 처음 Realm 파일을 열 때 Realm 파일들은 자동으로 새 파일 포맷으로 변환됩니다. 이 파일 변환은 이전은 되돌릴 수 없습니다! 이전 버전의 Realm에서 새 Realm 파일을 여는 것은 불가능합니다. 게다가 Realm 파일을 예전 파일 포맷으로 버전을 내리는 것도 불가합니다.

이전 앱들을 업그레이드하고 배포하기 전에 주의깊게 테스트하는 것을 추천합니다.

기본형 래퍼 클래스

Realm 자바 버전은 기본형(primitives)을 지원합니다. boolean, 정수형 (byte, short, int, long), 부동소수점 수 (float, double). 이 기본형 (혹은 기본형 래퍼 클래스 (primitive wrapper class, unboxed type)가 아닌 형)들은 Java에서 null을 대입할 수 없습니다. null 값을 대입할 필요가 없다면 기본형을 모델 클래스에 여전히 사용할 수 있습니다.

반면에 기본형 래퍼 클래스 (primitive wrapper class, boxed type)은 자바에서 일반적입니다. 래퍼 클래스 형의 변수와 필드에는 null을 넣을 수 있습니다.

Realm 자바는 불린형을 위한 래퍼 클래스 Boolean 정수형을 위한 Byte, Short, Integer, Long, 부동 소수점을 위한 FloatDouble를 준비합니다. 기본형 래퍼 클래스를 모델 객체에서 사용하면 필드에 null을 대입할 수 있습니다.

필드의 String, Date, byte[] 타입도 null이 될 수 있습니다. RealmListnull을 대입하는 것은 리스트가 비어있다는 의미입니다. 오브젝트들은 지워지지 않고 그것을 가리키는 레퍼런스만 제거됩니다. 게다가 RealmList 필드는 null이 될 수 없습니다. 게터는 언제나 RealmList 객체를 얻지만 리스트의 길이는 0이 됩니다.

작은 예제를 보여드리겠습니다. 아래의 모델 클래스는 두개의 integer 필드와 하나의 string 필드를 가집니다.

class Person extends RealmObject {
    String name;
    int age;
    Integer weight; // weight is not required!
}

객체를 만들고 필드의 값을 대입합시다.

Person john = realm.createObject(Person.class);
john.setName("John");
john.setAge(25);
john.setWeight(73);

Person bill = realm.createObject(Person.class);
bill.setName("Bill");
bill.setAge(41);
bill.setWeight(null);

John의 필드 3개 모두 대입한 것을 볼 수 있습니다. 반면에 Bill의 무게는 알수 없기에 null로 설정했습니다. (사실은 Person.weight의 기본값이 null이기 때문에 생략할 수 있는 부분입니다.)

새로 등장한 @Required 어노테이션

String, Date, byte[]와 기본형 래퍼 클래스의 필드 모두에 null을 대입할 수 있습니다. 위 예제에서 보였듯 가끔은 (null이 아닌) 적절한 값이 요구됩니다. null을 대입할 수 없는 필드를 지정하기 위해 새로 도입된 @Required 어노테이션을 쓸 수 있습니다. 이 어노테이션을 쓰면 Realm은 거기에 null을 대입하는 것을 허용하지 않습니다. 사람의 이름을 항상 알고 있다면 더 나은 모델은 다음과 같습니다.

class Person extends RealmObject {
    @Required
    String name;
    int age;
    Integer weight;
}

기본형 래퍼 타입 필드에 @Required을 쓰는 것도 가능합니다. Realm은 null이 아닌 값을 강제하고 저장합니다. 어노테이션은 기본형을 위서는 쓰일 수 없습니다. 기본형은 null을 가질 수 없기 때문입니다. 게다가 관계(RealmList와 단일 렘 객체들)도 @Required로 지정될 수 없습니다.

질의

@Required되지 않은 필드는 누구나 질의에 null 값을 반환할 수 있습니다. 집계하는 함수 (sum, min 등)은 계산에 null 값을 가져오지 않습니다. Realm은 모든 문자열의 시작, 끝, 중간에 null이 있을 수 있다고 가정하고 해석합니다. 아래의 질의는 모든 객체를 리턴하죠.

RealmResults<Person> persons = realm.where(Person.class).where().beginsWith("name", null).findAll();

만약에 @Required된 필드에서 null값을 질의하면 예외가 발생합니다.

마이그레이션

null 지원이 릴리즈되면서 Realm 하부의 스토리지 엔진은 자동으로 Realm 파일을 변환합니다. 스토리지 엔진이 변경되어 파일 변환이 필요합니다. null값을 모델 클래스에서 사용하지 않더라도 변환은 이루어집니다. 자동 파일 변환은 시간이 걸리고 처음에 Realm 파일에 접근하는 것은 꽤 시간이 걸릴 수 있습니다. 파일 변환이 끝나면 파일은 이전처럼 빨리 열리게 됩니다.

수동 마이그레이션을 하고 싶을 수 있습니다. 문자열, 날짜, 바이너리 (byte[]) 필드가 모델 클래스에 있는데 마이그레이션해야 합니다. 이전 버전의 Realm Java에서는 String이 null이 될 수 없었습니다. 0.83.0 버전의 Realm 자바에서는 String의 의미가 바뀌었습니다. 아래의 모델 클래스 예제를 봅시다.

class Dog {
    String name;
    int age;
}

Dog이 들어간 Realm 파일을 생성하면 name 필드는 null 대입이 안되었습니다. Realm 자바 버전 0.83.0 버전 부터는 값에 null을 허용하지 않으려면 모델 클래스를 바꿔야 합니다.

class Dog {
    @Required
    String name;
    int age;
}

만약에 모델 클래스를 바꾸고 싶지않다면 (또는 null을 사용하고 싶다면) Realm 파일을 마이그레이션 해야합니다. 이 용도로는 Table.convertColumnToNullable() 메서드를 마이그레이션 과정에 사용할 수 있습니다.

RealmMigration migration = new RealmMigration() {
    @Override
    public long execute(Realm realm, long version) {
        Table table = realm.getTable(Dog.class);
        table.convertColumnToNullable(table.getColumnIndex("name"));
        return 1;
    }
};

RealmConfiguration realmConfig = new RealmConfiguration.Builder(getContext())
    .schemaVersion(1)
    .schema(Dog.class)
    .migration(migration)
    .build();

Realm Team

Realm의 미션은 더 나은 앱을 빠르게 개발할 수 있도록 돕는 것입니다. 이를 위해 저희는 개발자들이 실시간 협업, 가상 현실, 라이브 데이터 동기화, 오프라인 경험, 메시징 등 정교하고 강력한 기능을 쉽게 개발할 수 있도록 하는 개발 도구와 플랫폼을 제공하고 있습니다.

저희는 모바일 인터넷이 수많은 사용자와 보다 많은 디바이스가 속한 개방형 네트워크와 이들 간의 실시간 상호 작용으로 진화할 것이라고 믿으며, 개발자가 이같은 방향으로 발전할 수 있도록 돕기 위해 저희 제품들을 개발하고 있습니다.

이런 개발 뉴스를 더 만나보세요