延时查询

发表时间:2017-05-17 17:28:39 浏览量( 16 ) 留言数( 0 )

学习目标:

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>

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