学习目标:

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. 文件,添加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. 文件:

<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>

因为你不知道这个查询会查询到多少条语句,所以一般情况下面这个还是不要配置的好。

收藏 打印