Android platform has many orm frameworks that can store data locally, such as ormlite, green Dao, SugarORM and so on. These orm frameworks are basically sqlite-based. The database Realm I'm going to introduce today is a solution to replace sqlite. It has its own database storage engine. It's lighter and faster than sqlite. Most importantly, it's cross-platform. There are five implementations of Java, Objective C, Swift, React-Native and Xamarin.
This article is an introductory tutorial for Realm databases in Android, without discussing the advantages and disadvantages of Realm and other orm frameworks (which have been searched a lot on the Internet).
Learning catalogue for this article
I. Environmental Configuration
II. Creating Entities
CRUD
IV. Advanced Usage
I. Environmental Configuration
- Add in the build file of the project
buildscript { repositories { jcenter() } dependencies { ... classpath "io.realm:realm-gradle-plugin:1.2.0" }
- Add in the build file of app
apply plugin: 'realm-android'
II. Creating Entities
Realm supports field types, in addition to the basic types provided by Java, Realm also supports objects that inherit RealmObject and RealmList<? extends RealmObject>
The object in the sample project is used directly for convenience.
Create a User entity
public class User extends RealmObject {
@PrimaryKey
private String id;
private String name;
private int age;
private RealmList<User> friends;
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 String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public RealmList<User> getFriends() {
return friends;
}
public void setFriends(RealmList<User> friends) {
this.friends = friends;
}
}
Careful students have noticed that the entity objects we created above inherit from RealmObject, and the Realm data entity definitions need to inherit from RealmObject classes.
Here are some points to know:
- @ PrimaryKey is used to identify the primary key
- All default fields are stored
- If a field does not need to be stored locally, add the @Ignore annotation to it.
CRUD
The use of database is nothing more than adding, deleting, modifying and checking these four operations, among which checking is the key point, which is also a difficult point in writing native sql statements. Let's take a look at Realm's CRUD
1. Adding data
RealmConfiguration realmConfig = new RealmConfiguration
.Builder(this)
.build();
Realm realm = Realm.getInstance(realmConfig);
public void testAdd() {
initRealm();
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
for (int i = 0; i < 10; i++) {
User user = realm.createObject(User.class);
user.setName("user" + i);
user.setAge(10 + i);
user.setId(UUID.randomUUID().toString());
}
showInTextView("10 Bar Data Added Successfully");
}
});
}
Before using Realm to operate, it is necessary to configure Realm. All write operations in Realm must be done in transactions. Otherwise, errors will be reported. Remember to call realm.close() in Activity's onDestory to release resources. The code snippet above creates 10 User objects.
2. Query data
- All queries
public void testQuery() { List<User> users= realm.where(User.class).findAll(); for (User user: users) { showInTextView("id:" + user.getId() + " name:" + user.getName() + " age:" + user.getAge()); } }
- Conditional query, Realm supports the following query conditions (from the official website):
- between(), greaterThan(), lessThan(), greaterThan OrEqualTo (), and lessThanOrEqualTo()
- equalTo() and notEqualTo()
- contains(), beginsWith(), and endsWith()
- isNull() and isNotNull()
- isEmpty() and isNotEmpty()
The following code snippet queries User younger than 15
public void testQueryAgeLessThan15() {
List<User> users= realm.where(User.class).lessThan("age", 15).findAll();
for (User user: users) {
showInTextView("id:" + user.getId() + " name:" + user.getName() + " age:" + user.getAge());
}
}
- Aggregate queries, supported aggregation operations are sum, min, max, average
The following code snippet gives the average age of everyonepublic void testQueryAverageAge() { double age = realm.where(User.class).findAll().average("age"); textView.setText("average age:" + age); }
3. Update data
public void testUpdate() {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
User user = realm.where(User.class).equalTo("name", "user9").findFirst();
if (user != null) {
user.setAge(99);
user.setName("Muddleheaded young people");
}
textView.setText("Update Successful");
}
});
}
4. Delete data
The following code snippet shows how to delete the specified object
public void testDelete() {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
User user = realm.where(User.class).equalTo("name", "user0").findFirst();
if (user != null)
user.deleteFromRealm();
textView.setText("Successful deletion");
}
});
}
IV. Advanced Usage
Through the previous section of the study, we have learned the basic Realm database add, delete and check operations.
In this section, let's see what other uses Realm has.
1. Creating objects with json
In actual development, we have more opportunities to deal with json, so it is very useful to create objects directly from json. The following code snippet shows how to use it.
private void testAddFromJson() {
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
String json = "{\n" +
" \"id\": \"uuid1\",\n" +
" \"name\": \"solid\",\n" +
" \"age\": 20\n" +
"}";
String jsons = "[\n" +
" {\n" +
" \"id\": \"uuid1\",\n" +
" \"name\": \"solid\",\n" +
" \"age\": 20\n" +
" },\n" +
" {\n" +
" \"id\": \"uuid2\",\n" +
" \"name\": \"jhack\",\n" +
" \"age\": 21\n" +
" },\n" +
" {\n" +
" \"id\": \"uuid3\",\n" +
" \"name\": \"tom\",\n" +
" \"age\": 22\n" +
" }\n" +
"]";
//realm.createObjectFromJson(User.class, json);
realm.createAllFromJson(User.class, jsons);
}
});
}
2. Data Model Change Processing
The data model in development can't be created from the beginning, so it can be guaranteed that it won't change in the later development process. For Realm, if one of the entity classes changes and we don't do any processing, we will report an error. If it is still in the early stage of application development, it doesn't matter. Clear the data directly, but if the application has been released, we need to find it. Find a solution.
The solutions here are as follows:
public class MyMigration implements RealmMigration {
@Override
public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
Log.e(MainActivity.TAG, "oldVersion:" + oldVersion + " newVersion:" + newVersion);
RealmSchema schema = realm.getSchema();
if (newVersion == 2) {
schema.get("User")
.addField("desc", String.class);
}
}
@Override
public boolean equals(Object obj) {
return obj instanceof MyMigration;
}
@Override
public int hashCode() {
return super.hashCode();
}
}
realmConfig = new RealmConfiguration
.Builder(this)
.schemaVersion(2)
.migration(new MyMigration())
.build();
3. Combination with RxJava
Realm is native to support Rxjava. Because RxJava is an optional dependency, you need to add the dependency of RxJava library to the build file of app when you use it. Here is the code snippet used.
public void testRxJava() {
realm.where(User.class).findAll()
.asObservable()
.flatMap(new Func1<RealmResults<User>, Observable<User>>() {
@Override
public Observable<User> call(RealmResults<User> users) {
return Observable.from(users);
}
})
.subscribe(new Action1<User>() {
@Override
public void call(User user) {
showInTextView("id:" + user.getId() + " name:" + user.getName() + " age:" + user.getAge() + " desc:" + user.getDesc());
}
});
}
This article received this, unfortunately Realm in Windows does not have a relevant viewer, only Mac version, so you can not directly view the data in the Realm database in Windows, I hope the official will support it later. For more information, please check the official documents.