Realm Flashcards
What is Realm?
A NoSQL database for several platforms Android (Java, Kotlin), iOS (Objective-C, Swift), Xamarin (C#), and JavaScript (React Native, Node.js).
Schema is defined by classes, and the data are just instances of these classes.
Key Features Realm
Zero copy - data is never copied to memory
Transactions — All changes of the linked data objects need to be done inside the transaction.
Open / Close — Need to open / close the instance database.
More global features:
- MVCC
- ACID
Limitations Realm
Disadvantages
- No auto increment for primary keys
- Can’t access objects across threads
So if, for example, you retrieve a realm object using AsyncTask’s doInBackground(), which runs in a background thread, you cannot pass this instance to the onPostExecute() methods, since those run on the main thread. Possible workarounds for this situation would be to either make a copy of the object and pass it along or pass the object’s id and retrieve the object again on onPostExecute(). Realm offers synchronous and asynchronous methods for read/write. - No support for model inheritance. The current workaround is to use composition. For example:
Wanted: Dog ->extends-> Animal
OnlySolution: set Animal as a field in Dog
MVCC
Let writers make a “new” copy while readers use an apropiate “old” copy.
Readers are always allowed to proceed;
ACID
Four primary attributes ensured to any transaction:
Atomicity. In a transaction involving two or more discrete pieces of information, either all of the pieces are committed or none are. (all-or-none unit of work)
Consistency. A transaction either creates a new and valid state of data, or, if any failure occurs, returns all data to its state before the transaction was started.
Isolation. A transaction in process and not yet committed must remain isolated from any other transaction.
Durability. Committed data is saved by the system such that, even in the event of a failure and system restart, the data is available in its correct state.
Creating Realm Model
The model has to extends RealmObject.
Relationships
— one-to-one - add a model as the field from another model.
– one-to-many-relationships - add a RealmList
RealmList - like a regular list, is container for RealmObject;
So it feels very natural, and we don’t need to deal with SQLite foreign keys
ORMs
To save us from dealing with raw SQL, ORMs came to the rescue.
Some of the most famous Android ORMs are DBFlow, greenDAO, and OrmLite.
The greatest value they bring is SQLite abstraction, letting us map database entities to Java objects relatively easy.
Realm and ORMs
The key difference between Realm and ORMs is that Realm is not an abstraction built on top of SQLite, but a whole new database engine. Rather than a relational model, it is based on an object store. Its core consists of a self-contained C++ library. It currently supports Android, iOS(Objective-C and Swift), Xamarin, and React Native.
Advantages
ZERO-COPY - which means that data is never copied to memory. The results you get from a query are actually just pointers to the real data, so everything happens quickly enough because there is no deserialization as such. The data itself is lazily loaded as you access it (a particular field).
FOR EXAMPLE, you have a model with 10 fields (columns in SQL).If you query for objects of this model and you just need 3 fields to fill the list items, those will be the only fields retrieved.
This is a big advantage over ORMs which usually load all data from selected SQL rows upfront.
- SO, THE BENEFITS:
- FAST
- Apps consume less memory
If you have already read data from Realm objects and displayed them on the screen, for example, and want to receive updates for when the underlying data changes, what do you do?
You can add a listener:
someresults.addChangeListener(new RealmChangeListener>() {
@Override
public void onChange(RealmResults results) {
// UPDATE UI
}
});
Creating Objects
2 ways:
SOLUTION 1: createObject() WITHIN A TRANSATIONS:
realm.beginTransaction();
User user= realm.createObject(User.class);
user.setName(“Tina”);
realm.commitTransaction();
SOLUTION 2: create OUTSIDE TRANSACTION, the copyToRealm() IN TRANSACTION:
User user = new User();
user.setName(“Tina”);
realm.beginTransaction();
User realmUser = realm.copyToRealm(user);
realm.commitTransaction();
- coyToRealm checks if the object exists (checks using primary key) if it is exists FAIL, if not Succes.
- copyOrUpdateToRealm checks if the object exists- Upsates,if not Creates and copies
Initialize Realm in Application
Before you can use Realm in your app, you must initialize a Realm. . Initializing a Realm is done once in the app’s lifecycle. A good place to do this is in an Application subclass.
We first initialize the Realm and then configure it with a RealmConfiguration object.
The RealmConfiguration controls all aspects of how a Realm is created. The minimal configuration usable by Realm is:
Realm.init(this);
RealmConfiguration config = new RealmConfiguration.Builder().build();
which will create a file called default.realm located in Context.getFilesDir().
Get Realm Instance
For example; we need realm instance in an Activity:
Realm realm = Realm.getDefaultInstance(); //opens
Don’t forget to close db.
Transactions
Creating a object, or modifying a value is considered WRITE OPERATIONS, and they must be done within a transaction.
A transaction can be commited or canceled.
A transaction can be synchronous or asynchrnous
2 ways to create transaction: SOLUTION 1: realm.beginTransaction(); ..... realm.commitTransaction();
SOLUTION 2: realm.executeTransaction( new Realm.Transaction(){ pubic void execute(Realm realm){ //code } }); executeTransaction - automatically handles calling realm.cancelTransaction() in case an exception is thrown
Asynchronous For Async tx, add another paramenter what is the callback; Realm will execute tx in background, and report back when tx is done realm.executeTransaction( new Realm.Transaction(){ pubic void execute(Realm realm){ //code },
new Realm.Transaction.Callback(){ pubic void onSucces(){//code} pubic void onFailure(){//code} } });