根据已经加载的对象导航到其他对象
例如:在前面的各种映射关系中,实体类包含对其他类对象的引用。
Dept d = (Dept) session.get(Dept.class,2);
d.getStaffSet().size(); //d对象关联Staff集合,hibernate会自动检索Staff数据。如何检索的,看下面图中发送的sql语句。
1.2、OID检索方式
按照对象的OID来检索对象
依赖Session接口主要是:load()/get()的用法
1.3、HQL检索方式
HQL:Hibernate Query Language ,是面向对象的查询语言,它和SQL查询语言有些相似,在Hibernate提供的各种检索方式中,HQL是使用的最广的一种检索方式,
注意:HQL操作的全是POJO类中的属性,而不是操作数据库表中的字段。
1.4、QBC检索方式
QBC:Query By Criteria,是一种更加面向对象的查询语言,提供的一系列QBC API来检索对象。
HQL所能做的事情,使用QBC也大多能做用,这个通过实例来看看QBC是如何使用的。
步骤:
1>获得session
2>session.createCriteria(Obejct.class); 创建criteria对象
3>使用criteria的API方法进行条件的增加。add(Restrictions.eq(属性名,值))
4>执行查询
list():返回一个集合列表,有可能集合中装的是数组,有可能是POJO对象。
uniqueResult():返回一个查询结果,在已知查询结果只有一个或者0个时,使用是没有问题的,如果返回结果有多个,那么就会报异常
例子一:使用QBC来对Staff进行查询
//使用QBC,更加面向对象,不用写sql语句。要查询什么,就直接将其类.class当作参数就能查询出来
Criteria QBCCriteria = session.createCriteria(Staff.class);
List<Staff> staffList = QBCCriteria.list();
for(Staff staff : staffList){
System.out.println(staff.toString());
}
//结果
Hibernate:
select
this_.id as id1_0_,
this_.name as name1_0_,
this_.deptId as deptId1_0_
from
staff this_
Staff [id=2, name=qqq1]
Staff [id=3, name=qqq2]
Staff [id=4, name=qqq3]
Staff [id=5, name=qqq4]
Staff [id=6, name=qqq5]
Staff [id=7, name=qqq6]
Staff [id=8, name=qqq7]
Staff [id=9, name=qqq8]
Staff [id=10, name=qqq9]
例子二:使用QBC来对Staff进行条件查询
//使用QBC,对Staff进行查询
Criteria QBCCriteria = session.createCriteria(Staff.class);
//add()添加条件,通过Restrictions(字段名,值),由于确定是1行记录,所以直接用uniqueResult()
Staff staff = (Staff) QBCCriteria.add(Restrictions.eq("id",3)).uniqueResult();
System.out.println(staff.toString());
//结果
Hibernate:
select
this_.id as id1_0_,
this_.name as name1_0_,
this_.deptId as deptId1_0_
from
staff this_
where
this_.id=?
Staff [id=3, name=qqq2]
例子三:QBC也能进行连接查询
// from Staff inner join dept d ON 后面是hibernate自动帮我们填写;
Criteria criteria = session.createCriteria(Staff.class);
//createAlias默认是内连接,可以不用写。可以为dept表取别名,也可以不取。
criteria.createAlias("dept", "d", Criteria.INNER_JOIN);
List list = criteria.list();
System.out.println(list);
//结果
Hibernate:
select
this_.id as id1_1_,
this_.name as name1_1_,
this_.deptId as deptId1_1_,
d1_.id as id0_0_,
d1_.name as name0_0_
from
staff this_
inner join
dept d1_
on this_.deptId=d1_.id
[oneToMany.Staff@6a155d66, oneToMany.Staff@55a7e5ae, oneToMany.Staff@1d82e71, oneToMany.Staff@17d0fda9, oneToMany.Staff@19bd6e76, oneToMany.Staff@639f122d, oneToMany.Staff@60627b73, oneToMany.Staff@6196ec74, oneToMany.Staff@7b7de5b9]
给一张表来看看qbc增加的条件查询语句。
重点有一个离线Criteria对象的用法。
1、在web层封装查询条件到离线Criteria对象中,将其DetachedCriteria对象绑定到Thread上。
2、到dao层,就能通过Thread拿到该离线Criteria对象,然后创建session。将session给DetachedCriteria,就能够执行查询
代码:
WEB层
DetachedCriteria detachedCriteria =DetachedCriteria.forClass(Customer.class);
detachedCriteria.add(Restrictions.eq("name", "kitty"));
DAO层
Session session = HibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
// 将离线查询对象 关联到Session
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
Customer customer = (Customer) criteria.uniqueResult();
1.5、本地SQL检索方式
使用标准的SQL语句来编写。
步骤:
1>获得session
2>编写sql语句
3>session.createSQLQuery(sql);获取SQLQuey对象
4>给sql语句设置参数。
5>执行查询
list():返回一个集合列表,集合中装的是Object[]。
返回实体类对象集合,如果与实体类进行了绑定,也就是使用了addEntity(xxx.class)。
二、总结
以上就是我们说的5种检索,其中说的重点就是hql的用法,上面的例子全部写完了差不多就对hql有一定的了解。记住hql是对pojo类进行操作,而不是对数据库中的表。在使用连接查询时,可以使用QBC,因为更简单,只需要用createAlias()就能使用任何的连接。一般在开发中sql语句都会提取出来放到hbm中,例如
在hbm映射文件 (也可以用注解配置)
<!-- 这里可以定义命名查询 -->
<!-- 定义 HQL 语句 <query name=""></query> -->
<!-- 定义 SQL 语句 <sql-query name=""></sql-query> -->
<query name="findCustomerByName">
<![CDATA[from Customer where name = ?]]>
</query>
* 为hql语句 起了一个名字
程序代码:
//相当于把sql语句分离开来了。方便维护
Query query = session.getNamedQuery("findCustomerByName");
query.setParameter(0, "tom");
Customer customer = (Customer) query.uniqueResult();