GreenDao总结

2018-07-07  本文已影响106人  晔可可

1. GreenDao 3.0注解

@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. 条件查询方法

3. 缓存处理

出现的问题:

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

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

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 基本用法

上一篇 下一篇

猜你喜欢

热点阅读