Hibernate读书笔记-----HQL查询
Hibernate提供了强大的查询系统,使用Hibernate有多种查询方法可以选择:可以使用Hibernate的HQL查询,也可以使用条件查询,甚至可以使用原生的SQL查询语句。其中HQL查询时Hibernate配置的功能强大的查询语句。HQL是非常有意识的被设计为完全面向对象的查询,它可以理解如继承、多态 和关联之类的概念。
一、HQL查询
HQL的语法和SQL很相似,但是HQL是一种面向对象的查询语句,它的操作对象是类、实例、属性等,而SQL的操作对象 是数据表、列等数据库对象。
由于HQL是完全面向对象的查询语句,因此可以支持继承、多态等特性。
HQL查询依赖于Query类,每一个Query实例对应一个查询对象,它的执行是通过Session的createQuery()方法来获得的。
执行HQL查询的步骤:
1、获得Hibernate Session对象
2、编写HQL语句
3、调用Session的createQuery方法创建查询对象
4、如果HQL语句包含参数,则调用Query的setXxx方法为参数赋值
5、调用Query对象的list等方法返回查询结果。
实例:
[java]
private void query(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
//以HQL语句创建Query对象,执行setString方法为HQL语句的参数赋值
//Query调用list方法访问查询的全部实例
List list = session.createQuery("select distinct p from Person p where p.name=:name")
.setString("name", "chenssy").list();
//遍历查询结果
for (Iterator iterator = list.iterator();iterator.hasNext();) {
Person p = (Person) iterator.next();
System.out.println("id="+p.getId()+",age="+p.getAge());
}
session.close();
}
上面的程序先编写HQL语句后,使用Session的createQuery(hql)方法创建一个Query,Query对象使用setXxx方法为HQL语句的参数赋值,最后调用list()方法返回查询的全部结果。
在这里Query对象可以连续多次调用setXxx方法为HQL参数赋值。这是因为Hibernate Query的setXxx方法的返回值为Query本身,因此程序创建Query后,可以直接多次调用setXxx方法为HQL语句的参数赋值。
Query对象还包含如下两个方法:
setFirstResult(int firstResult):设置返回的结果集从第几条记录开始
setMaxResult(int maxResult):设置本次查询返回的结果数目
这两个方法用于对HQL查询实现分页控制
二、HQL查询的from子句
Hibernate中最简单的查询语句的形式如下:
[sql]
from Person
From关键字后面紧跟持久化类的类名。
大多数情况下, 你需要指定一个别名, 原因是你可能需要在查询语句的其它部分引用到Person
[sql]
From Person as p
子句中可以同时出现多个类, 其查询结果是产生一个笛卡儿积或产生跨表的连接
[sql]
From Person as p ,MyEvent as e
三、关联与连接
当程序需要从多个数据表中获取数据时,Hibernate使用关联映射来处理底层数据表之间的连接,一旦我们提供了正确的关联映射后,当程序通过Hibernate进行持久化访问时,将可利用Hibernate的关联来进行连接。
HQL支持两种关联join的形式:implicit(隐式) 与explicit(显式)。
显式form子句中明确给出了join关键字,而隐式使用英文点号(.)来连接关联实体。
受支持的连接类型是从ANSI SQL中借鉴来的。
inner join(内连接)
left outer join(左外连接)
right outer join(右外连接)
full join (全连接,并不常用)
使用显式连接,可以通过with关键字来提供额外的join条件
[sql]
From Person as p inner join p.myEvent e with p.id=e.id
从上面可以看出with关键字的作用等同于SQL中on关键字的作用:用于指定连接条件。还有,一个"fetch"连接允许仅仅使用一个选择语句就将相关联的对象或一组值的集合随着他们的父对象的初始化而被初始化,这种方法在使用到集合的情况下尤其有用,对于关联和集合来说,它有效的代替了映射文件中的外联接与延迟声明(lazy declarations)。
对于隐式连接和显示连接有如下两个区别:
1、显式连接底层将转换成SQL99的交叉连接,显式连接底层将转换成SQL99的inner join、left join、right join等连接。
2、隐式连接和显式连接查询后返回的结果不同。使用隐式连接查询返回的结果是多个被查询实体组成的集合。使用显式连接的结果分为两种:如果HQL语句中省略select关键字时,返回的结果也是集合,但集合元素是被查询持久化对象、所有被关联的持久化对象所组成的数组。如果没有省略select关键字,返回的结果同样是集合,集合中的元素是跟在select关键字后的持久化对象组成的数组。
[sql]
Form Person as p inner join p.myEvent as e with p.id=e.id //...........1
Select p from Person as p inner join p.myEvent as e with p.id=e.id //.........2
........1中返回的结构是有Person实体和MyEvent实体组成的数组集合。而.........2 返回的结果是只有Person组成的集合。
对于有集合属性的。Hibernate默认采用延迟加载策略。如对于持久化类Person,有集合属性myEvent。加载Person实例时,默认是不加载myEvent的,如果session被关闭了,Person实例将会无法访问到关联的myEvent属性的。为了解决这个问题,可以再Hibernate映射文件中配置指定:lazy="false"来关闭延迟加载。或者使用join fetch:
[sql]
From Person as p join fetch p.myEvent
一个fetch连接通常不需要被指定别名, 因为相关联的对象不应当被用在 where 子句 (或其它任何子句)中。同时,相关联的对象并不在查询的结果中直接返回,但可以通过他们的父对象来访问到他们。
使用fetch关键字时需要注意以下几个问题:
1、fetch不应该与setMaxResults()和setFirstResults()共用,<
补充:软件开发 , Java ,