抓取策略应用的范围及作用:
主要用于set集合对象在提取数据时对hibernate底层的sql语句的操作,即由一个对象对关联对象查询,发出怎样的sql语句的机制。
以学生和班级为例:
抓取策略:
1、研究的主要是set集合如何提取数据
2、在Classes.hbm.xml文件中
<set fetch="join/select/subselect">
join 左外连接
如果把需求分析翻译sql语句,存在子查询,这个时候用该策略不起作用
select 默认
先查询一的一端,再查询多的一端
subselect 子查询
如果需要分析翻译成sql语句存在子查询,这个时候用该策略效率最高
例子示例:
/** * 查询所有班级下的所有学生 * 解决问题的方案:子查询 fetch="subselect" */ //@Test public void testAll_Classes(){ Session session = sessionFactory.openSession(); List<Classes> cList = session.createQuery("from Classes").list(); for(Classes classes:cList){ Set<Student> students = classes.getStudents(); for(Student student:students){ System.out.println(student.getSname()); } } session.close(); }
对应的class映射文件配置
<set name="students" cascade="save-update" inverse="true" fetch="join"> <!-- key是用来描述外键 --> <key> <column name="cid"></column> </key> <one-to-many class="cn.itcast.hiberate.sh.domain.Student"/> </set>
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=?
输出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=?
@Test /** * 查询班级号为1的所有学生 */ public void testQueryClasses_Id(){ Session session = sessionFactory.openSession(); Classes classes = (Classes)session.get(Classes.class, 1L); Set<Student> students = classes.getStudents(); for(Student student:students){ System.out.println(student.getSname()); } session.close(); }配置文件为:
Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=? 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=?
Hibernate: select classes0_.cid as cid0_1_, classes0_.cname as cname0_1_, classes0_.description as descript3_0_1_, students1_.cid as cid0_3_, students1_.sid as sid3_, students1_.sid as sid1_0_, students1_.sname as sname1_0_, students1_.description as descript3_1_0_, students1_.cid as cid1_0_ from Classes classes0_ left outer join Student students1_ on classes0_.cid=students1_.cid where classes0_.cid=?
一般来讲,发出的sql语句越少性能越高。
关于懒加载:
当要取出的set集合中的数据量很大时,我们使用懒加载,即当我们需要用到该对象时,才从数据库里加载,即当出现使用student.getXxx()等方法时才加载session.get()方法是不加载。
懒加载
1、类的懒加载
1、利用session.load方法可以产生代理对象
2、在session.load方法执行的时候并不发出sql语句
3、在得到其一般属性的时候发出sql语句
4、只针对一般属性有效,针对标示符属性是无效的
5、默认情况就是懒加载
2、集合的懒加载
false 当session.get时,集合就被加载出来了
true 在遍历集合的时候才加载
extra
针对集合做count,min,max,sum等操作
3、单端关联的懒加载(多对一)
<many-to-one lazy="false/no-proxy/proxy"> no-porxy 默认值 true
根据多的一端加载一的一端,就一个数据,所以无所谓
总结:懒加载主要解决了一个问题:类、集合、many-to-one在时候发出SQL语句,加载数据
hibernate的抓取策略和懒加载,布布扣,bubuko.com
原文:http://blog.csdn.net/kingherooo/article/details/20865179