预先抓取采用的是fetch="join"的方式
预先抓取指的是通过select语句使用outer join 一般是左外连接来获得对象的关联实例或者是关联的集合(集合被初始化了,这是重点)。
用上面的例子,加上一个身份证的对象。CARD 他和学生对象是一对一的关系。
身份-----立-----学-----立即------班
证-------即------生-----立即-----级
注释:max_fetch_depth是在hibernate.hbm.xml中设置。表示可以预先抓取的深度。
如果设置为1,表示只可以外连接一个表,如果这是为0,那么所有的预先抓取的策略将变成立即加载。
三者的对象都采取立即加载的方式。并且设置max_fetch_depth=0
打印:
Hibernate: select team0_.ID as ID0_0_, team0_.Name as Name0_0_ from test.team team0_ where team0_.ID=?
Hibernate: select students0_.teamID as teamID1_, students0_.ID as ID1_, students0_.ID as ID1_0_, students0_.Name as Name1_0_, students0_.TeamID as TeamID1_0_ from test.student students0_ where students0_.teamID=?
Hibernate: select card0_.ID as ID2_0_, card0_.StudentID as StudentID2_0_, card0_.Name as Name2_0_ from test.card card0_ where card0_.ID=?
Hibernate: select card0_.ID as ID2_0_, card0_.StudentID as StudentID2_0_, card0_.Name as Name2_0_ from test.card card0_ where card0_.ID=?
可以发现,对应于每个学生都会分别发出一条SQL语句去查询card的信息。
如果有100个学生那么就会发出100条SQL语句去查询card的信息。
这样很明显会降低系统的性能。
如果全部设置成预先抓取的话。
Hibernate: select team0_.ID as ID0_2_, team0_.Name as Name0_2_, students1_.teamID as teamID4_, students1_.ID as ID4_, students1_.ID as ID1_0_, students1_.Name as Name1_0_, students1_.TeamID as TeamID1_0_, card2_.ID as ID2_1_, card2_.StudentID as StudentID2_1_, card2_.Name as Name2_1_ from test.team team0_ left outer join test.student students1_ on team0_.ID=students1_.teamID left outer join test.card card2_ on students1_.ID=card2_.ID where team0_.ID=?
就只会发出一条SQL语句。
预先抓取和max_fetch_depth有很大的关系。