关于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()
这样做,当然是可以,但是有没有更好的做法呢。当然是有的,就是现在我们要说的disjuction和conjunction
逻辑或 和 逻辑 与 。简单来说,就是说 or 和 and
为什么说它好用呢。因为它支持自定义sql语句
使用如下:
Criteria criteria = session.createCriteria(Emp.class)
Dept d = new Dept()
d.setDeptno((byte) 20)
criteria.add(Restrictions.eq("dept", d))
// 逻辑或
Disjunction disjunc = Restrictions.disjunction()
Criterion cri = Restrictions
.sqlRestriction("ename like '%S%' or sal >800")
disjunc.add(cri)
// 逻辑与
Conjunction conjunc = Restrictions.conjunction()
cri = Restrictions.sqlRestriction("job like 'M%' and comm is null")
conjunc.add(cri)
criteria.add(disjunc)
criteria.add(conjunc)
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中
让我们来看一下编译的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)
看看结果是什么吧。
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的内置的运算函数好用,不过还要看个人喜好了。