Realm (Java) database using the document (Models)


Realm (Java) database using the document (directory)

Through inheritance RealmObjectto create a model Realm base class:

public class User extends RealmObject {

    private String          name;
    private int             age;

    @Ignore
    private int             sessionId;

    // IDE生成的标准getters和setters…
    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; }
}

Realm model field supports public, protected and private modifiers and custom methods.

public class User extends RealmObject {

    public String name;

    public boolean hasLongName() {
      return name.length() > 7;
    }

    @Override
    public boolean equals(Object o) {
      // Custom equals comparison
    }
}

3.1 Field Type

Realm support boolean、byte、short、int、long、float、double、String、Dateand byte[]field types. Numeric type byte、short、intand longthe Realm are mapped long. In addition to these standard field types, Realm also supported RealmObjectand RealmList <? extends RealmObject>extended to model relationships.

Boxed Boolean、Byte、Short、Integer、Long、 Floatand Doublecan also be used in the model class. Values of these types may be null.

3.2 Required field

@RequiredAnnotations can be used in ban marks Realm field to a null value, making it a required field, rather than an optional field. Use only @Required comments Boolean、Byte、Short、Integer、Long、Float、Double、String、byte[]and Date. If you add it to the other field types, the compiler will fail.

Having a base type and RealmListfield type is not essential. RealmObjectType of field can always be empty.

3.3 Primary

Use @PrimaryKeyannotation fields are marked as primary keys model. It must be a string field type ( String) or integer ( byte, short、int、long、Byte、Short、Integerand Long). String field as the primary key index for the field automatically: the string @PrimaryKeynotes implicitly set @Indexannotation. Realm composite key is not supported, i.e., a plurality of fields as a single primary key.

Primary key can be used copyToRealmOrUpdate()or insertOrUpdate()a method. They look for objects with the given primary key, and then update it (if the object has the key already exists) or create it (if the key does not exist). If you call in the absence of a primary key class copyToRealmOrUpdate()or insertOrUpdate()an exception is thrown.

When you use a primary key, read (inquiry) will be slightly faster, but writes (create and update objects) will be slower. Change in performance will depend on the size of the data set Realm.

Please note that Realm.createObjectreturns a new object, all its fields are set to their default values. If the object is a class with a primary key, a conflict may occur (the subject has a primary key set may already exist). To avoid this, you can create an unmanaged object, set its field values, and then use copyToRealm()or insert()add it to the Realm:

final MyObject obj = new MyObject();
obj.setId(42);
obj.setName("Fish");
realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        // 在Realm中创建一个新对象,或者如果该对象已经存在(相同的主键),则抛出异常。

        // 更新具有相同主键的现有对象,或者如果没有主键的对象= 42,则创建一个新对象
        realm.copyToRealmOrUpdate(obj);
    }
});

Unless @PrimaryKeythe @Requiredcombination annotation, or Stringinteger (or type of packing Byte,Short,Integerand Long) may have a primary key nullvalue.

3.4 Properties Index

To index the field, as the primary key as the use of @Indexannotations. This will write a little slower, but will read faster. (Store the index file also makes your Realm slightly) better to add the index only when optimizing read performance for a particular situation.

Can String、byte、short、int、long、booleanand Datefields using the index.

3.5 ignore property

If you do not want to save the model in the field to the Realm, please use the comment @Ignore. For example, if you enter a field that contains more than a model, and you do not want to have to deal with a lot of special circumstances not to use these data fields, you can do so.

Marked staticand transientthe fields are always ignored, and no @Ignorecomment.

3.6 Counters Counters

Realm provided MutableRealmIntegeras a special integer type. MutableRealmInteger discloses an additional API, you can use 同步Realmsmore clearly expressed intent and generate better conflict resolution procedures.

Conventionally, will, its value is incremented by reading a counter and set it to implement ( myObj.counter + = 1). In the asynchronous case (e.g., when the two client is offline), it does not work well, because both read a value, e.g. 10, its increment, and stores the value of 11. Eventually, when the change when they regain the connection and try to merge their value, they will agree to counter located at 11 instead of the expected 12.

MutableRealmIntegersFrom the traditional integer type support, so from the field byte、short、intor the longchange MutableRealmIntegeris not required to migrate.

MutableRealmIntegerNot as primitive numeric types in Java as immutable standard. It is a real object, such as RealmObject,RealmResultsand RealmList. This means that when writing Realm, MutableRealmIntegerthe value contained within it can be changed. Therefore, you must MutableRealmIntegerfields are marked final.

public class Party extends RealmObject {
    public final MutableRealmInteger guests = MutableRealmInteger.valueOf(0);
}

To change the counter value, simply call counter.increment()or counter.decrement().

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();

To reset the counter, can be used counter.set()to assign a new value for it.

Call set () might overwrite from other devices increment () and decrement () operations. Normal last merged successfully written, and therefore only the counter in the lossy case was acceptable mixing these operations should be carried out.

Party party = realm.where(Party.class).findFirst();
realm.beginTransaction();
party.guests.set(0);
realm.commitTransaction();

3.7 covers the attribute name

The default behavior is to use the name of the model class Realm defined as the name indicates that the internal documents of the Realm classes and fields. In some cases, you may want to change this behavior:

  • Support for the same project but have not located the package in order two model classes.
  • In order to simplify the use of cross-platform architecture, as different naming conventions.
  • To limit the length of Java class names of more than 57 characters Realm mandatory use.
  • Change the field name in Java applications without forcing the user to complete the migration process.

In these cases, you may be used @RealmModule,@RealmClass, or @RealmFieldannotation that defines a different name so as to cover the name used internally.

You can module naming policy definition, this will affect all class section of module:

@RealmModule(
  allClasses = true, 
  classNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES,
  fieldNamingPolicy = RealmNamingPolicy.LOWER_CASE_WITH_UNDERSCORES
)
public class MyModule {
  
}

You can define a custom name for the class, or the class can define fields will affect all fields naming strategy. This will cover all the module level settings:

@RealmClass(name = "__Person", fieldNamingPolicy = RealmNamingPolicy.PASCAL_CASE)
public class Person extends RealmObject {
  public String name;  
}

You can define a custom name for the field, which will cover all classes and Class Module Module level settings:

public class extends RealmObject {
  @RealmField(name = "person_name") 
  public String name;  
}

Select the name of the Java class model used in different internal names have the following meanings:

  • DynamicRealm queries on must use the internal name. On ordinary Realm example query you must continue to use the name of the Java class definition.
  • When you create a class and field, migration must use the internal name.
  • Report errors architecture will use the internal name.

Please note that the name change will not affect the internal imported from JSON data. JSON data still must follow the name of the Realm Java class definition.

When using the standard library Moshi, GSON Jackson or the like parsing JSON, be sure to remember that these libraries define the conversion from JSON to Java, and set up internal Realm name also defines the transition from Java to the Realm of the file. This means that if you want to use these libraries to import data into Realm from JSON, you still need to provide JSON parser library and Realm comments.

Use Moshi, it looks like this:

public class Person extends RealmObject {
    @Json(name = "first_name") // JSON输入中使用的名称。
    @RealmField(name = "first_name") // Realm文件内部使用的名称。
    public string firstName; // Java中使用的名称
}

For more information, see RealmNamingPolicy .

Published 59 original articles · won praise 88 · views 190 000 +

Guess you like

Origin blog.csdn.net/geofferysun/article/details/105058508