文档章节

ORMLite完全解析(三)官方文档第三章、自定义查询构造器 Custom Query Builder

k
 kim366
发布于 2016/05/13 19:17
字数 2128
阅读 13
收藏 0

          接着上一篇,下面是第三章的翻译整理,理解错误的地方还请批评指正。

          原文档:http://ormlite.com/javadoc/ormlite-core/doc-files/ormlite_3.html#Statement-Builder

          尊重原创,转载请说明出处,谢谢! http://blog.csdn.net/oyangyujun


 第三章、 自定义查询构造器


3.1  查询构造器基础
      下面是使用查询构造器创建自定义查询语句的基本步骤。首先,以java常量的形式为属性设置列名,便于使用它
们进行查询。
       @DatabaseTable(tableName = "accounts")
      public class Account {
           public static final String PASSWORD_FIELD_NAME = "password";
            …
           @DatabaseField(canBeNull = false, columnName = PASSWORD_FIELD_NAME)
           private String password;
           …

       这样就允许我们使用password属性构建查询,而不需要在后面的查询中重命名属性,及时属性名,和列名一样也
应该这样做。
         // get our query builder from the DAO
       QueryBuilder<Account, String> queryBuilder = accountDao.queryBuilder();
       // the 'password' field must be equal to "qwerty"
       queryBuilder.where().eq(Account.PASSWORD_FIELD_NAME, "qwerty");
       // prepare our sql statement
       PreparedQuery<Account> preparedQuery = queryBuilder.prepare();
       // query for all accounts that have "qwerty" as a password
       List<Account> accountList = accountDao.query(preparedQuery);
       如上面的代码,你可以通过Dao.queryBuilder()方法获得一个QueryBuilder对象,然后调用这个对象的方法,调
用queryBuilder.prepare()函数获得一个PrepareQuery对象,然后,将这个PrepareQuery方法传递到DAO的查询或者
遍历方法中。

      简化操作,可以在Where对象中调用prepare()方法,如下所示:
       // query for all accounts that have that password
      List<Account> accountList = accountDao.query(
         accountDao.queryBuilder().where()
         .eq(Account.PASSWORD_FIELD_NAME, "qwerty")
         .prepare());        
      也可以使用另外一种简化方法,通过QueryBuilder或者Where对象调用query()方法或者iterator()方法。如下:
       // query for all accounts that have that password
      List<Account> accountList =
         accountDao.queryBuilder().where()
         .eq(Account.PASSWORD_FIELD_NAME, "qwerty")
         .query();


3.2 构建查询语句
      下面是一些不相同的构建查询语句的方式。QueryBuilder类已经针对特殊使用和强大的用户进行了内部封装。
       QueryBuilder<Account, String> queryBuilder =
      accountDao.queryBuilder();
      // get the WHERE object to build our query
      Where<Account, String> where = queryBuilder.where();
      // the name field must be equal to "foo"
      where.eq(Account.NAME_FIELD_NAME, "foo");
      // and
      where.and();
      // the password field must be equal to "_secret"
      where.eq(Account.PASSWORD_FIELD_NAME, "_secret");
      PreparedQuery<Account> preparedQuery = queryBuilder.prepare();
      上面的语句会生成下面这样的sql语句
       SELECT * FROM account  WHERE (name = 'foo' AND password = '_secret')

       如果你喜欢使用方法链进行操作,则上面的语句也可以这样写:
        queryBuilder.where()
       .eq(Account.NAME_FIELD_NAME, "foo")
       .and()
       .eq(Account.PASSWORD_FIELD_NAME, "_secret");

       如果你喜欢使用括号将比较语句组合在一起,也可以这样用:
        Where<Account, String> where = queryBuilder.where();
       where.and(where.eq(Account.NAME_FIELD_NAME, "foo"),
       where.eq(Account.PASSWORD_FIELD_NAME, "_secret"));

      上面的三种调用方式会生成相同的sql语句。对于混合mixANDs和ORs的复杂查询而言,最后一种格式必须正确组装
,如下面这个查询:
       Where<Account, String> where = queryBuilder.where();
      where.or(
           where.and(
               where.eq(Account.NAME_FIELD_NAME, "foo"),
               where.eq(Account.PASSWORD_FIELD_NAME, "_secret")
           ),
           where.and(
               where.eq(Account.NAME_FIELD_NAME, "bar"),
               where.eq(Account.PASSWORD_FIELD_NAME, "qwerty")
           )
       );

       这个语句会长生下面这样的sql语句:
        SELECT * FROM account
       WHERE ((name = 'foo' AND password = '_secret')
           OR (name = 'bar' AND password = 'qwerty'))

       查询语句也允许指定需要查询返回的列,指定ORDER BY和GROUP BY属性,以及各种各样的sql特点,比如(LIKE,IN,>,>=,<, <=,<>, IS NULL, DISTINCT,...),具体细节查看Where Capabilities这节。也可以查看good SQL reference site中关于QueryBuilder和Where语句的java文档介绍。
 
   
3.3  构建更新和删除语句
    DAO对象也可以用于构建自定义的UPDATE和DELETE语句,UPDATE语句用于改变满足Where条件的数据行中特定的属
性的值,或者,如果没有指定where的话,用于更改所有数据行的属性值。delete语句用于删除满足条件的数据行,
如果没有条件限制,则用于删除所有数据。
    例如,如果你想要更新全部Account中passwords为null的值为“none”,可以使用下面的语句。
     UpdateBuilder<Account, String> updateBuilder =
    accountDao.updateBuilder();
    // update the password to be "none"
    updateBuilder.updateColumnValue("password", "none");
    // only update the rows where password is null
    updateBuilder.where().isNull(Account.PASSWORD_FIELD_NAME);
    updateBuilder.update();

    通过update语句,也可以指定表达式更新
     // update hasDog boolean to true if dogC > 0
    updateBuilder.updateColumnExpression("hasDog", "dogC > 0");

    为了便于构造你的表达式,可以使用UpdateBuilder的escape方法escapeColumnName和escapeValue值,这个两个
方法可以携带一个String或者StringBuffer,这样可以避免列名和关键字冲突。
    如果你想删除Account表中password为null的一行,可以使用下面的语句完成。
     DeleteBuilder<Account, String> deleteBuilder = accountDao.deleteBuilder();
    // only delete the rows where password is null
    deleteBuilder.where().isNull(Account.PASSWORD_FIELD_NAME);
    deleteBuilder.delete();


3.4  Query功能
    下面是关于QueryBuilder各种查询调用的详情。可以查看QueryBuilder类的最新JavaDoc文档获取更多信息。大
多数的方法都是返回QueryBuilder对象,以便使用方法链。
    具体细节参考 tutorial of SQL commands.中的详情。
    主要方法包括:
     distinct()
    groupBy(String columnName)
    groupByRaw(String sql)
    having(String sql)
    join(QueryBuilder joinedQueryBuilder)
    leftJoin(QueryBuilder joinedQueryBuilder)
    limit(Integer maxRows)
    offset(Integer startRow)
    orderBy(String columnName, boolean ascending)
    orderByRaw(String sql)
    prepare()
    selectColumns(String... columns)
    selectColumns(Iterable<String> columns)
    selectRaw(String... columns)
    where()
    query()
    queryForFirst()
    queryRawFirst()
    iterator()
    reset()


3.5  Where功能
    下面是关于查询功能的详解,更多细节参考tutorial of SQL commands.
    主要方法包括:  
     and()
    and(Where<T, ID> first, Where<T, ID> second, Where<T, ID>... others)
    and(int numClauses)
    between(String columnName, Object low, Object high)
    eq(String columnName, Object value)
    exists(QueryBuilder<?, ?> subQueryBuilder)
    ge(String columnName, Object value)
    gt(String columnName, Object value)
    idEq(ID id)
    idEq(Dao<OD, ?> dataDao, OD data)
    in(String columnName, Iterable<?> objects)
    in(String columnName, Object... objects)
    in(String columnName, QueryBuilder<?, ?> subQueryBuilder)
    isNull(String columnName)
    isNotNull(String columnName)
    le(String columnName, Object value)
    lt(String columnName, Object value)
    like(String columnName, Object value)
    ne(String columnName, Object value)
    not()
    not(Where<T, ID> comparison)
    notIn(String columnName, Iterable<?> objects)
    in(String columnName, Object... objects)
    notIn(String columnName, QueryBuilder<?, ?> subQueryBuilder)
    or()
    or(Where<T, ID> first, Where<T, ID> second, Where<T, ID>... others)
    or(int numClauses)
    raw(String rawStatement)
    prepare()
    reset()
    query()
    queryRaw()
    queryForFirst()
    queryRawFirst()
    countOf()
    iterator()


3.6  使用select参数
    select参数是一种使用在Where操作中的参数,这种参数可以直接指定为参数值(如上例子所示),或者作为一
个select参数对象。select参数可以用于后续设置参数值,他们会产生SQL ‘?’,类似于jdbc的占位符。
    例如:  
     QueryBuilder<Account, String> queryBuilder = accountDao.queryBuilder();
    Where<Account, String> where = queryBuilder.where();
    SelectArg selectArg = new SelectArg();
    // define our query as 'name = ?'
    where.eq(Account.NAME_FIELD_NAME, selectArg);
    // prepare it so it is ready for later query or iterator calls
    PreparedQuery<Account> preparedQuery = queryBuilder.prepare();

    // later we can set the select argument and issue the query
    selectArg.setValue("foo");
    List<Account> accounts = accountDao.query(preparedQuery);
    // then we can set the select argument to another
    // value and re-run the query
    selectArg.setValue("bar");
    accounts = accountDao.query(preparedQuery);

    人们通常会试着创建一些具有参数的查询语句,并包含一些特定的符号,这些符号能自动生成sql语句,并导致
语法错误。在这种情况下可以使用SelectArg。此外,如果你的参数使用户输入的,那么使用SelectArgs可以保护你
的程序避免sql注入问题。其次,特定的数据类型可以使用一种内部的SelectArg对象,因为对象的String值对于数据
库而言是不可靠的。例如java.util.Date。
    注意:SelectArg对象不能再一个对象的多列中使用,如果你想要在另外一列中使用SelectArg,你必须重新实例
化一个新的对象。


3.7  使用列参数
    假如你使用QueryBuilder让一个值和列数据进行比较。那么可以使用ColumnArg:
    例如:      
     QueryBuilder<Account, String> queryBuilder = accountDao.queryBuilder();
    // list all of the accounts that have the same
    // name and password field
    queryBuilder.where().eq(Account.NAME_FIELD_NAME, new ColumnArg(Account.PASSWORD_FIELD_NAME));
    List<Account> results = queryBuilder.query();
   
    ColumnArg也可以携带一个表名,这种方式在JION查询中用于比较一个表中的列和另一个表中的列的数据时比较
有用。详情查看Building Join Queries一节。


3.8  构建连接查询
    ORMLite支持基本的JION SQL查询,更多内容可查看JOIN documentation.
    通过两个QueryBuilder对象创建一个join查询,其中一个在DAO中,用于返回你的对象,另一个DAO与第一个DAO
相关联。其中一个必须是另一个的外部属性,否则,jion方法会抛出异常。
    例如:假设你想要获得一个account集合,并且这些account有一个订单的amount值大于100刀。则可以这样写:
     QueryBuilder<Order, Integer> orderQb = orderDao.queryBuilder();
    orderQb.where().ge("amount", 100.0F);
    QueryBuilder<Account, Integer> accountQb = accountDao.queryBuilder();
    // join with the order query
    List<Account> results = accountQb.join(orderQb).query();
    这里返回了所有的Account记录,并且,这些对象有一个对应的订单,这个订单有一个属性值大于100.
    ORMLite也支持LEFTJOIN的概念,意思是,在上面的例子中,在上面的语句中,没有订单的account也会被返回。
但是,ORMLite不支持RIGHT JOIN 和 FULL JOIN的概念。
    注意,其他的ORM库使用JOIN语句从多张表中获取数据填充外部对象属性和外部对象集合。ORMLite不支持这种特
性。你只能使用它从一张表中获得数据。


本文转载自:http://blog.csdn.net/oyangyujun/article/details/45938905

共有 人打赏支持
k
粉丝 1
博文 129
码字总数 0
作品 0
朝阳
私信 提问
ServiceStack.OrmLite

A Fast, Simple, Typed ORM for .NET OrmLite's goal is to provide a convenient, DRY, config-free, RDBMS-agnostic typed wrapper that retains a high affinity with SQL, exposing intu......

postdep
2014/10/13
0
1
如何在Eclipse中查看Android源码或者第三方组件包源码

在学习过程中如果经常阅读源码,理解程度会比较深,学习效率也会比较高,那么如何方便快捷的阅读Android源码? 如何查看Android源码[以Android2.2为例] 我们知道在Eclipse里按住Ctrl键不松手...

鉴客
2011/11/14
13.8K
3
A Fast, Simple, Typed ORM for .NET

Join the ServiceStack Google+ group or follow @servicestack for updates. A Fast, Simple, Typed ORM for .NET OrmLite's goal is to provide a convenient, DRY, config-free, RDBMS-ag......

postdep
2014/09/12
0
0
android 编程时,如何在Eclipse中查看Android源码或者第三方组件包源码

相信大多数人都知道怎么在eclipse中看android源码,但是在eclipse中看第三方源码的方法呢,我查看到这篇博文之前我不知道,可能是我才疏学浅,可能很多大牛都知道了,我在这里还是转过来,希...

anonymouos
2013/09/08
0
1
Android SQLite相关框架工具

我是一个Android新手,以前做的Web应用,公司需要,我转了Android,最近发现SQLite数据库代码开发工作量很大,颠来倒去就是创建表、删除表、查询、更新等操作,所以想找个工具(像Hibernate...

你我的宿命
2013/03/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Cloud Alibaba Sentinel 整合 Feign 的设计实现

作者 | Spring Cloud Alibaba 高级开发工程师洛夜 来自公众号阿里巴巴中间件投稿 前段时间 Hystrix 宣布不再维护之后(Hystrix 停止开发。。。Spring Cloud 何去何从?),Feign 作为一个跟 ...

Java技术栈
5分钟前
1
0
虚拟机加密

在超融合的基础设施和虚拟化成为常态的世界里,对加密的要求越来越高,越来越迫切,IT部门需考虑的重大安全问题和方法也浮现了出来。 物理数据中心时代,采取双保险式数据安全方法是相对简单...

linuxCool
9分钟前
0
0
MySQL 主从同步

MySQL主从介绍 MySQL主从又叫做Replication、AB复制。简单讲就是A和B两台机器做主从后,在A上写数据,另外一台B也会跟着写数据,两者数据实时同步的 MySQL主从是基于binlog的,主上须开启bin...

野雪球
21分钟前
0
0
OSChina 周一乱弹 —— 温柔的人应该这样

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @clouddyy :#每日一歌# 《フィクション-sumika》 《フィクション-sumika》 手机党少年们想听歌,请使劲儿戳(这里) 假期时间干嘛去, @for...

小小编辑
今天
156
7
[LintCode] Serialize and Deserialize Binary Tree(二叉树的序列化和反序列化)

描述 设计一个算法,并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”。 如何反序列化或序列化二叉树是没有限制的,你...

honeymose
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部