请教Hibernate 的 Criteria 的 in 查询

 我来答
百度网友5e15b90
2017-10-17 · TA获得超过1031个赞
知道小有建树答主
回答量:806
采纳率:91%
帮助的人:828万
展开全部
Hibernate中提供了三种查询方式,分别为HQL、Criteria查询、本地化SQL查询,实际应用中,有很多人忽略了Criteria的用处,觉得不如另外两种贴近SQL方式便捷,实际则未必,很多情况下Criteria更具有优势;本篇文章就对Criteria查询做一个全面的介绍,以期尽可能的将更多的Criteria强大的查询功能展现出来;
1、首先新建一个Maven Web Project项目,本次使用的是hibernate4.3.11版本,使用MySql数据库,添加如下依赖:

[html] view plain copy
<!-- 引入mysql jar依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- 引入hibernate依赖 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version>
</dependency>
新建完毕后,项目结构如下:

2、entity包下面放置的是通过Hibernate反向工程生成的实体映射类,samples包下面放置测试类,同样hibernate.cfg.xml文件需要配置,在此就不一一展示了,好了,准备工程就这么多,下面开始介绍Criteria的实际操作;
3、Criteria查询
3.1 获取Criteria对象

[java] view plain copy
package com.hibernate.samples;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import com.hibernate.entity.SlEmployee;

public class HibernateTest {
// 声明一个Hibernate Session类型的变量
private Session session;
@Before
public void getSession(){
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
session = sessionFactory.openSession();
}

@After
public void closeSession(){
if(session != null){
session.close();
}
}

@Test
public void doCreateCriteriaInstance(){
// 获取Criteria实例对象
Criteria criteria = session.createCriteria(SlEmployee.class);
Assert.assertNotNull(criteria);
}
}
3.2 在SQL中,我们可以通过WHERE关键字对条件进行定义,那么在Criteria中呢?看例子

[java] view plain copy
@Test
public void doConditionQueryInCriteria() {
// 获取Criteria实例对象
Criteria criteria = session.createCriteria(SlEmployee.class);

// 查询出王姓员工且收入在3000到5000之间的
// 类似于HQL中 WHERE employeeName LIKE '王%' AND salary BETWEEN 3000 AND 5000
List emps = criteria.add(Restrictions.like("employeeName", "王%"))
.add(Restrictions.between("salary", 3000.0, 5000.0)).list();

// 查询出工资在4000以下或5000以上的王姓员工
// 可以通过Restrictions的or或and进行逻辑分组
emps = criteria.add(Restrictions.like("employeeName", "王%"))
.add(Restrictions.or(Restrictions.gt("salary", 5000D), Restrictions.lt("salary", 3000D))).list();

// 查询出岗位是软件工程师或测试工程师,且学历是硕士、本科或大专的员工有哪些
emps = criteria.add(Restrictions.in("position", new String[] { "软件工程师", "测试工程师" }))
.add(Restrictions.disjunction().add(Restrictions.eq("degree", "硕士")).add(Restrictions.eq("degree", "本科"))
.add(Restrictions.eq("degree", "大专")))
.list();
}
上述三个查询可以看出Restrictions类提供了内建Cretirion类型来满足各种查询状况,此外Criteria还有一个特别强大的功能,那就是允许你直接指定SQL查询,看例子

[html] view plain copy
List emps = criteria.add(Restrictions.sqlRestriction("birthday > '1980-01-01' AND employee_name like '刘%'")).list();

上述无论是birthday还是employee_name都是数据库中表的字段名称,看起来是不是特别好用,此外还可以直接通过属性实例构建查询条件,比如要查询出学习是高中、中专的员工有哪些:

[java] view plain copy
List emps = criteria.add(Property.forName("degree").in(new String[]{"高中","中专"})).list();
3.3 对结果集进行排序,同样可以分为上述两种方式

[java] view plain copy
List emps = criteria.add(Restrictions.sqlRestriction("birthday > '1970-01-01'")).addOrder(Order.asc("birthday"))
.addOrder(Order.desc("salary")).list();

List emps = criteria.add(Restrictions.sqlRestriction("birthday > '1970-01-01'"))
.addOrder(Property.forName("birthday").asc()).addOrder(Property.forName("salary").desc()).list();
3.4 上述几个例子直接演示了对我们想要实体的操作,大家都知道每个实体都会有好多关联实体,比如一个请假实体类会关联请假申请人与审批人、一篇博客会关联作者和分类信息实体、一个订单会关联多个商品实体,顾客实体,地址实体等,如果此时我们想通过对关联实体的限制,最终限制想要的实体,那应该怎么处理呢,看例子;

[java] view plain copy
// 比如我们想查询北京各个公司中,员工学历中包括高中、中专、大专的公司部门有哪些
List depts = criteria.add(Restrictions.sqlRestriction("dept_name LIKE '北京%'"))
.createCriteria("slEmployees").add(Restrictions.in("degree", new String[]{"高中","中专","大专"})).list();
上述方法生成下列SQL文

[sql] view plain copy
from
sl_dept this_
inner join
sl_employee slemployee1_
on this_.dept_id=slemployee1_.DEPT_ID
where
dept_name LIKE '北京%'
and slemployee1_.DEGREE in (
?, ?, ?
)
通过该实例我们可以得出:

a)可以通过createCriteria方法来通过关联实体限制最终查询实体;
b)默认采用内连接的方式关联查询
那么如果我们想采用比如左连接,右连接甚至是全外连接的话又该怎么做呢,看例子:

[java] view plain copy
List depts = criteria.add(Restrictions.sqlRestriction("dept_name LIKE '北京%'")).createAlias("slEmployees", "emps2", JoinType.LEFT_OUTER_JOIN, Restrictions.gt("salary",6000.0)).list();
生成SQL如下:

[sql] view plain copy
from
sl_dept this_
left outer join
sl_employee emps2x1_
on this_.dept_id=emps2x1_.DEPT_ID
and (
emps2x1_.SALARY>?
)
where
dept_name LIKE '北京%'
另外同样在createCriteria方法中也同样可以指定查询方式;
莱伯泰科
2024-10-28 广告
LabTech Group,即北京莱伯泰科仪器股份有限公司,是业界领先的实验室科学仪器与解决方案提供商。我们专注于分析测试仪器的研发、生产和销售,致力于为全球科研工作者、高校及企业实验室提供高性能、高稳定性的产品与服务。通过持续的技术创新与... 点击进入详情页
本回答由莱伯泰科提供
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式