Model 생성
RealmObject를 상속하여 Model 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class User extends RealmObject { private String name; private int age; @Ignore private int sessionId; // 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 sessionId) { this.sessionId = sessionId; } } | cs |
private, public, protected 필드와 커스텀 메소드를 지원합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | public class User extends RealmObject { public String name; public boolean hasLongName() { return name.length() > 7; } @Override public boolean equals(Object o) { // Custom equals comparison } } | cs |
Field 타입
boolean, byte, short, int, long, float, double, String, Date, byte[]을 지원합니다.
byte, short, int, long은 모두 Realm 내에서 long으로 매핑됩니다.
RealmObject, RealmList<? extends RealmObject>를 지원합니다.
Boolean, Byte, Short, Integer, Long, Float, Double도 사용할 수 있습니다. 박스형은 null 값을 가질 수 있습니다.
@Required
Null 값을 허용하지 않도록 합니다.
Boolean, Byte, Short, Integer, Long, Float, Double, String, byte[], Date에만 사용할 수 있습니다.
기본형과 RealmList는 암묵적으로 Required로 취급합니다.
RealmObject는 항상 null이 가능합니다.
@Index
쓰기가 약간 느려지지만 읽기가 빨라집니다.
Index를 저장하기 위해 Realm 파일을 약간 크게 만듭니다.
읽기 성능을 최적화 할 때만 추가하는 것이 가장 좋습니다.
String, byte, short, int, long, boolean, Date에 사용할 수 있습니다.
@PrimaryKey
String, byte, short, int, long, Byte, Short, Integer, Long에만 사용할 수 있습니다.
String에 @PrimaryKey를 사용하면 암묵적으로 @Index를 설정합니다.
여러 필드를 @PrimaryKey로 설정할 수 없습니다.
기본키를 사용하면 copyToRealmOrUpdate 또는 insertOrUpdate 메소드를 사용할 수 있습니다.
쓰기가 약간 느려지지만 읽기가 약간 빨라집니다.
Realm.createObject는 모든 필드가 기본값으로 설정된 객체를 생성하기 때문에,
기본키가 있는 클래스인 경우 충돌을 방지하기 위해서
객체를 미리 만들고 필드 값을 설정한 후에 copyToRealm 또는 insert 합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | final MyObject obj = new MyObject(); obj.setId(42); obj.setName("Fish"); realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { // 새 객체를 만들거나, 객체가 이미 있는 경우(동일한 기본키) 예외를 발생 realm.copyToRealm(obj); // 동일한 기본키로 이미 존재하는 객체를 업데이트 하거나, // 기본키가 42인 객체가 없으면 새 객체를 생성 realm.copyToRealmOrUpdate(obj); } }); | cs |
@Required와 결합하지 않으면 String이나 박스형 필드는 기본키가 null값을 가질 수 있습니다.
@Ignore
Realm에 필드를 저장하고 싶지 않을 때 사용합니다.
입력하는 필드가 모델의 필드보다 많을 때나, 사용되지 않는 필드에 사용합니다.
static, transient은 항상 @Ignore로 설정됩니다.
Counter
Realm은 MutableRealmInteger를 특별한 정수형으로 제공합니다.
Traditionally, a counter would be implemented by reading a value, incrementing it and setting it (myObj.counter += 1). This will not work well in an asynchronous situation — for example when two clients are offline — because both parties will read a value, say 10, increment it, and store the value as 11. Eventually, when they regain connectivity and try to merge their changes, they’ll agree that the counter is at 11 rather than the expected 12.
MutableRealmIntegers are backed by traditional integer types, so no migration is required when changing a field from byte, short, int or long to MutableRealmInteger.
MutableRealmInteger is not an immutable type standard like primitive number types in Java. It is a live object like RealmObject, RealmResults and RealmList. This means the value contained inside the MutableRealmInteger can change when a Realm is written to. For this reason MutableRealmInteger fields must be marked final.
1 2 3 4 | public class Party extends RealmObject { { public final MutableRealmInteger guests = MutableRealmInteger.valueOf(0); } | cs |
To change the counter value, simply call counter.increment() or counter.decrement().
1 2 3 4 5 6 7 8 | Party party = realm.where(Party.class).findFirst(); realm.beginTransaction(); party.guests.get(); // 0 party.guests.increment(1); // 1 party.guests.decrement(1); // 0 party.guests.increment(5); // 5 party.guests.decrement(1); // 4 realm.commitTransaction(); | cs |
To reset the counter, you can assign it a new value using counter.set().
Calling set() can potentially override increment() and decrement() operations coming from other devices pr. the normal last-write-wins merge rules, so mixin these operations should only be done if lossy counters are acceptable.
1 2 3 4 | Party party = realm.where(Party.class).findFirst(); realm.beginTransaction(); party.guests.set(0); realm.commitTransaction(); | cs |
Overriding property names
The default behaviour is that Realm will use the name defined in the Java model class as the name to represent classes and fields internally in the Realm file. In some cases you might want to change this behaviour:
To support two model classes with the same simple name but in different packages.
To make it easier to work with cross platform schemas as naming conventions are different.
To use a Java class name that is longer than the 57 character limit enforced by Realm.
To change a field name in Java without forcing app users through a migration process.
In those cases you can override the name being used internally by defining a different name using the @RealmModule, @RealmClass or @RealmField annotations.
You can define a naming policy at the module level, which will affect all classes part of the module:
1 2 3 4 5 6 7 8 | @RealmModule( allClasses = true, classNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES, fieldNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES ) public class MyModule { } | cs |
You can define a custom name for the class or a field naming policy that will effect all fields in that class. This will override any module level settings:
1 2 3 4 | @RealmClass(name = "__Person", fieldNamingPolicy = RealmNamingPolicy.PASCAL_CASE) public class Person extends RealmObject { public String name; } | cs |
You can define a custom name for a field, this will override any Class and Module level settings:
1 2 3 4 | public class extends RealmObject { @RealmField(name = "person_name") public String name; } | cs |
Choosing an internal name that differs from the name used in the Java model classes has the following implications:
Queries on a DynamicRealm must use the internal name. Queries on normal Realm instances must continue to use the name as it is defined in the Java class.
Migrations must use the internal name when creating classes and fields.
Schema errors reported will use the internal names.
Note that changing the internal name does NOT affect importing data from JSON. The JSON data must still follow the names as defined in the Realm Java class.
When it comes to parsing JSON using standard libraries like Moshi, GSON or Jackson. Then it is important to remember that these libraries define the transformation from JSON to Java while setting the internal Realm names define the transformation from Java to the Realm file. This means that if you want to import data into Realm from JSON using these libraries you still need to provide the annotations from both the JSON parser library and Realm.
Using Moshi, it would look something like this:
1 2 3 4 5 | public class Person extends RealmObject { @Json(name = "first_name") // Name used in JSON input. @RealmField(name = "first_name") // Name used internally in the Realm file. public string firstName; // name used in Java } | cs |
출처
https://realm.io/docs/java/latest#models
'Android > Realm' 카테고리의 다른 글
[안드로이드 Realm] Realm에 대하여 (0) | 2019.05.17 |
---|---|
[안드로이드 Realm] Realm 시작하기 (0) | 2019.05.17 |