GreenDao查询,Querying

简介: GreenDao查询,Querying

举例:


    /**
     * 查询用户列表
     */
    public List<data_new> queryUserList(String path) {
        DaoMaster daoMaster = new DaoMaster(getReadableDatabase());
        DaoSession daoSession = daoMaster.newSession();
        data_newDao userDao = daoSession.getData_newDao();
        QueryBuilder<data_new> qb = userDao.queryBuilder();
        qb.where(data_newDao.Properties.NUMBERING.gt(path));
//                .orderAsc(data_newDao.Properties.PhoneNumber);
        List<data_new> list = qb.list();
        return list;
    }
    //
    public List<data_new> queryUser(String numbering) {
        DaoMaster daoMaster = new DaoMaster(getReadableDatabase());
        DaoSession daoSession = daoMaster.newSession();
        data_newDao userDao = daoSession.getData_newDao();
        QueryBuilder<data_new> qb = userDao.queryBuilder();
//        qb.where(data_newDao.Properties.NUMBERING.gt(numbering));
        qb.where(data_newDao.Properties.NUMBERING.eq(numbering));
//                .orderAsc(data_newDao.Properties.PhoneNumber);
        List<data_new> list = qb.list();
        return list;
    }

查询


查询接口返回符合指定条件的实体对象集合.你可以使用SQL组织你的查询语句,或者采用更好的方法,使用greenDao的QueryBuilder API.greenDao的查询也支持延迟加载结果,当结果集很大的时候,它会节省内存和提高性能.


1.QueryBuilder


QueryBuilder类让你不需要写SQL来构建查询条件.写SQL大多数人都不喜欢,并且容易出错,因为它需要在运行时才能反馈错误.QueryBuilder容易使用并且不需要写SQL.使用它,相比只想代码不容易产生bug,它的语法在编译时候就会检查完.以greenDao为基础的代码生成的方法,使编译时的检查项能包括每一个属性的引用.


例如:查询以Joe为名,以姓排序的所有用户.

  1. List joes = userDao.queryBuilder()
  2. .where(Properties.FirstName.eq("Joe"))
  3. .orderAsc(Properties.LastName)
  4. .list();


嵌套条件的例子:获取出生在1970年10月以后名为Joe的所有用户. 我们将用户生日对应到实体的年、月、日属性.我们使用更正式的形式将查询条件表达为:名是Joe AND(生日的年份大于1970 OR(生日的年是1970 AND 生日的月等于或大于10))


  1. QueryBuilder qb = userDao.queryBuilder();
  2. qb.where(Properties.FirstName.eq("Joe"),
  3. qb.or(Properties.YearOfBirth.gt(1970),
  4. qb.and(Properties.YearOfBirth.eq(1970), Properties.MonthOfBirth.ge(10))));
  5. List youngJoes = qb.list();


2.Query类和LazyList类


Query类对象代表一个可以被多次执行的查询.当你使用QueryBuilder中的一个方法来获取结果(如一个list()方法),QueryBuilder内部使用Query类.如果你要以相同的条件多次查询,你可以调用QueryBuilder的build()方法来产生一个Query,不需要执行它.


greenDao支持唯一结果(0或1个结果)、和多个结果的查询.如果你期望唯一的结果,调用Query或者QueryBuilder的unique()方法,它会给你唯一的结果或者null(如果没有找到匹配的实体).如果你的情况不允许null作为结果,调用uniqueOrThrow(),它会保证返回非空的实体(如果没有匹配的结果,它会抛出DaoException异常).


如果查询时你期望返回多个结果,你可以调用list...中的一个方法:

:--:|:--:

list()|所有实体加载到内存.结果是一个典型的ArrayList.容易使用


listLazy()|实体根据需要加载到内存.一旦列表中一个元素被使用,这个元素会被加载和缓存起来,给后续重复使用.使用完后需要关闭 listLazyUncached()|一个虚拟的实体列表:任何请求列表中的元素将会触发从数据库加载数据.使用后必须关闭 listIterator()|让你使用迭代器来遍历结果集,它根据需要加载数据(延迟加载).数据没有缓存,使用后必须关闭


listLazy、listLazyUncached和listIterator 使用了greenDao的LazyList类.为了使用时才加载数据,它保存了数据库游标的引用.这也是使用后必须调用关闭方法的原因(一般在try/finally代码块中关闭).一旦所有的元素被访问或遍历到,listLazy()返回有缓存、延迟加载列表和listIterator()返回的延迟加载迭代器会自动关闭数据库游标.如果数据的访问过早的结束了(没有遍历完全),那么关闭数据库游标是你要做的的工作.


3.使用Queries进行多次查询


一旦你使用QueryBuilder构造了一个query,这个query对象后续可以重复使用,来执行查询.这比总是创建新的Query对象要更有效.如果查询条件没有变,你只需要再次调用其中一个list/unique方法.如果参数有改变,你必须对改变的参数调用setParameter方法.目前,各个参数以0开始的索引来区分.对应你传入参数到QueryBuilder的索引.


下面的例子使用Query对象来查询"名"为Joe,出生在1970年的用于:

  1. Query query = userDao.queryBuilder().where(
  2. Properties.FirstName.eq("Joe"), Properties.YearOfBirth.eq(1970))
  3. .build();
  4. List joesOf1970 = query.list();


使用这个Query对象,我们查找名为Marias,出生在1977年的用户:

  1. query.setParameter(0, "Maria");
  2. query.setParameter(1, 1977);
  3. List mariasOf1977 = query.list();


4.在多线程中执行查询


如果你想在多线程中使用查询,你必须对query对象调用forCurrentThread()方法来获取一个当前线程的Query实例.从greenDao1.3以后,Query的实例对象绑定到构建query的线程中.这样,你可以安全的对Query对象设置参数而不受其他线程的干扰.如果其他线程试图对query对象设置参数或者执行绑定在其他线程的查询,greenDao会抛出异常.这样,你就不需要使用同步语句.事实上,我们应该避免使用锁,因为如果并发事务使用同一个Query对象,它会导致死锁.


为了完全避免潜在的死锁,greenDao1.3引入了forCurrentThread()函数.它会返回本线程的Query实例,它在当前线程可以安全的使用.每次调用forCurrentThread(),传入的参数和使用QueryBuilder构造Query的参数一致.


5.原始查询


获取数据,有两种方法来执行原始的SQL.比较好的方法是使用QueryBuilder和WhereCondition.StringCondition. 使用它,你可以向QueryBuilder传入任何的SQL WHERE子句片段.下面的代码是一个笨拙的方法,它让你使用一个select子句来起到join的效果


  1. Query query = userDao.queryBuilder().where(
  2. new StringCondition("_ID IN " +
  3. "(SELECT USER_ID FROM USER_MESSAGE WHERE READ_FLAG = 0)").build();


碰到QueryBuilder没有提供你需要的特性时(例如上面的join关键字),你可以回到原始的查询语句或者原始查询语句的构造方法.他们允许传入原始SQL字符串,追加到SELECT + 实体列名后面.通过这种方法,你可以拼好任意WHERE和ORDER BY子句,来查询数据库中的对象.实体表名用别名"T"来称呼:


下面的例子展示了如何使用join创建query对象,它查找组名为"admin"的用户群.

  1. Query query = userDao.queryRawCreate(
  2. ", GROUP G WHERE G.NAME=? AND T.GROUP_ID=G._ID", "admin");


注意:你可以使用生成的常量来指向表和列名.这是推荐的做法,它可以避免错别字,因为编译器会检查名字.在实体对应的Dao类中,你会找到TABLENAME,它持有数据库表的名字.Dao类中还有一个Properties内部类 ,包含所有的属性常量(对应数据库列名).


6.删除查询


批量删除会删除符合条件的实体.想要行批量删除,需要创建一个QueryBuilder,调用它的buildDelete方法,执行返回的DeleteQuery.这部分的api将来可以会修改,例如,会添加便利的方法.记住,批量删除目前不会影响identity scope中的实体,例如实体已经有缓存并且是调用传入ID来获取的函数,你可以"复活"他们.如果这里给你的情况带来一些问题,你可以考虑清除identity scope.


7.查找查询中的问题


你的查询没有返回你期望的值?这里有2个静态的标识,一个是将sql语句打印出来,一个是将传入QueryBuilder的参数打印出来:


  1. QueryBuilder.LOG_SQL = true;
  2. QueryBuilder.LOG_VALUES = true;


这些日志会记录生成的sql命令和调用build()方法传入的参数.这样你可以对比他们是不是你预期的.这也帮助你们拷贝sql语句到其他数据库浏览工具,并执行他们获取结果。


目录
相关文章
|
索引
Entity Framework 索引
Entity Framework 索引
237 0
|
SQL Java 数据库连接
Hibernate-ORM:15.Hibernate中的Criteria查询
    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------         本篇博客讲师Hibernate中的Criteria查询! 一,Criteria简介:   刚接触Hibernate的时候,就有一个概念,全自动的ORM框架,不用写...
1025 0
|
SQL Java Spring
Spring Data之@Query中的org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML
Spring Data之@Query中的org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML 1.
1711 0
|
数据库 .NET 开发框架
|
关系型数据库 MySQL
|
SQL Java 数据库连接
HQL: The Hibernate Query Language
Chapter 14. HQL: The Hibernate Query Language 14.1. Case Sensitivity 14.2. The from clause 14.
1498 0