Introduction
Realm is an Open Source mobile database, based on the ORM model and a replacement for SQLite. Realm does not use SQLite as its engine and instead it has its own C++ core. Realm stores data in a universal, table-based format by a C++ core. It is cross-platform, supporting Java (in Android only), Android 2.3 i.e. Gingerbread and above, Objective C, Swift, React Native, Xamarin.
Why Realm?
Realm is the fastest database today, with respect to performance, speed and efficiency. One should migrate to Realm because of its unique features:
1. Zero Copy
Zero Copy means it does not copy results to the cursor window by getting a list of references to the matching objects and one can work directly work with the original objects.
2. Auto Update UI
Objects in Realm are `live’ and you don’t have to re-fetch them again. It can be implemented through realm.addChangeListener
3. Works on MVCC architecture
`Writes’ does not block `Read’ operations. Thanks to MVCC architecture, i.e. Multi Version Concurrency Control, the Reader always reads another copy or version of data.
4. Uses a Fluent Interface
To construct multi-clause queries. E.g. Wealm.where(User.class).equalTo(“name”, “John”).or().equalTo(“name”, “Peter”).findAll();
5. Faster read/writes
Up to 10x speed than SQLite for normal operations.
6. No Mapping
Results do not need to be mapped to models.
7. Ease of use
Easy to learn and understand
Installation
Installing Realm as a Gradle plugin requires two steps:
Add the following class path dependency to the project level build.gradle file.
dependencies { classpath "io.realm:realm-gradle-plugin:2.2.1" }
Apply the realm-android plugin to the top of application level build.gradle.
apply plugin: 'realm-android'
Config class file
Create a class which extends the application and in it create `write’:
RealmConfiguration realmConfiguration = new RealmConfiguration.Builder(this) .name(Realm.DEFAULT_REALM_NAME) .schemaVersion(0) .deleteRealmIfMigrationNeeded() .build(); Realm.setDefaultConfiguration(realmConfiguration);
Model class file
Create a model class file for Realm. Unlike others, you need to use this model to create general Java objects too.
Supported field types are: Boolean, Byte, Short, Int, Long, Float, Double, String, Date and byte[].
Public, Private and Protected access specifiers are also supported.
public class User extends RealmObject { @PrimaryKey private String name; @Required private int age; @Ignore private int sessionId; @Index public String username
// Realm Model Class supports public, protected and private fields as well as custom methods.
// Standard getters & setters generated by your IDE…
}
Relationships
1. One to many
public class Contact extends RealmObject { private Email email; // Other fields… }
2. Many to many:
public class Contact extends RealmObject { public String name; public RealmList<Email> emails; }
public class Email extends RealmObject {
public String address;
public boolean active;
}
Writes
All write operations (adding, modifying, and removing objects) must be wrapped in write transactions.
// Obtain a Realm instance Realm realm = Realm.getDefaultInstance(); realm.beginTransaction();
//… add or update objects here …
realm.commitTransaction();
or
realm.cancelTransaction();
Creating objects
Every mutator (write, update, delete) operation should be written inside the transaction block.
Either create a new realm object by using User user = realm.createObject(User.class); and then set data to it by user.setname(“john”) or set email and use the below code, so that you can insert user object with regard to Java or finally you can also copy it to Realm.
User user = new User("John"); user.setEmail("john@corporation.com");
// Copy the object to Realm. Any further changes must happen on realmUser
realm.beginTransaction();
User realmUser = realm.copyToRealm(user);
realm.commitTransaction();
Queries
To find all users named John or Peter you would write:
No need of Transaction Blocks for queries. Objects can be accessed and queried at any time.
Realm results are ordered.Logical-And is Implicit, Logical-or must be applied explicitly with or().
Results in realm are Auto-updating. So you can provide notifications or update UI whenever realm.addChangeListener get the change.
RealmResults<User> result2 = realm.where(User.class) .equalTo("name", "John") .or() .equalTo("name", "Peter") .findAll();
This is a fluent interface most object oriented language uses to built multi-clause queries.
Deletion
// obtain the results of a query
final RealmResults<Dog> results = realm.where(Dog.class).findAll();
// All changes to data must happen in a transaction
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
// remove single match
results.deleteFirstFromRealm();
results.deleteLastFromRealm();
// remove a single object
Dog dog = results.get(5);
dog.deleteFromRealm();
// Delete all matches
results.deleteAllFromRealm();
}
});
Limitations
Passing Instances across Threads (enforces transaction version isolation).
- Updating to newer versions is slightly difficult as several things change in newer versions
- There is no support for auto-incrementing field values like ID fields
- Not many learning resources are available