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

来源:互联网 发布:火线精英刷枪软件 编辑:程序博客网 时间:2024/06/06 23:18

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

          原文档: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不支持这种特
性。你只能使用它从一张表中获得数据。


2 0
原创粉丝点击