Realm (Java) database using the document (Writes)


Realm (Java) database using the document (directory)

And read operations differ, writes Realm must be packed in a transaction. In the write operation is finished, you can submit the transaction or cancel the transaction. The transaction will be submitted to all the changes are written to disk (if Realm is synchronized, it is queued for synchronization with the Realm Object Server). If you cancel a write transaction, all changes will be discarded. A transaction is "all or nothing": All written transaction are successful, or no one will work. This helps ensure data consistency and to provide thread safety.

// 获取一个Realm实例
Realm realm = Realm.getDefaultInstance();

realm.beginTransaction();

//... 在此处添加或更新对象 ...

realm.commitTransaction();

Or discard the changes by canceling the transaction:

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

//  ...

realm.cancelTransaction();

Write transactions block each other. If you also create a write transaction on the UI and a background thread, it may lead to ANR error. To avoid this situation, when you create a write transaction on the UI thread using asynchronous transactions .

If an exception occurs in the transaction, you will lose your changes in the transaction, but the Realm itself is not affected (or damaged). If abnormal findings and the application continues to run, you need to cancel the transaction. If you use executeTransaction , it will happen automatically.

With Realm of MVCC architecture, when opening a write transaction will not stop reading. Unless you need to carry out a transaction from multiple threads at the same time, or you can choose to work in large-scale transaction processing more fine-grained than many affairs. When you submit a transaction to write Realm, all other instances of the Realm will be notified and updated automatically .

Realm of read and write access to the ACID .

7.1 to create objects

The method createObject packaged in a write transaction.

realm.beginTransaction();
User user = realm.createObject(User.class); // 创建一个新对象
user.setName("John");
user.setEmail("[email protected]");
realm.commitTransaction();

If you create an object instance first, and then use copyToRealm add it to the Realm, then you should copy the packaging operation in a transaction. Realm support any number of custom constructor, as long as one is a common no-argument constructor can.

User user = new User("John");
user.setEmail("[email protected]");

// 将对象复制到Realm。 任何进一步的更改都必须在realmUser上发生
realm.beginTransaction();
User realmUser = realm.copyToRealm(user);
realm.commitTransaction();

Remember, the object Realm manage only returned (in this example realmUser), without management object (user) initial replication. To change the objects in the database, change the copy is returned, instead of the original copy.

If only to insert the object of interest, rather than using a managed copy immediately, you can use insert. This is copyToRealmsimilar to the way of working, but faster, because they do not return the object can be more optimized.

If you want to insert many objects, the recommended method is to use insertor insertOrUpdate.

List<User> users = Arrays.asList(new User("John"), new User("Jane"));

realm.beginTransaction();
realm.insert(users);
realm.commitTransaction();

7.2 Trading Block

You can use executeTransaction method instead of manual tracking beginTransaction,commitTransactionand cancelTransactionthe method will be processed automatically begin / commit, and canceled when an error occurs.

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

7.3 asynchronous transaction

Because the transaction is blocked by other transactions, so you may need to write on a background thread to avoid blocking the UI thread. By using asynchronous transaction, Realm will run the transaction on a background thread.

realm.executeTransactionAsync(new Realm.Transaction() {
    @Override
    public void execute(Realm bgRealm) {
        User user = bgRealm.createObject(User.class);
        user.setName("John");
        user.setEmail("[email protected]");
    }
}, new Realm.Transaction.OnSuccess() {
    @Override
    public void onSuccess() {
        // Transaction was a success.
    }
}, new Realm.Transaction.OnError() {
    @Override
    public void onError(Throwable error) {
        // Transaction failed and was automatically canceled.
    }
});

OnSuccessAnd OnErrorcallbacks are optional, but if provided, respectively, to call them when the transaction succeeds or fails. Callback by the Loopercontrol, and therefore only allows callbacks on Looper thread.

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

If you need to exit the Activity / Fragment before the transaction is completed, the RealmAsyncTask objects can cancel any transaction to be processed. If the callback update the UI, then forgot to cancel the transaction may cause the application to crash!

public void onStop () {
    if (transaction != null && !transaction.isCancelled()) {
        transaction.cancel();
    }
}

7.4 strings and updating the byte array byte arrays

Since Realm runs across the field, and therefore not directly update the individual elements of the string or byte array. Instead, you need to read the entire field of individual elements to modify, and then write it back to transaction block.

realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        bytes[] bytes = realmObject.binary;
        bytes[4] = 'a';
        realmObject.binary = bytes;
    }
});

7.5 Batch Update

If you need to update a number of objects, then the most effective way is to perform queries to find objects and use RealmResults.setX () method one, where X is the type of field you want to update.

// Updating a boolean field
realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        RealmResults<Person> persons = realm.where(Person.class).equalTo("invited", false).findAll();
        persons.setBoolean("invited", true);
    }
});

Use may also be referred to as a RealmResults.setValue(String fieldName,Object value)common set of methods, which automatically detects the type of input and performing the appropriate conversion. This is similar to DynamicRealmObject.setX()and DynamicRealmObject.setValue()behavior. Using the RealmResults.setValue()ratio of the specific type of method used to slow.

// Updating a boolean field using automatic input conversion as needed.
realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        RealmResults<Person> persons = realm.where(Person.class).equalTo("invited", false).findAll();
        persons.setValue("invited", "true"); 
    }
});

Such fields can only be updated directly on the object. Link field or list element can not use these methods to update.

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

Guess you like

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