Realm技术选型初体验

作者: IT_xiao小巫 | 来源:发表于2017-06-16 19:00 被阅读52次

    Realm

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

    查看官网介绍:https://realm.io/cn/

    Realm的优点

    • 简单易用
    • 速度快
    • 跨平台
    • 高级功能
    • 可视化
    • 开源

    接入

    根目录build.gradle进行以下配置:

    buildscript {
        repositories {
            jcenter()
        }
        dependencies {
            ...
            
            classpath "io.realm:realm-gradle-plugin:3.1.1"
            
            ...
        }
    }
    
    

    工程目录build.gradle依赖插件:

    apply plugin: 'realm-android'
    
    

    Application类onCreate方法进行初始化:

    public class RealmApplication extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
            Realm.init(this);
        }
    }
    
    

    实操

    获取Ream实例

       public static Realm newRealmInstance() {
            return Realm.getInstance(new RealmConfiguration.Builder()
                    .deleteRealmIfMigrationNeeded()
                    .name(RealmHelper.DB_NAME)
                    .build());
        }
    
    

    声明实体

    **
     * User Model.
     *
     * 也可以使用@RealmClass注解来生命数据模型,比如:
     *
     * @RealmClass
        public class User implements RealmModel {
        ...
        }
     *
     * @author devilwwj
     * @since 2017/6/16
     */
    public class User extends RealmObject {
        // 主键唯一
        @PrimaryKey
        private String name;
        private int age;
    
        // 属性忽略,意味着此字段可以不被存储到数据库中
        @Ignore
        private int sessionId;
    
        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 int getSessionId() {
            return sessionId;
        }
    
        public void setSessionId(int sessionId) {
            this.sessionId = sessionId;
        }
    }
    
    

    必须继承RealmObject.

    写操作

        realm.beginTransaction();
        User user = realm.createObject(User.class); // 创建一个新的对象
        user.setName("John");
        user.setEmail("john@corporation.com");
        realm.commitTransaction();           
    
    

    不想手动处理事务?使用以下方式:

    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            User user = realm.createObject(User.class);
            user.setName("John");
            user.setEmail("john@corporation.com");
        }
    });
    
    

    想异步处理事务?使用以下方式:

    realm.executeTransactionAsync(new Realm.Transaction() {
                @Override
                public void execute(Realm bgRealm) {
                    User user = bgRealm.createObject(User.class);
                    user.setName("John");
                    user.setEmail("john@corporation.com");
                }
            }, new Realm.Transaction.OnSuccess() {
                @Override
                public void onSuccess() {
                    // 事物成功完成
                }
            }, new Realm.Transaction.OnError() {
                @Override
                public void onError(Throwable error) {
                    // 事物失败,自动取消
                }
            });
    
    

    查操作

    // 创建一个RealmQuery用于查找所有符合条件的user
    RealmQuery<User> query = realm.where(User.class);
    // 添加查询条件
    query.equalTo("name", "John");
    query.or().equalTo("name", "Peter");
    // 执行查询
    RealmResults<User> result1 = query.findAll();
    // 或者进行简化
    RealmResults<User> result2 = realm.where(User.class)
                                      .equalTo("name", "John")
                                      .or()
                                      .equalTo("name", "Peter")
                                      .findAll();
    
    

    改操作

    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            Dog myPuppy = realm.where(Dog.class).equalTo("age", 1).findFirst();
            myPuppy.setAge(2);
        }
    });
    
    

    删操作

    // 获取查询结果
    final RealmResults<Dog> results = realm.where(Dog.class).findAll();
    // 所有对数据的变更必须在事物中进行
    realm.executeTransaction(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            // 移除符合条件的单个查询结果
            results.deleteFirstFromRealm();
            results.deleteLastFromRealm();
            // 移除单个对象
            Dog dog = results.get(5);
            dog.deleteFromRealm();
            // 移除所有符合条件的查询结果
            results.deleteAllFromRealm();
        }
    });
    
    

    以上就是Realm的CRUD基本用法,第一次使用确实被惊艳了,很简单易用啊,符合技术选型的一个要求。

    除了简单易用,它有没有一些我们不知道的坑,必须有啊,具体看下以下这篇文章:

    说说 Realm 在 Android 上的坑

    指明了realm有以下缺点:

    • 线程的限制(realm对象只能被创建它的线程中访问,不能随意切换)
    • 数据类型(RealmList没有实现Serializable接口,不能通过intent直接传值)
    • 数据库版本迁移问题(需要关注实体类的变更,这。。)
    • 其实还有增加包大小的问题(可以通过split abi来减少包大小)

    总结

    本篇文章,只是粗略了介绍了Realm的用法,还需要更加深入去使用才能决定是否使用到项目中,在技术选型中,除了简单易用还要考虑是否适合自己的场景,
    就好像男生追求女生一样,尽管对方很优秀,但彼此并不适合,那就还是不要在一起了,因为你们不会幸(xing)福的,瞎扯了一下,感谢你的阅读。

    参考资料

    相关文章

      网友评论

      • 小_恶_魔:有没有buttrrknife和realm冲突问题的解决办法
      • mzeht:有故事

      本文标题:Realm技术选型初体验

      本文链接:https://www.haomeiwen.com/subject/apmmqxtx.html