关于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 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));//找到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 list = criteria.list();
System.out.println("结果:");
for (Emp Emp : list) {
System.out.println(Emp.getEname() + "\t" + Emp.getJob());
}
编译出来的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
,看到这里,我们可以试试,将
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
发现了什么?我们的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
又发现了什么?我们的or条件被内置了!!!
disjunction和conjunction 个人感觉比Criteria的内置的运算函数好用,不过还要看个人喜好了。