Hibernate02-HQL查询语言
一、使用HQL语句操作数据库
Hibernate支持三种查询方式:HQL查询、Criteria查询及原生SQL(Native SQL)查询(本篇文章对HQL查询进行讲解)。
-
HQL(Hibernate Query Language,Hibernate查询语言)是一种面向对象的查询语言,其没有表和字段的概念,只有类、对象和属性的概念。
-
Criteria查询采用面向对象的方式构造查询。
-
原生SQL查询就是直接执行SQL语句的查询,可以在SQL中利用不同数据库所特有的一些特性进行查询。例如数据库是Oracle,则可以使用Oracle的关键字或函数等。
1、编写HQL语句
HQL语句中除了Java类和属性的名称外,对大小写不敏感,所以SELECT和select是相同的,但是cn.hibernate.entity.Dept不等价于hibernate.entity.DEPT。HQL语句中的关键字建议使用小写字母,如select。
(1)form子句
Hibernate中最简单的HQL语句形式如下,以下几条HQL语句都用于查询所有部门。
例1: from cn.hibernatedemo.entity.Dept
说明: cn.hibernatedemo.entity.Dept 是全限定类名
例2: from Dept
说明: 类名Dept省略了包名
例3:
from Dept as dept
from Dept dept
说明: 以上两条HQL语句为持久化类Dept指派了别名dept,可以在HQL语句中使用这个别名;关键字as是可选的。
(2)select子句 :用于选取对象和属性
例1: select dept.deptName from Dept as dept;
说明: select子句选取了一个属性deptName,也可选取多个属性。
例2: elect dept from Dept as dept;
说明: select后跟的是别名dept
(3)where子句:用于表达查询的限制条件
例1: from Dept where deptName='SALES'
说明:
- 该HQL语句用于查询名称是 SALES 的部门;
- 在where子句中直接使用属性名deptName
例2: from Dept as dept where dept.deptName='SALES'
说明:
- 该HQL语句用于查询名称是 SALES 的部门;
- 在语句中指派了别名,在where子句中使用了完整的属性名dept.deptName
例3: from Dept dept where dept.loc is not null
说明: 这条HQL语句用于查询地址不为 null 的部门
(4)表达式:一般用在where子句中
例1: from Dept dept where lower(dept.deptName)='sales'
说明:
- 该HQL语句用于查询名称是sales的部门,不区分大小写。
- lower()函数用于把字符串中的每个字母改为小写
例2: from Emp where year(hireDate)=1980
说明:
- 该HQL语句用于查询1980年入职的员工;
- year()函数用于获取日期字段的年份
(5)order by子句:用于按指定属性排序
例1: from Emp order by hireDate asc
说明:
- 该HQL语句用于查询所有员工,并按员工入职时间升序排序
- 关键字asc或desc为可选,默认asc升序排序
例2: from Emp order by hireDate,salary deac
说明: 该HQL语句用于查询所有员工,先按员工入职时间升序排序,入职时间相同的再按员工工资降序排序。
2、使用Query对象执行HQL语句
(1)使用list()方法获取所有数据
Emp实体类
/**
* 员工类
*/
public class Emp {
/**
* 员工编号
*/
private Integer empNo;
/**
* 员工姓名
*/
private String ename;
/**
* 员工职位
*/
private String job;
/**
* 上级编号
*/
private Integer mgr;
/**
* 入职日期
*/
private Date hiredate;
/**
* 工资
*/
private Double sal;
/**
* 福利
*/
private Double comm;
/**
* 部门编号
*/
private Integer deptNo;
//省略getter/setter方法
}
Emp.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.demo.po.Emp" table="EMP" schema="scott" dynamic-update="true">
<id name="empNo" type="java.lang.Integer" column="EMPNO">
<!--为了避免主键生成器assigned造成的干扰,把主键生成器 替换为increment-->
<generator class="assigned"/>
</id>
<property name="ename" type="java.lang.String" column="ENAME"/>
<property name="deptNo" type="java.lang.Integer" column="DEPTNO"/>
<property name="mgr" type="java.lang.Integer" column="MGR"/>
<property name="job" type="java.lang.String" column="JOB"/>
<property name="sal" type="java.lang.Double" column="SAL" />
<property name="comm" type="java.lang.Double" column="COMM" />
<property name="hiredate" type="java.util.Date" column="HIREDATE"/>
</class>
</hibernate-mapping>
注意配置完成后需要在hibernate.cfg.xml中做映射
<!--映射文件配置,注意文件名必须包含其相对于classpath的全路径-->
<mapping resource="cn/demo/dao/emp/Emp.hbm.xml"/>
EmpDao.java
public class EmpDao extends BaseDao{
/**
* 查询所有员工:使用Query对象的list()方法
* @return
*/
public List<Emp> findAll(){
//定义HQL语句
String hql="from Emp";
//构建Query对象
Query query=currentSession().createQuery(hql);
//执行查询
return query.list();
}
}
EmpBiz.java
public class EmpBiz {
private EmpDao empDao=new EmpDao();
/**
* 获取所有员工信息
* @return 员工列表
*/
public List<Emp> findAllEmps(){
Transaction tx=null;
List<Emp> emps=null;
try {
//开始事务
tx=empDao.currentSession().beginTransaction();
emps=empDao.findAll(); //调用list()方法进行持久化操作
tx.commit(); //提交事务
}catch (HibernateException e){
e.printStackTrace();
if(tx!=null){
tx.rollback(); //回滚事务
}
}
return emps;
}
}
测试类
/**
* 测试获取所有员工信息方法
*/
@Test
public void test1(){
//使用list()方法获取所有员工信息
List<Emp> empList=new EmpBiz().findAllEmps();
//遍历并输出结果
for (Emp emp:empList){
System.out.println("员工姓名:"+emp.getEname());
}
}
运行结果
(2)使用iterate()方法获取所有数据
EmpDao.java
public class EmpDao extends BaseDao {
public Iterator<Emp> findAll1(){
//定义HQL语句
String hql="from Emp";
//构建Query对象
Query query=currentSession().createQuery(hql);
return query.iterate();
}
}
EmpBiz.java
public class EmpBiz {
private EmpDao empDao=new EmpDao();
/**
* 获取所有员工信息
* @return
*/
public Iterator<Emp> findAllEmps(){
Transaction tx=null;
Iterator<Emp> emps=null;
try {
//开始事务
tx=empDao.currentSession().beginTransaction();
//调用itertate()方法查询所有
emps=empDao.findAll1();
//遍历并输出结果,与调用list()方法时不同,需在会话关闭前测试查询结果
Emp emp=null;
while(emps.hasNext()){
emp=emps.next();
System.out.println("员工姓名:"+emp.getEname());
}
tx.commit(); //提交事务
}catch (HibernateException e){
e.printStackTrace();
if(tx!=null){
tx.rollback(); //回滚事务
}
}
return emps;
}
}
测试类
@Test
public void test1(){
//调用itertate()方法查询所有员工
Iterator<Emp> empIterator=new EmpBiz().findAllEmps();
}
注意运行结果
Hibernate:
select
emp0_.EMPNO as col_0_0_
from
scott.EMP emp0_
Hibernate:
select
emp0_.EMPNO as EMPNO3_0_,
emp0_.ENAME as ENAME3_0_,
emp0_.DEPTNO as DEPTNO3_0_,
emp0_.MGR as MGR3_0_,
emp0_.JOB as JOB3_0_,
emp0_.SAL as SAL3_0_,
emp0_.COMM as COMM3_0_,
emp0_.HIREDATE as HIREDATE3_0_
from
scott.EMP emp0_
where
emp0_.EMPNO=?
员工姓名:SMITH
Hibernate:
select
emp0_.EMPNO as EMPNO3_0_,
emp0_.ENAME as ENAME3_0_,
emp0_.DEPTNO as DEPTNO3_0_,
emp0_.MGR as MGR3_0_,
emp0_.JOB as JOB3_0_,
emp0_.SAL as SAL3_0_,
emp0_.COMM as COMM3_0_,
emp0_.HIREDATE as HIREDATE3_0_
from
scott.EMP emp0_
where
emp0_.EMPNO=?
员工姓名:ALLEN
Hibernate:
select
emp0_.EMPNO as EMPNO3_0_,
emp0_.ENAME as ENAME3_0_,
emp0_.DEPTNO as DEPTNO3_0_,
emp0_.MGR as MGR3_0_,
emp0_.JOB as JOB3_0_,
emp0_.SAL as SAL3_0_,
emp0_.COMM as COMM3_0_,
emp0_.HIREDATE as HIREDATE3_0_
from
scott.EMP emp0_
where
emp0_.EMPNO=?
员工姓名:WARD
Hibernate:
select
emp0_.EMPNO as EMPNO3_0_,
emp0_.ENAME as ENAME3_0_,
emp0_.DEPTNO as DEPTNO3_0_,
emp0_.MGR as MGR3_0_,
emp0_.JOB as JOB3_0_,
emp0_.SAL as SAL3_0_,
emp0_.COMM as COMM3_0_,
emp0_.HIREDATE as HIREDATE3_0_
from
scott.EMP emp0_
where
emp0_.EMPNO=?
员工姓名:JONES
说明:
- 从Hibernate生成的sql语句可以看出,list()方法生成一条sql查询语句,查询
所有符合条件的记录; - iterate()方法首先查询出所有符合条件的主键值,此处是empno,然后在需要
某一对象的其他属性值时,才生成按主键查询的sq语句,此处是
select * from emp where empno=?
即iterate()方法可能生成1+n条sql语句。
小结:执行HQL语句的步骤
- 获取session对象
- 编写hql语句
- 创建query对象
- 执行查询,得到查询结果
二、在HQL语句与绑定参数
1、HQL语句的参数绑定
(1)按参数位置绑定
在HQL语句中用“?”占位符来定义参数的位置,形式如下
Query query=session.createQuery("from Emp where job=? and salary>?");
以上HQL语句中定义了两个参数,可以通过setXXX()方法来绑定参数,参数位置下标从0开始:
query.setString(0,job);
query.setDouble(1,salary);
Query对象提供了绑定各种类型参数的方法,setInteger()等等
例:
/**
* 根据部门名称查找部门
* @param deptName
* @return
*/
public List<Dept> findByDeptName(String deptName){
String hql="from Dept as dept where dept.dName=?";
Query query=currentSession().createQuery(hql);
query.setString(0,deptName); //绑定参数,下标从0开始
return query.list();
}
(2)按参数名称绑定
在HQL语句中可以定义命名参数,命名参数以“:”开头,形式如下
Query query=currentSession().
createQuery("from Emp where job=:empJob and sal>:empSalary");
说明:
- 以上HQL语句定义了两个 命名参数 empJob和empSalary
- 接下来调用Query对象的setXXX()方法来绑定参数
query.setString("empJob",empJob);
query.setDouble("empSalary",empSalary);
Query对象提供了绑定各种类型参数的setXXX()方法的重载,第一个参数代表命名参数的名称,第二个参数代表命名参数的值。
例:
/**
* 根据部门名称查找部门
* @param deptName
* @return
*/
public List<Dept> findByDeptName(String deptName){
//按参数名称绑定
String hql="from Dept as dept where dept.dName=:name";
Query query=currentSession().createQuery(hql);
query.setString("name",deptName);//为命名参数赋值
return query.list();
}
按名称绑定与按位置绑定相比有以下优势:
- (1)使程序代码有较好的可读性
- (2)按名称绑定的形式有利于程序代码的维护。对于按位置绑定的形式,如果参数在HQL语句中的位置改变了,就必须修改相关绑定参数的代码。此种方式削弱了程序代码的健壮性和可维护性。
2、绑定不同数据类型的参数
(1)Query接口提供的绑定不同数据类型参数的方法
- setBoolean():绑定类型为java.lang.Boolean的参数
- setByte():绑定类型为java.lang.Byte的参数
- setDouble():绑定类型为java.lang.Double的参数
- setDate():绑定类型为java.util.Date的参数
- setString():绑定类型为java.lang.String的参数
以上每个方法都有两种重载形式,如setString()方法
- setString(int position,String val):按位置绑定参数
- setString(String name,String val):按名称绑定参数
除了以上用于绑定特定类型的参数方法,Hibernate还提供了 setParameter()方法 ,用于绑定任意类型的参数。该方法使用Object类型作为HQL参数的类型,当不变指定参数的具体类型时,可以使用setParameter()为参数赋值。
例:
EmpDao.java
public class EmpDao extends BaseDao{
/**
* 根据条件查询员工:使用setParameter()方法
* @param conditions
* @return
*/
public List<Emp> findByConditions(Object[] conditions){
//查询依赖多个条件,且类型各异
String hql="from Emp where job=? and sal>?";
Query query=currentSession().createQuery(hql);
//判断条件参数是否为空
if(conditions!=null&&conditions.length>0){
//若不为空则遍历数组绑定参数值
for (int i=0;i<conditions.length;i++){
//这里下标从0开始
query.setParameter(i,conditions[i]); //为占位符赋值
}
}
return query.list();
}
}
EmpBiz.java
public class EmpBiz{
private EmpDao empDao=new EmpDao();
/**
* 根据条件查询员工:使用setParameter()方式
* @param conditions
* @return
*/
public List<Emp> findByConditions(Object[] conditions){
Transaction tx=null;
List<Emp> emps=null;
try {
tx=empDao.currentSession().beginTransaction();
emps=empDao.findByConditions(conditions);
tx.commit();
}catch (HibernateException e){
e.printStackTrace();
if(tx!=null){
tx.rollback();
}
}
return emps;
}
}
测试类
/**
* 根据条件获取emps:使用setParameter()方式
*/
@Test
public void test2(){
//查询条件
Object[] conditions={"CLERK",1000.0};
List<Emp> empList=new EmpBiz().findByConditions(conditions);
//遍历并输出结果
for (Emp emp:empList){
System.out.println("员工姓名:"+emp.getEname());
}
}
运行结果
(2)setProperties()方法:绑定命名参数与一个对象的属性值
EmpDao.java
public class EmpDao extends BaseDao{
/**
* 根据条件获取Emp:使用setProperties()方法
* @param conditions
* @return
*/
public List<Emp> findByConditions(Emp conditions){
//=:后面的为命名参数,命名参数必须与对象的属性名一致
String hql="from Emp where job=:job and sal>:sal";
Query query=currentSession().createQuery(hql);
//根据命名参数的名称,从conditions中获取相应的属性值进行赋值
query.setProperties(conditions);
return query.list();
}
}
说明: setProperties()方法为命名参数赋值,使用Emp对象封装了条件,命名参数和Emp类的相关属性相匹配。
EmpBiz.java
public class EmpBiz{
private EmpDao empDao=new EmpDao();
/**
* 根据条件获取员工信息列表:使用setProperties()方式
* @param conditions
* @return
*/
public List<Emp> findByConditions(Emp conditions){
Transaction tx=null;
List<Emp> empList=null;
try {
tx=empDao.currentSession().beginTransaction();
empList=empDao.findByConditions(conditions);
tx.commit();
}catch (HibernateException ex){
ex.printStackTrace();
if(tx!=null){
tx.rollback();
}
}
return empList;
}
}
测试类
/**
* 多条件获取emps:使用setProperties()方式
*/
@Test
public void test3(){
Emp conditions=new Emp();
conditions.setJob("SALESMAN");
conditions.setSal(1000.0);
List<Emp> empList=new EmpBiz().findByConditions(conditions);
//遍历并输出结果
for (Emp emp:empList){
System.out.println("员工姓名:"+emp.getEname());
}
}
执行结果
3、Hibernate动态设置查询参数的方式
需求:根据员工职位Job、工资>某数,入职时间在某个日期段的信息列表;三个条件可以随意组合,所以在条件数不确定的情况下,可以使用Hibernate提供的动态设置查询参数的方式。下面创建一个类用于封装查询条件:
EmpCondition.java
/**
* 封装员工表查询条件
*/
public class EmpCondition {
private String job; //员工职位
private Double salary; //工资
private Date hireDateEnd; //员工入职结束时间
private Date hireDateStart; //员工入职起始时间
//省略getter/setter方法
}
因为涉及日期类型的数据处理,所以创建一个工具类用于转换日期格式
stringToDateConverter.java
/**
* 字符串转换日期类型
*/
public class stringToDateConverter {
/**
* 将字符串转换为日期类型
* @param dateStr 日期字符串
* @param pattern 转换格式
* @return 日期对象
*/
public static Date strToDate(String dateStr,String pattern)throws Exception{
//设置日期格式
SimpleDateFormat simpleDateFormat=new SimpleDateFormat(pattern);
//将String类型的日期转换为java.util.Date
return simpleDateFormat.parse(dateStr);
}
}
EmpDao.java
/**
* 多条件动态查询emps
* @param hql
* @param empCondition
* @return
*/
public List<Emp> findByConditions(String hql, EmpCondition empCondition){
return currentSession().createQuery(hql). //创建Query对象
setProperties(empCondition). //为参数赋值
list(); //执行查询,获取查询结果
}
EmpBiz.java
/**
* 多条件动态查询emps
* @param empCondition
* @return
*/
public List<Emp> findByConditions(EmpCondition empCondition){
Transaction tx=null;
List<Emp> empList=null;
try {
//开启事务
tx=empDao.currentSession().beginTransaction();
//HQL根据条件动态生成
StringBuffer hql=new StringBuffer("from Emp as emp where 1=1");
//判断职位是否为空
if (empCondition.getJob()!=null&&empCondition.getJob().length()>0){
hql.append(" and emp.job=:job");
}
//判断薪资条件是否为空
if (empCondition.getSalary()!=null&&empCondition.getSalary()!=0){
hql.append(" and emp.sal>:salary");
}
//判断入职日期大于某个日期
if(null!=empCondition.getHireDateStart()){
hql.append(" and emp.hiredate>:hireDateStart");
}
//判断入职日期小于某个日期
if(null!=empCondition.getHireDateEnd()){
hql.append(" and emp.hiredate<:hireDateEnd");
}
//执行查询
empList=empDao.findByConditions(hql.toString(),empCondition);
//提交事务
tx.commit();
}catch (HibernateException ex){
ex.printStackTrace();
if(tx!=null){
tx.rollback();
}
}
return empList;
}
测试类
/**
* 动态绑定多条件参数查询emps
*/
@Test
public void test4(){
EmpCondition empCondition=new EmpCondition();
empCondition.setJob("CLERK");
empCondition.setSalary(1000.0);
try {
empCondition.setHireDateStart(stringToDateConverter.strToDate("1981-4-1","yyyy-MM-dd"));
//empCondition.setHireDateEnd(stringToDateConverter.strToDate("1985-9-9","yyyy-MM-dd"));
}catch (Exception e){
e.printStackTrace();
}
List<Emp> empList=new EmpBiz().findByConditions(empCondition);
//遍历并输出结果
for (Emp emp:empList){
System.out.println("员工姓名:"+emp.getEname());
}
}
运行结果
4、使用Hibernate API之uniqueResult()方法
上面例子中使用Query接口的list()、iterate()方法可以获取集合,还可以通过uniqueResult()方法获取唯一结果。
EmpDao.java
/**
* 获取薪资>=范围的员工数:使用Query对象的uniqueResult(),该方法返回唯一结果
* @param sal
* @return
*/
public Long obtainTheRowCount(Double sal){
String hql="select count(id) from Emp where sal>=:sal";
return (Long)currentSession().createQuery(hql).
setDouble("sal",sal). //设置参数
uniqueResult(); //执行返回唯一结果,以Object类型封装
}
EmpBiz.java
public Long countBySalary(Double sal){
Transaction tx=null;
Long result=null;
try{
tx= empDao.currentSession().beginTransaction();
result=empDao.obtainTheRowCount(sal);
tx.commit();
}catch (HibernateException e){
e.printStackTrace();
if(tx!=null){
tx.rollback();
}
}
return result;
}
测试类
/**
* 测试Query的uniqueResult()方法返回唯一结果
*/
@Test
public void test5(){
Double sal=1000.0;
Long result=new EmpBiz().countBySalary(sal);
System.out.println("薪资:"+sal+"以上的员工人数有:"+result+"人");
}
运行结果
三、实现分页和投影查询
1、Hibernate分页查询API
Hibernate通过使用Query接口的以下两个方法实现分页:
- setFirstResult(int firstResult):用于设置需要返回的第一条记录的位置,下标从0开始。
- setMaxResults(int maxResults):用于设置最大返回记录数。
例:
EmpDao.java
/**
* 分页获取数据
* @param pageNo 当前页数
* @param pageSize 每页显示记录数
* @return
*/
public List<Emp> findByPage(int pageNo,int pageSize){
return currentSession().createQuery("from Emp order by id").
setFirstResult((pageNo-1)*pageSize). //设置获取结果的起始下标
setMaxResults(pageSize). //设置每页显示记录数
list(); //执行查询
}
EmpBiz.java
/**
* 分页获取emps
* @param pageNo
* @param pageSize
* @return
*/
public List<Emp> findEmpByPage(int pageNo,int pageSize){
Transaction tx=null;
List<Emp> empList=null;
try {
tx=empDao.currentSession().beginTransaction();
empList=empDao.findByPage(pageNo,pageSize);
tx.commit();
}catch (HibernateException e){
e.printStackTrace();
if(tx!=null){
tx.rollback();
}
}
return empList;
}
测试类
/**
* 测试分页获取员工信息
*/
@Test
public void test6(){
int pageNo=2;
int pageSize=4;
List<Emp> empList=new EmpBiz().findEmpByPage(pageNo,pageSize);
//遍历并输出结果
for (Emp emp:empList){
System.out.println("员工姓名:"+emp.getEname());
}
}
运行结果
2、Hibernate投影查询API
有时数据展示并不需要获取对象的全部属性,而是只需要对象的某一个或某几个
属性,或者需要通过表达式、聚合函数等方式得到某些结果,此时可以使用投影查询。投影查询需要使用HQL的select子句。对于投影结果的封装,有以下3种常见情况:
- (1)每条查询结果仅包含一个结果列
DeptDao.java
/**
* 获取所有部门名称
* @return String集合
*/
public List<String> findAllNames(){
String hql="select dName from Dept";
return currentSession().createQuery(hql).list();
}
DeptBiz.java
/**
* 获取所有部门名称
* @return
*/
public List<String> findAllNames(){
Transaction tx=null;
List<String> result=null;
try {
tx=deptDao.currentSession().beginTransaction();
result=deptDao.findAllNames();
tx.commit();
}catch (HibernateException e){
e.printStackTrace();
if(tx!=null){
tx.rollback();
}
}
return result;
}
测试类:
/**
* 使用投影查询获取所有部门名称
*/
@Test
public void test7(){
List<String> result=new DeptBiz().findAllNames();
for(String str:result){
System.out.println(str);
}
}
运行结果
- (2)每条查询结果包含不止一个结果列
DeptDao.java
/**
* 获取所有部门信息:返回多行多列
* @return
*/
public List<Object[]> findAllDeptList(){
String hql="select deptNo,dName from Dept";
return currentSession().createQuery(hql).list();
}
说明: 以上方法为获得所有部门的编号与名称。查询结果集合中的每个元素都是对象数组Object[],数组的长度为2,数组的第一个元素是部门编号,第二个元素是部门名称。这种方式一般只应用于查询部分属性值时,注意数组下标与属性值的对应。
DeptBiz.java
/**
* 获取所有部门信息:返回多行多列
* @return
*/
public List<Object[]> findAllDeptList(){
Transaction tx=null;
List<Object[]> result=null;
try {
tx=deptDao.currentSession().beginTransaction();
result=deptDao.findAllDeptList();
tx.commit();
}catch (HibernateException e){
e.printStackTrace();
if(tx!=null){
tx.rollback();
}
}
return result;
}
测试类
/**
* 测试:使用投影API返回多行多列
*/
@Test
public void test8(){
List<Object[]> list=new DeptBiz().findAllDeptList();
//遍历集合
for(int i=0;i<list.size();i++){
Object[] object=list.get(i); //取出每一个对象数组Object[]
//遍历数组:数组第一个下标对应部门编号,第二个编号对应部门名称
for(int j=0;j<object.length;j++){
System.out.println(object[j]);
}
}
}
运行结果
- (3)将某条查询结果通过构造方法封装成对象
DeptDao.java
/**
* 将每条查询结果通过构造方法封装成对象
* @return
*/
public List<Dept> findDeptList(){
String hql="select new Dept(deptNo,dName) from Dept";
return currentSession().createQuery(hql).list();
}
注:Dept.java中需要存在无参/带参构造方法
DeptBiz.java
/**
* 将每条查询结果通过构造方法封装成对象
* @return
*/
public List<Dept> findDeptList(){
Transaction tx=null;
List<Dept> result=null;
try {
tx=deptDao.currentSession().beginTransaction();
result=deptDao.findDeptList();
tx.commit();
}catch (HibernateException e){
e.printStackTrace();
if(tx!=null){
tx.rollback();
}
}
return result;
}
测试类
/**
* 测试投影API 将查询结果通过构造方法封装为对象
*/
@Test
public void test9(){
List<Dept> list=new DeptBiz().findDeptList();
for(Dept dept:list){
System.out.println("部门编号:"+dept.getDeptNo());
System.out.println("部门名称:"+dept.getdName());
}
}
运行结果