本文共 16337 字,大约阅读时间需要 54 分钟。
In this tutorial, we’ll be discussing the basics of Realm Database and implement it in our Android Application for offline data storage.
在本教程中,我们将讨论Realm数据库的基础知识,并将其在我们的Android应用程序中进行离线数据存储。
Realm is a database that is the perfect alternative to SQLite. It’s is a NoSQL database designed for mobile platform.
Its core consists of a self-contained C++ library. It supports Android and iOS both.Realm是数据库的完美替代SQLite。 这是专为移动平台设计的NoSQL数据库。
它的核心包括一个自包含的C ++库。 它同时支持Android和iOS。Pros of Realm
领域的优点
Add the following classpath in your root build.gradle
file:
在根build.gradle
文件中添加以下类路径:
buildscript { ... dependencies { ... classpath 'io.realm:realm-gradle-plugin:3.2.1' }}
Add the following plugin to the app’s build.gradle
将以下插件添加到应用的build.gradle
apply plugin: 'realm-android'
Creating a Realm Instance
创建一个领域实例
To create a Realm instance we do the following:
要创建一个Realm实例,请执行以下操作:
Realm mRealm = Realm.getInstance(context);
We can also pass a RealmConfiguration
instance inside the getInstance()
我们还可以在getInstance()
内传递RealmConfiguration
实例。
RealmConfiguration config = new RealmConfiguration.Builder() .name("test.db") .schemaVersion(1) .deleteRealmIfMigrationNeeded() .build();
Creating Realm Model class
创建领域模型类
To create Model classes, extend them with RealmObject
.
@PrimaryKey
annotation. 要创建Model类,请使用RealmObject
对其进行RealmObject
。
@PrimaryKey
注释。 Following are some annotations commonly used on Realm Model classes:
以下是领域模型类上常用的一些注释:
You can write data to Realm in the following ways:
您可以通过以下方式将数据写入Realm:
Realm realm = Realm.getDefaultInstance();realm.beginTransaction();realm.copyToRealm(realmModelInstance)realm.commitTransaction();
There is a problem with the above approach though. It doesn’t cancel the transaction if failed.
Hence it is not the recommended way to insert data into the Database.但是,上述方法存在问题。 如果失败,它不会取消交易。
因此,不建议将数据插入数据库。The method executeTranscation
or executeTranscationAsync
automatically handle the cancel transaction.
方法executeTranscation
或executeTranscationAsync
自动处理取消事务。
Realm realm = Realm.getDefaultInstance(); realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { realm.insertOrUpdate(realmModelInstance); } });
Also, we can add a try-catch inside the executeTranscation
to catch exceptions. Try-catch is ignored by the earlier approach though.
另外,我们可以在executeTranscation
内部添加一个try-catch来捕获异常。 但是,较早的方法忽略了try-catch。
insertOrUpdate
or insertOrUpdate
或 copyToRealmOrUpdate
are used to insert if the primary key doesn’t exist or update the current object if the primary key exists. copyToRealmOrUpdate
进行插入;如果主键存在,则用于更新当前对象。 RealmResultsresults = realm.where(RealModelClass.class).findAll();
Again it’s a good practice to use this inside the execute method.
同样,在execute方法中使用此方法也是一个好习惯。
mRealm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { RealmResultsresults = realm.where(RealModelClass.class).findAll(); results.deleteAllFromRealm(); } });
Following are the other methods that can be used to delete the results:
以下是可用于删除结果的其他方法:
RealmList
is a built-in collection of RealmObjects and is used for model one-to-many relationships.
RealmList
是RealmList
的内置集合,用于模型一对多关系。
RealmList cannot support non-realm objects(such as Long, String, Integer).
RealmList无法支持非领域对象(例如Long,String,Integer)。
In the following section, we’ll be creating a basic Android Application which uses Realm and performs CRUD operations.
在下一节中,我们将创建一个基本的Android应用程序,该应用程序使用Realm并执行CRUD操作。
The code for the activity_main.xml layout is given below:
下面给出了activity_main.xml布局的代码:
Inside the MyApplication.java is where we initialise our Realm.
在MyApplication.java中,是我们初始化领域的地方。
package com.journaldev.androidrealmdatabase;import android.app.Application;import io.realm.Realm;import io.realm.RealmConfiguration;public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); Realm.init(getApplicationContext()); RealmConfiguration config = new RealmConfiguration.Builder() .deleteRealmIfMigrationNeeded() .build(); Realm.setDefaultConfiguration(config); }}
The code for the Employee.java class is given below:
Employee.java类的代码如下:
package com.journaldev.androidrealmdatabase;import io.realm.RealmList;import io.realm.RealmObject;import io.realm.annotations.PrimaryKey;import io.realm.annotations.Required;public class Employee extends RealmObject { public static final String PROPERTY_NAME = "name"; public static final String PROPERTY_AGE = "age"; @PrimaryKey @Required public String name; public int age; public RealmListskills;}
The code for the Skill.java class is given below:
下面给出了Skill.java类的代码:
package com.journaldev.androidrealmdatabase;import io.realm.RealmObject;import io.realm.annotations.PrimaryKey;import io.realm.annotations.Required;public class Skill extends RealmObject { public static final String PROPERTY_SKILL = "skillName"; @PrimaryKey @Required public String skillName;}
The code for the MainActivity.java is given below:
MainActivity.java的代码如下:
package com.journaldev.androidrealmdatabase;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import io.realm.Realm;import io.realm.RealmList;import io.realm.RealmResults;import io.realm.exceptions.RealmPrimaryKeyConstraintException;public class MainActivity extends AppCompatActivity implements View.OnClickListener { Button btnAdd, btnRead, btnUpdate, btnDelete, btnDeleteWithSkill, btnFilterByAge; EditText inName, inAge, inSkill; TextView textView, txtFilterBySkill, txtFilterByAge; Realm mRealm; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); mRealm = Realm.getDefaultInstance(); } private void initViews() { btnAdd = findViewById(R.id.btnAdd); btnAdd.setOnClickListener(this); btnRead = findViewById(R.id.btnRead); btnRead.setOnClickListener(this); btnUpdate = findViewById(R.id.btnUpdate); btnUpdate.setOnClickListener(this); btnDelete = findViewById(R.id.btnDelete); btnDelete.setOnClickListener(this); btnDeleteWithSkill = findViewById(R.id.btnDeleteWithSkill); btnDeleteWithSkill.setOnClickListener(this); btnFilterByAge = findViewById(R.id.btnFilterByAge); btnFilterByAge.setOnClickListener(this); textView = findViewById(R.id.textViewEmployees); txtFilterBySkill = findViewById(R.id.txtFilterBySkill); txtFilterByAge = findViewById(R.id.txtFilterByAge); inName = findViewById(R.id.inName); inAge = findViewById(R.id.inAge); inSkill = findViewById(R.id.inSkill); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btnAdd: addEmployee(); break; case R.id.btnRead: readEmployeeRecords(); break; case R.id.btnUpdate: updateEmployeeRecords(); break; case R.id.btnDelete: deleteEmployeeRecord(); break; case R.id.btnDeleteWithSkill: deleteEmployeeWithSkill(); break; case R.id.btnFilterByAge: filterByAge(); break; } } private void addEmployee() { Realm realm = null; try { realm = Realm.getDefaultInstance(); realm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { try { if (!inName.getText().toString().trim().isEmpty()) { Employee employee = new Employee(); employee.name = inName.getText().toString().trim(); if (!inAge.getText().toString().trim().isEmpty()) employee.age = Integer.parseInt(inAge.getText().toString().trim()); String languageKnown = inSkill.getText().toString().trim(); if (!languageKnown.isEmpty()) { Skill skill = realm.where(Skill.class).equalTo(Skill.PROPERTY_SKILL, languageKnown).findFirst(); if (skill == null) { skill = realm.createObject(Skill.class, languageKnown); realm.copyToRealm(skill); } employee.skills = new RealmList<>(); employee.skills.add(skill); } realm.copyToRealm(employee); } } catch (RealmPrimaryKeyConstraintException e) { Toast.makeText(getApplicationContext(), "Primary Key exists, Press Update instead", Toast.LENGTH_SHORT).show(); } } }); } finally { if (realm != null) { realm.close(); } } } private void readEmployeeRecords() { mRealm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { RealmResultsresults = realm.where(Employee.class).findAll(); textView.setText(""); for (Employee employee : results) { textView.append(employee.name + " age: " + employee.age + " skill: " + employee.skills.size()); } } }); } private void updateEmployeeRecords() { mRealm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { if (!inName.getText().toString().trim().isEmpty()) { Employee employee = realm.where(Employee.class).equalTo(Employee.PROPERTY_NAME, inName.getText().toString()).findFirst(); if (employee == null) { employee = realm.createObject(Employee.class, inName.getText().toString().trim()); } if (!inAge.getText().toString().trim().isEmpty()) employee.age = Integer.parseInt(inAge.getText().toString().trim()); String languageKnown = inSkill.getText().toString().trim(); Skill skill = realm.where(Skill.class).equalTo(Skill.PROPERTY_SKILL, languageKnown).findFirst(); if (skill == null) { skill = realm.createObject(Skill.class, languageKnown); realm.copyToRealm(skill); } if (!employee.skills.contains(skill)) employee.skills.add(skill); } } }); } private void deleteEmployeeRecord() { mRealm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { Employee employee = realm.where(Employee.class).equalTo(Employee.PROPERTY_NAME, inName.getText().toString()).findFirst(); if (employee != null) { employee.deleteFromRealm(); } } }); } private void deleteEmployeeWithSkill() { mRealm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { RealmResults employees = realm.where(Employee.class).equalTo("skills.skillName", inSkill.getText().toString().trim()).findAll(); employees.deleteAllFromRealm(); } }); } private void filterByAge() { mRealm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { RealmResults results = realm.where(Employee.class).greaterThanOrEqualTo(Employee.PROPERTY_AGE, 25).findAllSortedAsync(Employee.PROPERTY_NAME); txtFilterByAge.setText(""); for (Employee employee : results) { txtFilterByAge.append(employee.name + " age: " + employee.age + " skill: " + employee.skills.size()); } } }); } @Override protected void onDestroy() { super.onDestroy(); if (mRealm != null) { mRealm.close(); } }}
Don’t forget to close the Realm instance!
不要忘记关闭Realm实例!
When you click update with a different Skill that doesn’t exist, it creates that and adds it to the RealmList.
当您单击不存在的其他技能进行更新时,它将创建该技能并将其添加到RealmList中。
The output of the above application in action is given below:
上面应用程序的输出如下:
That brings an end to this tutorial. You can download the project from the link below:
这样就结束了本教程。 您可以从下面的链接下载项目:
翻译自:
转载地址:http://samzd.baihongyu.com/