美文网首页
GreenDao总结

GreenDao总结

作者: 晔可可 | 来源:发表于2018-07-07 19:05 被阅读106次

    1. GreenDao 3.0注解

    • @Id :主键 long/Long型,可以通过@Id(autoincrement = true)设置自增长
    • @Property:设置一个非默认关系映射所对应的列名,默认是的使用字段名 举例:@Property (nameInDb=”name”)
    • @NotNul:设置数据库表当前列不能为空
    • @Transient :添加次标记之后不会生成数据库表的列
      1.)索引注解
    • @Index:使用@Index作为一个属性来创建一个索引,通过name设置索引别名,也可以通过unique给索引添加约束
    • @Unique:向数据库列添加了一个唯一的约束
      2.)关系注解
    • @ToOne:定义与另一个实体(一个实体对象)的关系
    • @ToMany:定义与多个实体对象的关系
    @ToOne的用法

    customerId作为外键与Customer中的主键(也就是id)相连。

    @Entity
    public class Order {
        @Id private Long id;
      
        private long customerId;
      
        @ToOne(joinProperty = "customerId")
        private Customer customer;
    }
      
    @Entity
    public class Customer {
        @Id private Long id;
    }
    
    @ToMany的用法

    第一种 Site类的ownerId作为外键,与User的主键相连。

    @Entity
    public class User {
        @Id private Long id;
      
        @ToMany(referencedJoinProperty = "ownerId")
        private List<Site> ownedSites;
    }
      
    @Entity
    public class Site {
        @Id private Long id;
        private long ownerId;
    }
    

    第二种 Site类的ownerId作为外键,与User的非主键不为空的键相连。

    @Entity
    public class User {
        @Id private Long id;
        @Unique private String authorTag;
      
        @ToMany(joinProperties = {
                @JoinProperty(name = "authorTag", referencedName = "ownerTag")
        })
        private List<Site> ownedSites;
    }
      
    @Entity
    public class Site {
        @Id private Long id;
        @NotNull private String ownerTag;
    }
    

    @ToMany的属性referencedJoinProperty,类似于外键约束。

    @JoinProperty 对于更复杂的关系,可以使用这个注解标明目标属性的源属性。

    @JoinEntity 如果你在做多对多的关系,有其他的表或实体参与,可以给目标属性添加这个额外的注

    @Entity
    public class Site {
        @Id private Long id;
      
        @ToMany
        @JoinEntity(
                entity = JoinSiteToUser.class,
                sourceProperty = "siteId",
                targetProperty = "userId"
        )
        private List<User> authors;
    }
      
    @Entity
    public class JoinSiteToUser {
        @Id private Long id;
        private Long siteId;
        private Long userId;
    }
      
    @Entity
    public class User {
        @Id private Long id;
    }
    

    2. 条件查询方法

    • “whereOr” where语句里面写的条件都是用“且”连接,whereOr里的语句使用“或”连接
    • “distinct” 直接过滤掉重负字段
    • “limit” 分页n个一页,一般和offset结合使用
    • “offset” 忽略查询出的前n条结果
    • “orderAsc” 以字段升序排序
    • “orderDesc”以字段降序
    • “preferLocalizedStringOrder” 本地化字符串排序
    • “orderCustom” 自定义排序 里面需要传两个参数: 一个属性 和对应的排序方案 ASC 或是 DESC
    • “orderRaw” 也是自定义排序, 把字段和 排序方案 写在一个字符串传入
    • “stringOrderCollation” 也是自定义排序 可以合并多个升降排序方案 以日期升序 且 价格降序
    • “notEq” 和eq相反,别傻傻在再去外面敲“!”取反
    • “notIn” 同上
    • “or” 或者
    • “like” 就是sql语句的LIKE "%"+string+"%"
    • “between” 也就是BETWEEN ? AND ? 可以取两个值的区间 (但是这条语句要慎用,不同的数据库不一样,有的是A<条件<B,有的是A<=条件<=B)
    • “gt” 相当于 >
    • “ge”相当于 >=
    • “lt” 相当于 <
    • “le”相当于 <=
    • “isNull” 为空
    • “notIsNull” 不为空

    3. 缓存处理

    出现的问题:

    查询前后存入的3条不同记录,结果为3条相同的记录。

    排查过程:
    1. 将Android手机上的数据库导出到电脑
    2. 使用SQLite查看工具发现数据库里的三条记录确实不相同
    3. 在GreenDao查询方法处打断点得到SQL语句
    4. 复制到SQLite查看工具中
    5. 运行语句得到的确实是3条不同的记录,这证明查询语句没有问题。
    6. 经排查发现,是GreenDao自带缓存导致的问题。
    解决办法:
    • 清除daoSession的缓存
    daoSession.clear();
    
    • 清除指定dao类的缓存
    dao.detachAll();
    
    何时清空缓存

    在单纯的查询中我们没必要清理缓存,比如列表页查询集合,跳入详情页查询对象,这样的操作就没必要清理缓存,缓存会减少IO操作、大大提高我们的查询效率,但是执行了插入、修改、删除,会影响我们查时,我们只清理该表的缓存,一般情况就是我们在网络获数据后有必要对该表执行一下清理缓存。

    4. 分页加载

    分页加载20条数据,getTwentyRec(int offset)中控制页数offset++即可

    public List<UserEntity> getTwentyRec(int offset){
        UserDao dao = openReadableDb().getUserDao();
        List<UserEntity> listMsg = dao.queryBuilder().offset(offset * 20).limit(20).list();
        return listMsg;
    }
    

    5. insertOrReplace和save的区别

    • insertOrReplace : 传入的对象在数据库中,有则更新无则插入。推荐同步数据库时使用该方法。
    • save 类似于insertOrReplace,区别在于save会判断传入对象的key,有key的对象执行更新,无key的执行插入。当对象有key但并不在数据库时会执行失败.适用于保存本地列表
    save源码如下
      /**
         * "Saves" an entity to the database: depending on the existence of the key property, it will be inserted
         * (key is null) or updated (key is not null).
         * <p>
         * This is similar to {@link #insertOrReplace(Object)}, but may be more efficient, because if a key is present,
         * it does not have to query if that key already exists.
         */
        public void save(T entity) {
            if (hasKey(entity)) {
                update(entity);
            } else {
                insert(entity);
            }
        }
    

    可以看出,save只判断了对象key是否存在,并不会去查询数据库。当对象有key但并不在数据库时,执行update语句不会有数据得到更新。

    适用场景

    只有本地数据库,且key默认由数据库生成。直接使用save就好。
    插入的数据有key,其实这种情况通常是同步线上数据到本地数据库时的情况,因为直接使用了数据库的key,所以不能使用save,必须使用insertOrReplace。

    结论

    在确保插入数据有key时必须存在于数据库的情况下,适用save更高效。其他情况一律适用insertOrReplace

    6. 相关链接

    GreenDao在GitHub上的Demo
    GreenDao3 基本用法

    相关文章

      网友评论

          本文标题:GreenDao总结

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