HQL是Hiberante官方推荐的Hibernate检索方式,它使用类似SQL的查询语言,以面向对象的方式从数据库中查询。可以使用HQL查询具有继承、多态和关联关系的数据。在检索数据时应优先考虑使用HQL方式。
本笔记将会沿用前面所使用的dept部门表,emp员工表。
dept部门表
emp员工表
1 查询实体
hibernate的session.createQuery()方法是使用HQL语句查询对象的。
hql:是查询对象的,例如:"from User",其中from不区分大小写,而User是区分大小写,因为它是对象。是User类
返回Query对象。
执行这条语句后,Hibernate会根据配置文件中所配置的数据库适配器自动生成相应数据库的SQL语句。
sql: select * from dept; from 后面是表名
hql: form Dept; from 后面是类。
可以对类起别名,有两种方法。
hql: from Dept d
hql:from Dept as d
以上两种起别名方法皆可。
public void Test1() throws Exception{ Configuration config=new Configuration().configure(); SessionFactory sessionFactory= config.buildSessionFactory(); Session session=null; Transaction tr=null; try{ session= sessionFactory.openSession(); tr=session.beginTransaction(); String hql="from Dept"; //定义String类型hql,写入hql语句。 Query query=session.createQuery(hql);
List<Dept> list = query.list(); for(Dept dept:list){ System.out.print("部门编号: "+dept.getDid() +" "); System.out.println("部门名称: "+dept.getDname());
} tr.commit(); }catch(Exception e){ tr.rollback(); }finally{ if(session!=null){ session.close(); } if(sessionFactory!=null){ sessionFactory.close(); } } }
执行结果
Hibernate: select dept0_.did as did1_, dept0_.dname as dname1_, dept0_.daddress as daddress1_ from dept dept0_ 部门编号: 1 部门名称: 业务部 部门编号: 2 部门名称: 技术部 部门编号: 3 部门名称: 管理部 部门编号: 4 部门名称: 财务部 部门编号: 5 部门名称: 人力资源部
2 查询表中单个属性
sql: select ename from dept
hql: select ename from Dept
对属性也可以设置别名
hql:select ename as from Dept
as 必须加。
public void Test2() throws Exception{ Configuration config=new Configuration().configure(); SessionFactory sessionFactory= config.buildSessionFactory(); Session session=null; Transaction tr=null; try{ session= sessionFactory.openSession(); tr=session.beginTransaction(); Query query=session.createQuery("select dname from Dept"); List<String> list = query.list(); for(String name:list){ System.out.println("部门名称: "+name); } tr.commit(); }catch(Exception e){ tr.rollback(); }finally{ if(session!=null){ session.close(); } if(sessionFactory!=null){ sessionFactory.close(); } } }
执行结果:
Hibernate: select dept0_.dname as col_0_0_ from dept dept0_ 部门名称: 业务部 部门名称: 技术部 部门名称: 管理部 部门名称: 财务部 部门名称: 人力资源部
3 对多个属性进行查询
sql: select ename,eage from emp
hql:select ename,eage from Emp
hql: select e.ename,e.eage from Emp e
以上两种hql写法均可。
public void Test3() throws Exception{ Configuration config=new Configuration().configure(); SessionFactory sessionFactory= config.buildSessionFactory(); Session session=null; Transaction tr=null; try{ session= sessionFactory.openSession(); tr=session.beginTransaction(); Query query=session.createQuery("select ename,eage from Emp"); List<Object[]> list = query.list(); //对多个属性查询的时候,使用Obejct数组。
for(Object[] message:list){ System.out.println(Arrays.toString(message)); //采用辅助类Arrays的toString()方法打印数组。 } tr.commit(); }catch(Exception e){ tr.rollback(); }finally{ if(session!=null){ session.close(); } if(sessionFactory!=null){ sessionFactory.close(); } } }
测试结果
Hibernate: select emp0_.ename as col_0_0_, emp0_.eage as col_1_0_ from emp emp0_ [刘德华, 40] [李世民, 34] [曹操, 59] [和珅, 44] [贺龙, 45] [郭富城, 34]
4 通过实体类方式查询多属性
除了上述方法外,还可以采用实体类的方式查询,要在Emp类中加入带有查询参数的构造器,代码如下。
public class Emp { private int eid;
private int eage;
private float esal; private String ename;
省略get,set方法。
public Emp() { super(); } public Emp(int eage, String ename) { //需要查询的属性是什么,构造器的参数就是什么。 super(); this.eage = eage; this.ename = ename; }
测试类
public void Test4() throws Exception{ Configuration config=new Configuration().configure(); SessionFactory sessionFactory= config.buildSessionFactory(); Session session=null; Transaction tr=null; try{ session= sessionFactory.openSession(); tr=session.beginTransaction(); Query query=session.createQuery("select new Emp(eage,ename) from Emp e"); select 后直接调用构造器,参数就是查询的属性,参数不可错乱。 List<Emp> list = query.list(); 此处不实用object数组,类类型即可 for(Emp message:list){ System.out.print("姓名:"+message.getEname()+" "); System.out.println("年龄:"+message.getEage()); } tr.commit(); }catch(Exception e){ tr.rollback(); }finally{ if(session!=null){ session.close(); } if(sessionFactory!=null){ sessionFactory.close(); } } }
测试结果
Hibernate: select emp0_.eage as col_0_0_, emp0_.ename as col_1_0_ from emp emp0_ 姓名:刘德华 年龄:40 姓名:李世民 年龄:34 姓名:曹操 年龄:59 姓名:和珅 年龄:44 姓名:贺龙 年龄:45 姓名:郭富城 年龄:34
|