Grails框架中用createCriteria构建复杂查询

  常见用法可见官方文档: 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 语言习惯; 第二种具有独特的逻辑层次感. 没有优劣之分.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值