复杂的SQL条件
By:zozoh<zozohtnt@gmail.com>

概述

Top

什么是 Nutz.Dao 中的复杂SQL条件

Top

Nutz.Dao 将如何如何使用这个条件

Top

Condition 接口

Top

Nutz 给你的快速实现

Top

一个友好的工具类 -- Cnd

Top

有些情况,数据库中的字段同 Java 对象中的字段并不同名,所以就需要给 Java 字段上的数据库字段注解加上参数 @Column("数据库字段名")如果你通过 Cnd.wrap() 硬编码某个字段,那么当这个字段数据库字段名发生改变时,你就需要改动很多。因此你希望仅仅将对于数据库的变动限制在 Java 对象的源文件里所以 Nutz 提供了 Cnd.where() 方法

Condition c = Cnd.where("age",">",30).and("name", "LIKE", "%K%").asc("name").desc("id");

这个条件将生成 SQL

WHERE age>30 AND name LIKE '%K%' ORDERBY name ASC, id DESC

你也可以嵌套表达式

SqlExpressionGroup e1 = Cnd.exps("name", "LIKE", "P%").and("age", ">", "20");
SqlExpressionGroup e2 = Cnd.exps("name", "LIKE", "S%").and("age", "<", "30");
Condition c = Cnd.where(e1).or(e2).asc("name");

这个条件将生成 SQL

WHERE (name LIKE 'P%' AND age>'20') OR (name LIKE 'S%' AND age<'30') ORDER BY name ASC

直接硬编码(不推荐)

Top

最暴力的方法就是直接输出 WHERE 关键字后面的 SQL 代码了。比如查询一个 Person 对象

List<Person> crowd = dao.query(Person.class, Cnd.wrap("name LIKE 'J%' AND age>20"), null);

部分暴力,使用Static

// 筛选年龄(age)小于20,现金(cash字段)多于负债(due字段)的XX
List<Pet> list = dao.query(Girl.class, Cnd.where("age", "<", 20).and(new Static("cash > due")));

拼装更加复杂的条件

Top

上面的例子的 Cnd.where 函数,在大多数情况下可以快速的生成一个简单的查询条件。但是,如果查询条件非常复杂,用它可能就比较费劲了。是的,它的设计初衷就是 " 查询条件应该一行搞定"。

有些时候,查询条件很复杂,一行确实搞不定,怎么办? Nutz-1.b.38 以后,提供了 Criteria 接口,它继承自Condition 接口,它的设计目的有两个:

  1. 让程序员更容易的拼装复杂逻辑的条件
  2. 让生成的 SQL 可以被参数化,更好的支持 PreparedStatement

这个接口的使用也很简单,它基本符合 "IDE 的所见即所得" 接口设计原则。 就是说,如果你的 IDE 有智能提示的话,你使用这个接口是不需要文档的。

// 创建一个 Criteria 接口实例
Criteria cri = Cnd.cri();

// 组装条件
if(...){
    cri.where().andIn("id", 3,4,5).andIn("name", "Peter", "Wendal", "Juqkai");
}else if(...){
    cri.where().andLT("id", 9);
}

if(...){
    cri.where().andLike("name", "%A%");
}

cri.getOrderBy().asc("name").desc("id");

// 执行查询
List<MyObj> list = dao.query(MyObj.class, cri, null);

Criteria 的 where() 函数返回的是 SqlExpressionGroup,主要由它来提供各种 SQL 条件的组合方法。这里需要给出一点提示,比如方法名 andGT,表示的是 andGreatThan,即"大于" 的意思,同理:

模糊查询的小提示

Top

如下代码,当str的长度大于1和等于1时的行为有差异

Cnd cnd = Cnd.where("name", "like", str);
// 若str的长度为1,输出的SQL是
// where name like "%a%"
// 若str的长度为2,输出的SQL是
// where name like "ab"

正确的写法是

Cnd cnd = Cnd.where("name", "like", "%" + str + "%s");