Android ORM——初识greenDAO 3及使用greenDAO 3前应该掌握的一些知识点介绍了greenDAO的配置步骤和一些重要的知识点,以及重要的角色的功能和联系,这一篇就正式开始结合点源码从应用greenDAO方面总结。在使用greenDAO之前,我们得明确一点greenDAO是ORM框架,简单来说就是把数据库实体表映射成为对应的JavaBean,操作JavaBean即是操作数据表,完完全全的面向对象思想。
Property源码中是这样子介绍的:映射到数据库列的属性的元数据,用于创建查询构建器使用的WhereCondition 对象(Meta data describing a property mapped to a database column; used to create WhereCondition object used by the query builder),简单理解它就是数据列在以JavaBean的形式展现,除此之外还有一个重要的功能就是构造Where条件子句(封装了很多条件子句),一切皆基于对象嘛,而Properties则可以看成是一个数据表的结构,一个Properties对应数据表的列。
Property的部分方法名 | 说明 |
---|---|
WhereCondition eq(Object value) | 相当于在Where字句后加上 “=” value |
WhereCondition notEq(Object value) | 在Where字句后加上 “!=” value |
WhereCondition like(String value) | 在Where字句后加上 “like” value模糊查询 |
WhereCondition between(Object a, Object b) | 在Where字句后加上 “between a and b” value |
总所周知查询是为了得到符合特定条件的实体数据,而在greenDAO中我们有两种查询方式:通过Query使用原始SQL来制定查询;不编写原始SQL语句而是调用QueryBuilder封装的对应API(优先考虑,原因就是因为QueryBuilder 已经封装了对应的接口方法去生成不同类型的SQL语句,使用的时候可以通过QueryBuilder 创建自定义查询Without SQL。),简单来说greeDAO就是把原始的SQL的分为很多部分,而且分别封装成了对应的API方法,比如:GreenDAOApplication.getDaoSessionins().getUserDao().queryBuilder(),作用就相当于Select * from table,是主句,其他的条件子句、排序、去重等子句的构造(包括执行数据的增删改查),都是封装到了对应的方法,调用了之后自动添加到主句之后,最终形成完整的一条SQL语句完成数据操作。
QueryBuilder部分方法名 | 说明 |
---|---|
protected QueryBuilder(AbstractDao |
构造方法是保护的,不能通过其构造方法获取对象 |
QueryBuilder |
去重查询,相当于是在SQL语句中加了distinct |
QueryBuilder |
条件子句,相当于SQL中的Where |
QueryBuilder |
或条件查询 |
WhereCondition and(WhereCondition cond1, WhereCondition cond2, WhereCondition… condMore) | 且条件 |
QueryBuilder |
Order 子句 |
QueryBuilder |
分页查询 |
DeleteQuery |
删除 |
List |
执行Query并把返回集合,并且entity都会加载到内存中,返回的结果通常就是ArrayList |
LazyList listLazy() | Entity按需加载到内存中,在第一次访问list中的element时,它就会呗加载并且缓存。 |
LazyList listLazyUncached() | 每次访问结果集的时候都是从数据库中加载,而不使用缓存。 |
LazyList listIterator() | 通过迭代器访问结果集,并且采用的时lazy-loading,结果不会缓存。 |
T unique() | 返回唯一的数据 |
尽管QueryBuilder已经很强大,但是假如还是不能满足你的需求,greeDAO还支持原始的SQL语句,主要有两种方式:
//嵌套子查询,userDao.queryBuilder() 这句执行了之后就相当于是Select * from User
Query query = userDao.queryBuilder().where(
new StringCondition("_ID IN " +
"(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)").build();
Query<User> query = userDao.queryRawCreate(
", GROUP G WHERE G.NAME=? AND T.GROUP_ID=G._ID", "admin"
);
Query方法名 | 说明 |
---|---|
Query setParameter(int index, Object parameter) | 设置参数 |
List |
执行Query并把返回集合,并且entity都会加载到内存中,返回的结果通常就是ArrayList |
LazyList listLazy() | Entity按需加载到内存中,在第一次访问list中的element时,它就会呗加载并且缓存。 |
LazyList listLazyUncached() | 每次访问结果集的时候都是从数据库中加载,而不使用缓存。 |
LazyList listIterator() | 通过迭代器访问结果集,并且采用的时lazy-loading,结果不会缓存。 |
T unique() | greenDao支持唯一结果(0 or 1个结果)和结果集。会返回唯一结果或者null |
T uniqueOrThrow() | 会返回唯一结果,不会返回null |
另外listLazy,listLazyUncached,listIterator都采用greenDao的LazyList类,在真正使用数据的时候才加载(on-demand),还持有一个database cursor引用。(这就是为什么需要调用close方法关闭lazy lists和iterators(通常在try/finally块里面))。当所有的element被访问了之后,listLazy()和listIterator()自动关闭cursor,但如果list提前处理完成,就必须去调用close()。
Query
public class GreenDAOApplication extends Application {
private final static String DBNAME="REBOT_DB" ;
public static DaoSession daoSession=null;
@Override
public void onCreate() {
super.onCreate();
initGreenDAO(this);
}
/**
* 初始化并创建数据库及其结构
*/
private void initGreenDAO(Context context){
DaoMaster.DevOpenHelper openHelper=new DaoMaster.DevOpenHelper(context,DBNAME);
Database database=openHelper.getWritableDb();
DaoMaster daoMaster=new DaoMaster(database);
daoSession=daoMaster.newSession();
}
public static DaoSession getDaoSessionins(){
return daoSession;
}
}
前面所讲一个Entity实例对应数据表的一行数据,所以插入新增的数据的时候,我们只需要把实例化后的Entity对象传递insert系方法,再通过AbstractDao的子类对象调用即可,其中insert是插入一个,insertInTx是插入多个(“Tx”表示用一个事务去控制整个过程(提高效率))。
insertOrReplace是插入或替换。
/*插入一条记录*/
User user=new User(1,name,"/sdcard/avtar/"+(name+1)+".png");//greenDAO的主键是Long型,如果传入null,则GreenDao会默认设置自增长的值
try{
GreenDAOApplication.getDaoSessionins().getUserDao().insert(user);
}catch(Exception e){}
try{
GreenDAOApplication.getDaoSessionins().getUserDao().deleteByKey(id);
}catch(Exception e){}
根据实体类删除一条记录这个有多种方式:直接调用delete(Entity entity)和先查询再通过QueryBuilder
User user = new User((long)1, "crazymo","",false);
try{
GreenDAOApplication.getDaoSessionins().getUserDao().delete(user);
}catch(Exception e){}
List list = getUserList();
GreenDAOApplication.getDaoSessionins().getUserDao().deleteInTx(list);
public void deleteUserInfo(int userId){
QueryBuilder qb = GreenDAOApplication.getDaoSessionins().getUserDao().queryBuilder();
DeleteQuery bd = qb.where(Properties._id.eq(userId)).buildDelete();
bd.executeDeleteWithoutDetachingEntities();
}
try{
GreenDAOApplication.getDaoSessionins().getUserDao().deleteAll();
}catch(Exception e){}
例如update USER SET age =20 WHERE name = “CrazyMo_” 这样一个语句在greenDao中怎么执行的,始终记住一句话,greenDao 对对象的增,删,改,查 就是对数据库的增,删,改,查,被查询出的对象被修改后,在替换原来自己的对象就可以了
User user=new User(1,name,"/sdcard/avtar/"+(name+1)+".png");
try{
GreenDAOApplication.getDaoSessionins().getUserDao().update(user);
}catch(Exception e){}
String updateName = content.getText().toString().trim();
QueryBuilder qb2 = userDao.queryBuilder();
qb2.where(Properties.Name.eq("CrazyMo_"));
List update = qb2.list();
String newName = content.getText().toString().trim();
for (User user : update) {
user.setAge(20);
userDao.insertOrReplaceInTx(user);
}
在数据库的四个基本操作中查询是比较复杂的,优先使用QueryBuilder API,使用更为简单方面而且支持惰性加载(当处理一个较大的结果集时,lazy-loading(懒加载模式)可以节省内存提高性能),在更为复杂的查询的情况下还支持原始SQL查询。
通过DAO的queryBuilder方法获取QueryBuilder 实例,得到查询主句(即Select 子句部分)
调用QueryBuilder 的成员方法根据需求分别构造Where条件子句、Join子句、Order子句等等
调用QueryBuilder 的获取数据集合方法 list系 得到返回数据集,相当于是执行了完整SQL语句。
//查询用户中FirstName为CrazyMo_的所有用户的信息,等价于Select * from User where FirstName=“Mo” order by LastName asc
QueryBuilder qb = userDao.queryBuilder(); //构造QueryBuilder对象
qb.where(Properties.FirstName.eq("Mo")) //添加Where查询条件子句
.orderAsc(Properties.LastName) //添加排序子句
.list(); //返回查询结果
Query query = userDao.queryBuilder()
.where(new WhereCondition.StringCondition("_ID IN (SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)"))
.build();
query.list();
public boolean isSaved(int _id){
QueryBuilder qb = GreenDAOApplication.getDaoSessionins().getUserDao().queryBuilder();
qb.where(Properties.Id.eq(_id));
qb.buildCount().count();
return qb.buildCount().count() > 0 ? true : false;
}
public List getAllUser(){
return QueryBuilder qb = GreenDAOApplication.getDaoSessionins().getUserDao().queryBuilder().list();
/* try {
GreenDAOApplication.getDaoSession().getUserDao().queryBuilder().listLazy();
}catch (Exception e){
。。。
}*/
}
返回的Query对象是可以多次重复查询的,如果查询条件没有改变直接再调用一次就好,而条件更新了可以通过调用setParameter()方法来更新参数完成再次筛选,避免了多次构建Query对象。
/*等价于Select * from User where FirstName=“Mo” and YearOfBirth=1999*/
Query query = GreenDAOApplication.getDaoSessionins().getUserDao().queryBuilder().where(
Properties.FirstName.eq("Mo"), Properties.YearOfBirth.eq(1999))
.build();
List list= query.list();
查询FirstName为Crazy,YearOfBirth为199的人
query.setParameter(0, "Crazy");//前面0代表条件的序号,通过条件的序号更改查询条件。
query.setParameter(1, 2000);
List list= query.list();