常见用法可见官方文档: https://docs.grails.org/3.3.8/ref/Domain%20Classes/createCriteria.html
这里说一下文档中没有的, 比如联表查询和分页查询.
先新建两个domain:
学生表:
/**
* 学生信息
*/
class Student{
/** 学号*/
String stdNo
/** 学生姓名*/
String stdName
/** 性别 "0":"女", "1":"男"*/
String gender
/** 学院*/
Dept dept
}
学院表:
/**
* 学院信息
*/
class Dept{
/** 学院编号*/
String deptNo
/** 学院名称*/
String deptName
/** 院长*/
String leaderName
}
查询主要通过 Criteria 对象中的 list 方法进行. 先看看接口:
/**
* Defines and executes a list query in a single call. Example: Foo.createCriteria().list { }
* @param closure The closure to execute
*
* @return The result
*/
Object list(@DelegatesTo(Criteria.class) Closure closure);
/**
* Defines and executes a list query in a single call. Example: Foo.createCriteria().list { }
*
* @param params pagination parameters (max, offset, etc...)
* @param closure The closure to execute
*
* @return The result
*/
Object list(Map params, @DelegatesTo(Criteria.class) Closure closure);
可以看到, list方法有两个, 第一个有一个参数, 类型为闭包; 第二个有两个参数, 依次为Map和闭包; 看注释可知, 我们需要用到第二个list方法.
1.模糊查询
// 每页数据量
int pageSize = json.optInt("table_pageSize", 10)
// 页码
int page = json.optInt("table_page", 1)
// 搜索内容
def searchContent=json.optString("table_search").trim()
def criteria = Student.createCriteria()
def list = criteria.list(max:pageSize,offset:page-1) {
createAlias("dept","b", JoinType.LEFT_OUTER_JOIN)
or {
ilike("stdName","%${searchContent}%")
ilike("b.deptName","%${searchContent}%")
ilike("b.leaderName","%${searchContent}%")
}
order("stdNo","asc")
}
createAlias 行用于创建Student表中dept关联表的别名, 使用时用 别名"点"属性 即可; JoinType是 org.hibernate.sql.JoinType的枚举, 旧版中用的是 org.hibernate.criterion.CriteriaSpecification 接口, 已过时.
2.查出的结果用 list 参数接收, 可以用
def dataCount = list.totalCount as Long
获取数据总数.
这样, 一个列表查询就算完成了
如果要查别名中关联的表信息, 用别名创建别名, 如Dept表中还有一个字段
class Dept {
...
/** 院长*/
Teacher leader
}
class Teacher {
/** 教职编号*/
String tchNo
/** 教职姓名*/
String tchName
/** 性别 "0":"女", "1":"男"*/
String gender
/** 类型 "1":"授课老师", "2":"行政人员"*/
String tchType
}
在创建别名时,第一个参数为别名中的属性, 如下:
createAlias("b.leader","c", JoinType.LEFT_OUTER_JOIN)
注意别名创建的先后顺序.
另外还有一种查询方法, 可以直接用表字段接闭包进行查询:
criteria.list(max:pageSize,offset:page-1){
dept{
or {
ilike("leaderName","%${searchContent}%")
leader {
ilike("tchName","%${searchContent}%")
}
}
}
}
两种方式的结果都一样. 第一种符合 sql 语言习惯; 第二种具有独特的逻辑层次感. 没有优劣之分.