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<T,?> dao) | 构造方法是保护的,不能通过其构造方法获取对象 |
QueryBuilder<T> distinct() | 去重查询,相当于是在SQL语句中加了distinct |
QueryBuilder<T> where(WhereCondition cond, WhereCondition… condMore) | 条件子句,相当于SQL中的Where |
QueryBuilder<T> whereOr(WhereCondition cond1, WhereCondition cond2, WhereCondition… condMore) | 或条件查询 |
WhereCondition and(WhereCondition cond1, WhereCondition cond2, WhereCondition… condMore) | 且条件 |
QueryBuilder<T> orderAsc(Property… properties) | Order 子句 |
QueryBuilder<T> limit(int limit) | 分页查询 |
DeleteQuery<T> buildDelete() | 删除 |
List<T> list() | 执行Query并把返回集合,并且entity都会加载到内存中,返回的结果通常就是ArrayList |
LazyList listLazy() | Entity按需加载到内存中,在第一次访问list中的element时,它就会呗加载并且缓存。 |
LazyList listLazyUncached() | 每次访问结果集的时候都是从数据库中加载,而不使用缓存。 |
LazyList listIterator() | 通过迭代器访问结果集,并且采用的时lazy-loading,结果不会缓存。 |
T unique() | 返回唯一的数据 |
尽管QueryBuilder已经很强大,但是假如还是不能满足你的需求,greeDAO还支持原始的SQL语句,主要有两种方式:
QueryBuilder,WhereConditon,StringCondition结合//嵌套子查询,userDao.queryBuilder() 这句执行了之后就相当于是Select * from UserQuery query = userDao.queryBuilder().where(new StringCondition("_ID IN " +"(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)").build();采用queryRaw或者queryRawCreate方法传入一个原始的SQL,它将被追加到SELECT和columns之后。这样,就可以使用Where和Order by来选择entities,此外表还可以使用别名“T”。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<T> 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<T>和QueryBuilder<T>都是可以用于构造SQL并且执行SQL,不同的是QueryBuilder还支持条件、排序子句的构造,而Query既可以完全不依赖QueryBuilder,全部用原始SQL来代替,也可以主句(即Select * from table 这段用QueryBuilder)后面的子句用原始的SQL来执行,两者都支持查询并返回集合。
前面所讲一个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){}根据实体类删除一条记录这个有多种方式:直接调用delete(Entity entity)和先查询再通过QueryBuilder
User user = new User((long)1, "crazymo","",false);try{ GreenDAOApplication.getDaoSessionins().getUserDao().delete(user);}catch(Exception e){} List<User> list = getUserList(); GreenDAOApplication.getDaoSessionins().getUserDao().deleteInTx(list);例如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<User> 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 ascQueryBuilder 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();返回的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();新闻热点
疑难解答