学习目标:
1、了解Hibernate的延时操作的特点
学习过程:
一、默认的延时加载
通过上面几节课的配置之后,我们的javaBean就不是独立存在的了,那么我们这样配置有什么好处呢。这样配置之后我们就可以使用面向对象的思想,非常容易的操作数据库和查询数据库信息了,下面我们就讲讲如何延时查询数据了。
我们经常在查询员工的时候都需要显示该员工的职务,以前我们需要查询两张表,一般我们可以写一个链接查询,或者执行两次的查询,如果涉及的表比较多,那么查询会更加复杂,hibernate可以帮助我们解决这个问题。
看一下下面的代码:
public class Run5 {
public static void main(String[] args) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
// 开启一个事务
session.beginTransaction();
Employee employee=session.get(Employee.class, 5);
System.out.println(employee.getEmployeeName());
//必须再同一个session中,
//如果没有这个获取操作,hibernate不会执行对Post表的查询的,但是如果有就会执行sql查询,这就是延时的查询,非常智能
System.out.println(employee.getPost().getPostName());
// 提交事物
session.getTransaction().commit();
session.close();
HibernateUtil.getSessionFactory().close();
}
}
我们可以先注释了employee.getPost()的代码。看一下输出的sql,然后再开启看一下输出的sql。你就会看出之间的区别的了。
我们也可以看一下多对多的测试。然后再开启,看一下输出,你会发现hibernate确实非常智能,在同一个会话中,能根据你的需要去查询数据库
public class Run6 {
public static void main(String[] args) {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
// 开启一个事务
session.beginTransaction();
Login login=session.get(Login.class, 4);
//必须再同一个session中,
//如果没有这个获取操作,hibernate不会执行对Post表的查询的,但是如果有就会执行sql查询,这就是延时的查询,非常智能
System.out.println(login.getRoles().size());
Set<Role> roles=login.getRoles();
for(Role role:roles) {
System.out.println(role.getRoleName());
}
// 提交事物
session.getTransaction().commit();
session.close();
HibernateUtil.getSessionFactory().close();
}
}
二、显示的加载
我们可以看到hibernate默认的方式就已经非常好了,但是如果你想显示的操作也可以的,因为不是很推荐这样的操作,所以下面的内容大家就参考一下就可以了。修改post.hbm.xml文件,添加fetch="join"或者lazy="false",两个写一个就行了。我们先写fetch="join"吧。
<many-to-one name="post" class="com.javadayup.stuormrelate.Post" cascade="save-update" fetch="join" >
<column name="post_id"></column>
</many-to-one>
修改EmployeeDao的代码,写一个根据员工id查询的语句,
运行上面的代码,查看一下输入,就会发现员工的职务名称也可以打印出来,输出的sql语句也表明确实对Post表做了一个左外连接查询。
我们删除fetch="join",写上lazy="false",再次运行上面的代码,结果如下:
<many-to-one name="post" class="com.pojo.Post" cascade="save-update" lazy="false" >
<column name="post_id"></column>
</many-to-one>
员工的职务还是可以查询出来,不过生成的sql语句有点不同,而是执行了两次查询
我们还可以在做多一个实验,获得账号名称,员工名称,和该账号所有的角色,这样需要涉及的表比较多。但是我们可以修改配置文件就可以很方便的实现这个功能。
修改Login.hbm.xml文件:
<many-to-one name="employee" class="com.pojo.Employee" unique="true" lazy="false" >
<column name="employee_id" />
</many-to-one>
<set name="roles" table="login_role" lazy="false" >
<key column="login_id"></key>
<many-to-many column="role_id" class="com.pojo.Role"></many-to-many>
</set>
大家可以看到,hibernate可以帮助我们很好的完成复杂的查询,不过大家必须要谨慎使用这些功能,因为hibernate有可能会查询了很多你根据就不需要的数据,尤其是在对集合set配置的时候,如下面的代码
<set name="roles" table="login_role" lazy="false" >
<key column="login_id"></key>
<many-to-many column="role_id" class="com.javadayup.stuormrelate.Role"></many-to-many>
</set>
因为你不知道这个查询会查询到多少条语句,所以一般情况下面这个还是不要配置的好。