或者
<class name="cn.itcast.hibernate0909.fetch.Classes" lazy="true">注意:不管SClasses.hbm.xml文件的<class>元素的lazy属性是true还是false,Session的get()方法及Query的list()方法在School类级别总是使用立即检索策略。
默认的检索策略是立即检索。在Hibernate映射文件中,通过在<class>上配置 lazy属性来确定检索策略。对于Session的检索方式,类级别检索策略仅适用于load方法;也就说,对于get、qurey检索,持久化对象都会被立即加载而不管lazy是false还是true.一般来说,我们检索对象就是要访问它,因此立即检索是通常的选择。由于load方法在检索不到对象时会抛出异常(立即检索的情况下),因此我个人并不建议使用load检索;而由于<class>中的lazy属性还影响到多对一及一对一的检索策略,因此使用load方法就更没必要了。
在<set>标签上或者在<many-to-one>上设置两个属性值来控制其检索策略, fetch、lazy
fetch:代表检索时的语句的方式,比如左外连接等。
fetch:join、select 、subselect
lazy:是否延迟加载。
lazy:true、false、extra
分两种情况
fetch=select时,生成多条简单sql查询语句
可以发现发出了n+1条查询语句。
批量检索 什么叫批量检索,就是多条sql语句才能完成的查询,现在一条sql语句就能解决多条sql语句才能完成的事情。
重新测试
Hibernate: select classes0_.cid as cid0_, classes0_.cname as cname0_, classes0_.description as descript3_0_ from Classes classes0_ Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description as descript3_1_0_, students0_.cid as cid1_0_ from Student students0_ where students0_.cid in (?, ?, ?, ?) 菜肉哥! 包子哥! caicai CCC zxczxc qweqwe可以看结果,只发送两条sql语句,第一条是查询班级的,第二条是一看使用关键字 IN 来将所有的班级ID含括在内 这样就只需要发送一条sql语句,来达到发送5条sql语句才能完成的功能。 这就是批量检索
上面是从一查多,batch-size放在set中。从多查一呢,在many-to-one中并没有batch-size这个属性。注意了,此时batch-size放在一方的class中
疑问一:为什么从一到多,batch-size就放在set中,而从多到一,batch-size也是放在一方的class中? 这样去想:一方查多方,在一方的set中就代表着多方的对象,将batch-size放在set中,就可以理解查多方的时候,就使用批量检索了。 多方查一方,在一方的class中设置batch-size。可以理解,当多方查到一方时,在一方的映射文件中的class部分遇到了batch-size就知道查询一方时需要批量检索了 这样应该更好理解和记忆。如果抓取策略改成join
从sql语句可以看出,join用的是左外连接.。join该需求变成一条sql语句
