自强不息    厚德载物

Android -【 开源库】数据库 Realm 的基本使用

  2023/7/22 9:00:00   【次浏览】 本站

简介

Realm 是一个 MVCC (多版本并发控制)数据库,由Y Combinator公司在2014年7月发布一款支持运行在手机、平板和可穿戴设备上的嵌入式数据库,目标是取代 SQLite。Realm 本质上是一个嵌入式数据库,他并不是基于 SQLite 所构建的。它拥有自己的数据库存储引擎,可以高效且快速地完成数据库的构建操作。和 SQLite 不同,它允许你在持久层直接和数据对象工作。在它之上是一个函数式风格的查询 API,众多的努力让它比传统的SQLite 操作更快 。


GitHub 地址:realm-java


优点

易用

Ream 不是在SQLite基础上的ORM,它有自己的数据查询引擎。并且十分容易使用。


快速

由于它是完全重新开始开发的数据库实现,所以它比任何的ORM速度都快很多,甚至比SLite速度都要快。


跨平台

Realm 支持 iOS & OS X (Objective‑C & Swift) & Android。我们可以在这些平台上共享Realm数据库文件,并且上层逻辑可以不用任何改动的情况下实现移植。


高级

Ream支持加密,格式化查询,易于移植,支持JSON,流式api,数据变更通知等高级特性


可视化

Realm 还提供了一个轻量级的数据库查看工具,在Mac Appstore 可以下载“Realm Browser”这个工具,开发者可以查看数据库当中的内容,执行简单的插入和删除数据的操作。


使用

1. 添加依赖

在 project 的 build 中加入依赖

buildscript {

  repositories {

      jcenter()

  }

  dependencies {

      classpath "io.realm:realm-gradle-plugin:2.2.1"

  }

}



在 module 中加入

apply plugin: 'realm-android'

1

2. 创建 model

创建一个 User 类,需要继承 RealmObject 。支持public, protected和 private的类以及方法


public class User extends RealmObject {

    private String name;

    private int age;


    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;

    }

}


除了直接继承于 RealmObject 来声明 Realm 数据模型之外,还可以通过实现 RealmModel 接口并添加 @RealmClass 修饰符来声明。


@RealmClass

public class User implements RealmModel {

    ...

}


3. 初始化

使用默认配置:


Realm.init(this);

        Realm mRealm = Realm.getDefaultInstance();


这时候会创建一个叫做 default.realm的Realm文件,一般来说,这个文件位于/data/data/包名/files/。通过realm.getPath()来获得该Realm的绝对路径。


注意:模拟器上运行时,Realm.getDefaultInstance()抛出异常,真机上没问题


当然,我们还可以使用 RealmConfiguration 来配置 Realm


RealmConfiguration config = new RealmConfiguration.Builder() 

            .name("myrealm.realm") //文件名

            .schemaVersion(0) //版本号

            .build();

Realm realm = Realm.getInstance(config);


4. 关闭 Realm

记得使用完后,在 onDestroy 中关闭 Realm


@Override 

protected void onDestroy() { 

    super.onDestroy();

    // Close the Realm instance. 

    realm.close(); 

}


5. 版本升级

当数据结构发生变化是,需要升级数据库。对于Realm来说,数据库升级就是迁移操作,把原来的数据库迁移到新结构的数据库。


例1:User类发生变化,移除age,新增个@Required的id字段。

User版本:version 0


String name;

int    age;


User版本:version 1


@Required

String    id;

String name;


创建迁移类 CustomMigration,需要实现RealmMigration接口。执行版本升级时的处理:


/**

  * 升级数据库

  */

 class CustomMigration implements RealmMigration {

     @Override

     public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {

         RealmSchema schema = realm.getSchema();

         if (oldVersion == 0 && newVersion == 1) {

             RealmObjectSchema personSchema = schema.get("User");

             //新增@Required的id

             personSchema

                     .addField("id", String.class, FieldAttribute.REQUIRED)

                     .transform(new RealmObjectSchema.Function() {

                         @Override

                         public void apply(DynamicReal

mObject obj) {

                             obj.set("id", "1");//为id设置值

                         }

                     })

                     .removeField("age");//移除age属性

             oldVersion++;

         }

     }

 }


使用Builder.migration升级数据库,将版本号改为1(原版本号:0)。当Realm发现新旧版本号不一致时,会自动使用该迁移类完成迁移操作。


RealmConfiguration config = new RealmConfiguration.Builder() 

         .name("myrealm.realm") //文件名

         .schemaVersion(1) 

         .migration(new CustomMigration())//升级数据库

         .build();


6. 增

写入操作需要在事务中进行,可以使用executeTransaction方法来开启事务。


使用executeTransaction方法插入数据

mRealm.executeTransaction(new Realm.Transaction() {

         @Override

         public void execute(Realm realm) {

             User user = realm.createObject(User.class);

             user.setName("Gavin");

             user.setAge(23);

         }

     });


注意:如果在UI线程中插入过多的数据,可能会导致主线程拥塞。


使用copyToRealmOrUpdate或copyToRealm方法插入数据

当Model中存在主键的时候,推荐使用copyToRealmOrUpdate方法插入数据。如果对象存在,就更新该对象;反之,它会创建一个新的对象。若该Model没有主键,使用copyToRealm方法,否则将抛出异常。

final User user = new User();

      user.setName("Jack");

      user.setId("2");

      mRealm.executeTransaction(new Realm.Transaction() {

          @Override

          public void execute(Realm realm) {

              realm.copyToRealmOrUpdate(user);

          }

      });


使用executeTransactionAsync该方法会开启一个子线程来执行事务,并且在执行完成后进行结果通知。

RealmAsyncTask transaction = mRealm.executeTransactionAsync(new Realm.Transaction() {

 @Override

 public void execute(Realm realm) {

     User user = realm.createObject(User.class);

     user.setName("Eric");

     user.setId("4");

   }

});


注意:如果当Acitivity或Fragment被销毁时,在OnSuccess或OnError中执行UI操作,将导致程序奔溃 。用RealmAsyncTask .cancel();可以取消事务


7. 删

使用deleteFromRealm()

//先查找到数据

final RealmResults userList = mRealm.where(User.class).findAll();

mRealm.executeTransaction(new Realm.Transaction() {

  @Override

  public void execute(Realm realm) {

      userList.get(0).deleteFromRealm();

  }

});


使用deleteFromRealm(int index)

mRealm.executeTransaction(new Realm.Transaction() {

  @Override

  public void execute(Realm realm) {

      userList.deleteFromRealm(0);

  }

});


8. 改

mRealm.executeTransaction(new Realm.Transaction() {

    @Override

    public void execute(Realm realm) {

        //先查找后得到User对象

        User user = mRealm.where(User.class).findFirst();

        user.setAge(26);

    }

});

9. 查

findAll ——查询

RealmResults userList = mRealm.where(User.class).findAll();

1

findAllAsync——异步查询

RealmResults userList = mRealm.where(User.class)

              .equalTo("name", "Kevin")

              .findAllAsync();

findFirst ——查询第一条数据

User user2 = mRealm.where(User.class).findFirst();

equalTo ——根据条件查询

RealmResults userList = mRealm.where(User.class)

         .equalTo("name", "Kevin").findAll();


equalTo ——多条件查询

RealmResults userList = mRealm.where(User.class)

         .equalTo("name", "Kevin").findAll();

RealmResults userList = user5.where()

         .equalTo("dogs.name", "二哈").findAll();


手机扫码查看当前文章:

Android -【 开源库】数据库 Realm 的基本使用

如本网转载稿涉及版权等问题,请作者见稿后在两周内速来电与我们联系, 详见版权声明

  上一篇:Android开源库——xUtils框架

 下一篇:腾讯x5内核TBS服务集成