Realm数据库踩坑

时间:2024-05-23 21:45:55

本文主要记录自己在使用Realm数据库过程中踩过的一些坑。

一.首先还是导入Realm

   这个就不多说了,网上很多(其实是我懒得敲)

二.使用过程中的一些坑

1.实体类:

   有两种方式:a.实现implements RealmModel接口[email protected]

@RealmClass
public class LocationAmapEntity implements RealmModel {
    /**
     * 纬度
     */
    @JSONField(name = "latitude")
    private double latitude;
    /**
     * 经度
     */
    @JSONField(name = "longitude")
    private double longitude;
    /**
     * 地址
     */
    @JSONField(name = "address")
    private String address;
    /**
     * 上传时间(格式->yyyy-MM-dd HH:mm:ss)
     */
    @JSONField(name = "upload_time")
    private String uploadLocateTime;
    /**
     * 范围
     */
    private float radius;

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getUploadLocateTime() {
        return uploadLocateTime;
    }

    public void setUploadLocateTime(String uploadLocateTime) {
        this.uploadLocateTime = uploadLocateTime;
    }

    public float getRadius() {
        return radius;
    }

    public void setRadius(float radius) {
        this.radius = radius;
    }

}

       b.继承RealmObject     

public class LocationAmapEntity extends RealmObject {
    /**
     * 纬度
     */
    @JSONField(name = "latitude")
    private double latitude;
    /**
     * 经度
     */
    @JSONField(name = "longitude")
    private double longitude;
    /**
     * 地址
     */
    @JSONField(name = "address")
    private String address;
    /**
     * 上传时间(格式->yyyy-MM-dd HH:mm:ss)
     */
    @JSONField(name = "upload_time")
    private String uploadLocateTime;
    /**
     * 范围
     */
    private float radius;

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getUploadLocateTime() {
        return uploadLocateTime;
    }

    public void setUploadLocateTime(String uploadLocateTime) {
        this.uploadLocateTime = uploadLocateTime;
    }

    public float getRadius() {
        return radius;
    }

    public void setRadius(float radius) {
        this.radius = radius;
    }

}

    建议使用a方式:实现implements RealmModel接口[email protected]

    因为在使用接口过程用到了FastJson解析和转换数据,使用b方式会导致无法转换和解析的问题,如果自己将数据转换好后(不使用FastJson转换list数据)再调用接口是OK的

2.天坑:数据表主键

   能不用主键就不要主键,Realm实体RealmObjects的主键primarykey自定义设置无自增属性,会导致很多问题

   如果需要主键的话,自己做好主键的自增

  例子:

  存储数据:无主键,两种方式
            Realm数据库踩坑
            Realm数据库踩坑
无主键的话使用copyToRealmOrUpdate(obj)会报错
有主键的话:
主键类型必须是String或者整型(byte, short, int, long)或者它们的装箱类型(Byte, Short, Integer, Long).
有主键的对象创建的时候不能使用createObject(Class<E> clazz)方法, 而应该使用createObject(Class<E> clazz, Object primaryKeyValue)附上主键.
有主键的话使用copyToRealm(obj), 有冲突会崩溃

              使用copyToRealmOrUpdate(obj),数据库有这个主键的话执行更新,无这个主键执行添加

            注意事项:
                1.如果有自定义permaryKey属性,初始化赋予值否则:
                Realm数据库踩坑
                2. 不论是create还是copyToRealm,有主键@PrimaryKey,要注意避免相重复primaryKey

                3.最好添加的时候采用insert(obj)方法,修改的时候先查询出来再修改

                4.事物结束一定要关闭Realm,否则会导致数据库无限增大,撑爆手机内存(在开发的过程中遇到过这个问题,天坑)

.RealmObject自带线程保护功能,只能在创建它的线程中访问,在子线程中不能访问。

也就是说,如果你在主线程中new了一个RealmObject对象 user,那么在子线程中是访问不了user对象的。
要想在子线程中访问,必须先将user存入Ream中,然后在子线程中query出来。

四.如果想在Realm.close()之后继续操作查询得到的对象,只能通过copyFromRealm()复制一份数据传出来。

Realm数据库踩坑

注意事项:
            1. 如果当前业务块是碎片的,不是在一整个流程中,即开用完即关。
            2. 查询的结果集需要return,或者是需要传给下一个方法体异步操作,则需要copy一份出来使用。
            3. 代码要健壮,就不可避免要try拦截这些错误,也是因为担心第三方库的不稳定,影响接入的产品性能,使用try catch避免。
                在这里解释下try catch会不会影响到运行性能:在没有抛出异常的情况下,性能没有区别(有异常情况则必须保护运行稳定程度)
            4. 简单的业务可不需要try