Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Introduction to Realm Database

DZone's Guide to

Introduction to Realm Database

We are going to build a very simple application using Realm database. It is going to be an Android app.

· Database Zone ·
Free Resource

Databases are better when they can run themselves. CockroachDB is a SQL database that automates scaling and recovery. Check it out here.

Nowadays, we have a lot of options when deciding to choose a database solution. We have different attractive options, each of which has its strengths and weaknesses. One I have found to be outstanding is Realm database. Realm database can be used by Android, IOS, React, and even Xamarin developers.

What Realm

Most applications today will need some sort of persistent data, and sorting that out usually involves making the application more complex and adds more lines of code. Many engineering organizations are all too familiar with the pain of increased development complexity that results in longer cycles, overburdened resources, and an unwieldy code base. Realm, alongside other new database solutions, is solving this issue of complexity.

Realm simplifies your application architecture while giving you very powerful features. The Realm Platform is actually made up of two major components. The Realm Database and the Realm Object Server. According to the official documentation, these two components work in conjunction to automatically synchronize data enabling a lot of use cases ranging from offline apps to complex backend integrations. I am not going to cover the Realm Object Server in this article, therefore, you can read more about the Realm Object Server here.

One of the key factors that makes Realm so special is the fact that it was built for our modern mobile development demands, and a lot of the solutions we used were not actually designed for phones, tablets, or wearables:
Mountain View

For a very long time, SQLite has been our main choice for persistence on mobile, and even if it is not used directly, it is used by many libraries that provides a convenience wrapper around it such as Couchbase Lite, Core Data, ORMLite, etc.

Realm also boasts of speed. According to the documentation, Realm is faster than even raw SQLite on common operations, while maintaining an extremely rich feature set.



Realm is also simple to use. Here are some sample codes of how basic Realm transactions would look:

For Java:

public class Dog extends RealmObject {
  public String name;
  public int age;
}

Dog dog = new Dog();
dog.name = "Rex";
dog.age = 1;

Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
realm.copyToRealm(dog)
realm.commitTransaction();

RealmResults<Dog> pups = realm.where(Dog.class)
                               .lessThan("age", 2)
                               .findAll();


For Swift:

class Dog: Object {
  @objc dynamic var name = ""
  @objc dynamic var age = 0
}

let dog = Dog()
dog.name = "Rex"
dog.age = 1

let realm = try! Realm()
try! realm.write {
  realm.add(dog)
}

let pups = realm.objects(Dog.self).filter("age < 2")


For Javascript:

class Dog {}

Dog.schema = {
  name: 'Dog',
  properties: {
    name: 'string',
    age: 'int',
  }
};

let realm = new Realm();
realm.write(() => {
  realm.create('Dog', {name: 'Rex', age: 1});
});

let pups = realm.objects('Dog').filtered('age < 2');


For Xamarin (C#):

public class Dog : RealmObject 
{
  public string Name { get; set; }
  public int Age { get; set; }
}

var realm = Realm.GetInstance();
realm.Write(() => 
{
  realm.Add(new Dog
  {
    Name = "Rex",
    Age = 1
  });
});

var pups = realm.All<Dog>().Where(d => d.Age < 2);

Getting Started

We are going to build a very simple application using Realm database. It is going to be an Android app. I will try to make it as simple as I can so anyone can relate to it and implement it on whatever platform they wish.

The app we are going to make just does basic database operations, and this is just to give you an overview of what to expect when working with Realm.

We have an Edittext view for the name and age of a user to be inserted into the database. Then, below those is an add button, which inserts the user's name and age into the database. There is also the filter button, which queries the database for specific users.

Mountain View

First Step

Add the classpath dependency to the project level build.gradle file.

buildscript {

    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'

        classpath "io.realm:realm-gradle-plugin:5.1.0" //todo (1) add realm dependency

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}


Second step

Apply the realm-android plugin to the top of the application level build.gradle file.

apply plugin: 'com.android.application'

apply plugin: 'realm-android' //todo (2) add realm plugin

android {
    compileSdkVersion 27
    defaultConfig {
...

Define Model Class

Define your model class by extending RealmObject. It is similar to your everyday POJO classes.

import io.realm.RealmObject;

//todo (3) Define your model class by extending RealmObject
public class User extends RealmObject{
    private String name;
    private int age;

    public User() {
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}


Initialize Realm

To get started, you will need to initialize Realm, this is needed just once per application, so a good place to do this is in onCreate.


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        //todo (4) Initialize Realm (just once per application)
        Realm.init(this);

        //todo (5) Get a Realm instance for this thread
        Realm realm = Realm.getDefaultInstance();
...

Writes

So now all is set and ready. The next step is to add a new user with a name and age. They are added by clicking the 'ADD' button as shown in the diagram above. The ID's for the Edittext views name, age are name_txt and age_txt respectively, while the ID for the button is add_btn.


   add_btn.setOnClickListener(v -> {
            // write operations in Realm must be wrapped in transactions.
            realm.beginTransaction();
            User user = realm.createObject(User.class); //todo  Create a new object
            user.setName(name_txt.getText().toString()); //todo get user name from Edittext and store in user object
            user.setAge(Integer.valueOf(age_txt.getText().toString())); //todo get user age from Edittext and store in user object
            realm.commitTransaction();
            // commit transaction

            Toast.makeText(this, "User added", Toast.LENGTH_LONG).show();
            clearText();
        });

When beginning a Realm write operation, it has to be wrapped in transactions. Basically, at the end of a write operation, you can either commit the transaction or cancel it. Committing a transaction writes all changes to disk. If you cancel a write transaction, all the changes are discarded.

If you noticed, the first samples in this article used copyToRealm() to add a new Object, and both methods will insert data into the database.

In the code above, we simply created a new object from the User class, which extends RealmObject, and we set the values, and voila! We have inserted that data. I haven't hidden any extra code or class from you, that is really all it takes to perform a write operation.

Queries

So now that we can insert our lovely data, the next question is, how do we get it out?
Well, if you thought the process of inserting data looked cool, wait and see how we retrieve it. Suppose you wanted to get all the users whose age was less than 45. This is how that query would look:

        RealmResults<User> result = realm.where(User.class)
                            .lessThan("age", 45)//find all users with age less than 45
                            .findAll();//return all result that reach criteria

Now, ain't that splendid? After doing that, you could loop through the realm results and get the values for example:

    StringBuilder stringBuilder = new StringBuilder();
                    for (int i = 0; i < result.size(); i++) {
                        stringBuilder.append(result.get(i).getName() + "  ");
                    }

I have just scratched the surface, Realm can do much more than I have demonstrated; this was just meant to be an introduction. You can check the documentation for more information on queries, filtering, multi-threading, testing, and much more.

Databases should be easy to deploy, easy to use, and easy to scale. If you agree, you should check out CockroachDB, a scalable SQL database built for businesses of every size. Check it out here. 

Topics:
android ,realm ,database ,sqlite alternatives ,java ,swift ,javascript ,xamarin

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}