Hibernate的数据检索策略(二)

    技术2022-05-19  23

    (3)  预先抓取

          预先抓取指的是Hibernate通过select语句使用outer join(外连接,一般是左外连接left outer join)来获得对象的关联实例或者关联集合(集合被初始化了,这是重点)。分两种情况来讨论

          情况一:对象之间全都是立即加载

          假设对象之间全都是立即加载,有三张表:班级(Team)、学生(Student)和身份证(Certificate),有如下代码:

           -----//打开Session,开启事务

           Team team = (Team)session.get(Team.class,1);

           -----//提交事务,关闭Session

           上述程序运行后控制台的显示结果如下:

          Hibernate:select t.* from team t where t.id=?

          Hibernate:select s.* from student s where team.id=?

          Hibernate:select c.* fromcertificate c  where c.id=?

          Hibernate:select c.* fromcertificate c  where c.id=?

          可见通过取得班级对象,从而递归的取得了学生和身份证对象。Hibernate共发送4条sql语句来得到这些数据,如果关联的对象很多(如果有100个学生,则要发送100条sql语句去取得100个身份证),使用立即检索方式是不适合的。

     

          情况二:对象之间全都是预先抓取

          假设对象之间全都是预先抓取,同样运行上面的代码,控制台显示结果如下:

          Hibernate:select t.*,s.*,c.* from team t

          left outer join student s on t.id = s.team_id

          left outer join certificate c on s.id = c.id where team0_id=?

          只用一条sql语句就把使用立即检索时用的4条sql语句包括了。使用预先抓取不用理会有多少个学生,都是上面一条语句就可以把所有学生的身份证资料取出来,而是用立即加载的话,有100个学生就需要发送100条sql语句。但是使用1条sql语句来完成原先要100条才能完成的功能,给这一条语句带来的负担也是比较重的。可以使用hibernate.max_fetch_depth来控制。该值为1表示只允许外连接1个表,为0则表示不允许外连接,即外连接失效。

     

         实际使用时,一对多和多对多关系推荐使用延迟加载,而一对一和多对一关系推荐使用预先加载。


    最新回复(0)