Hibernate的Disjunction和Conjunction

本文介绍如何利用Hibernate Criteria API中的Disjunction和Conjunction来构建更灵活的查询条件,通过自定义SQL增强查询功能,并展示了不同组合方式对查询结果的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于Disjunction和Conjunction的如何使用?

本人在学习阶段也曾在百度搜索,但是找到后,感觉描述的不太直白,思考良久才看懂是什么意思。故此在此小结一下。

Oracle数据库的scott用户下的Emp 和Dept表为例

假如我们现在面临这样的一个问题

 /*
     * 1.从员工表里面查询出20号部门下名字里包含S,或者工资在800以上。 
     * 并且职位名称开头带有M or comm属性不位null 的人。
     * 要求:使用hibernate的Criteria相关技术实现
    */

当我们遇到这样的问题时,可能首先会想到这样做

Criteria criteria = session.createCriteria(Emp.class);
        Dept d = new Dept();
        d.setDeptno((byte) 20);
        criteria.add(Restrictions.or(
                Restrictions.like("ename", "S", MatchMode.ANYWHERE),
                Restrictions.gt("sal", 800d)));
        criteria.add(Restrictions.or(
                Restrictions.like("job", "M", MatchMode.START),
                Restrictions.isNotNull("comm")));
        List<Emp> list = criteria.list();
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这样做,当然是可以,但是有没有更好的做法呢。当然是有的,就是现在我们要说的disjuctionconjunction

逻辑或 和 逻辑 与 。简单来说,就是说 or 和 and

为什么说它好用呢。因为它支持自定义sql语句

使用如下:

Criteria criteria = session.createCriteria(Emp.class);
        Dept d = new Dept();
        d.setDeptno((byte) 20);
        criteria.add(Restrictions.eq("dept", d));//找到20号部门下的员工
        // 逻辑或
        Disjunction disjunc = Restrictions.disjunction();
        Criterion cri = Restrictions
                .sqlRestriction("ename like '%S%'  or sal >800");//
        disjunc.add(cri);//自定义sql语句添加 or 条件
        // 逻辑与
        Conjunction conjunc = Restrictions.conjunction();
        cri = Restrictions.sqlRestriction("job like 'M%' and comm is  null");
        conjunc.add(cri);  //自定义sql语句添加 and条件

        criteria.add(disjunc); //将 or 条件 添加到criteria
        criteria.add(conjunc); //将 and条件 添加到criteria
        List<Emp> list = criteria.list();
        System.out.println("结果:");
        for (Emp Emp : list) {
            System.out.println(Emp.getEname() + "\t" + Emp.getJob());
        }
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

编译出来的sql语句如下:

Hibernate: 
    select
        this_.EMPNO as EMPNO1_0_,
        this_.DEPTNO as DEPTNO1_0_,
        this_.ENAME as ENAME1_0_,
        this_.JOB as JOB1_0_,
        this_.MGR as MGR1_0_,
        this_.HIREDATE as HIREDATE1_0_,
        this_.SAL as SAL1_0_,
        this_.COMM as COMM1_0_ 
    from
        SCOTT.EMP this_ 
    where
        this_.DEPTNO=? 
        and (
            ename like '%S%'  
            or sal >800
        ) 
        and (
            job like 'M%' 
            and comm is  null
        )
结果:
JONES   MANAGER
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

,看到这里,我们可以试试,将

        disjunc.add(conjunc);//and添加到or条件里面是什么效果
        criteria.add(disjunc);//最后将or条件加入criteria中
 
  • 1
  • 2
  • 1
  • 2

让我们来看一下编译的sql语句

Hibernate: 
    select
        this_.EMPNO as EMPNO1_0_,
        this_.DEPTNO as DEPTNO1_0_,
        this_.ENAME as ENAME1_0_,
        this_.JOB as JOB1_0_,
        this_.MGR as MGR1_0_,
        this_.HIREDATE as HIREDATE1_0_,
        this_.SAL as SAL1_0_,
        this_.COMM as COMM1_0_ 
    from
        SCOTT.EMP this_ 
    where
        this_.DEPTNO=? 
        and (
            ename like '%S%'  
            or sal >800 
            or (
                job like 'M%' 
                and comm is  null
            )
        )
结果:
JONES   MANAGER
SCOTT   ANALYST
ADAMS   CLERK
FORD    ANALYST
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

发现了什么?我们的and 条件被内置了。有兴趣的可以尝试下这样做。

    conjunc.add(disjunc);
    criteria.add(conjunc);
 
  • 1
  • 2
  • 1
  • 2

看看结果是什么吧。

Hibernate: 
    select
        this_.EMPNO as EMPNO1_0_,
        this_.DEPTNO as DEPTNO1_0_,
        this_.ENAME as ENAME1_0_,
        this_.JOB as JOB1_0_,
        this_.MGR as MGR1_0_,
        this_.HIREDATE as HIREDATE1_0_,
        this_.SAL as SAL1_0_,
        this_.COMM as COMM1_0_ 
    from
        SCOTT.EMP this_ 
    where
        this_.DEPTNO=? 
        and (
            job like 'M%' 
            and comm is  null 
            and (
                ename like '%S%'  
                or sal >800
            )
        )
结果:
JONES   MANAGER
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

又发现了什么?我们的or条件被内置了!!!

disjunction和conjunction 个人感觉比Criteria的内置的运算函数好用,不过还要看个人喜好了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值