Hibernate(四)
来源:互联网 发布:泽东书法 知乎 编辑:程序博客网 时间:2024/05/16 05:09
抓取策略
案例一
<!--默认值为”select” --><set name="students" lazy="true" fetch="select">
/** * 发出两条sql语句 */ @Test public void testSetFetch_Select(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); Classes classes = (Classes)session.get(Classes.class, 1L); Set<Student> students = classes.getStudents(); for(Student student:students){ System.out.println(student.getName()); } transaction.commit(); }
上述的图中会发出n+1条sql语句,1代表查询classes表的数据,n代表classes表中的记录数
Hibernate: select classes0_.cid as cid0_0_, classes0_.name as name0_0_ from Classes classes0_ where classes0_.cid=?Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.name as name1_0_, students0_.cid as cid1_0_ from Student students0_ where students0_.cid=?
案例二
<set name="students" lazy="true" fetch="join">
Hibernate: select classes0_.cid as cid0_1_, classes0_.name as name0_1_, students1_.cid as cid0_3_, students1_.sid as sid3_, students1_.sid as sid1_0_, students1_.name as name1_0_, students1_.cid as cid1_0_ from Classes classes0_ left outer join Student students1_ on classes0_.cid=students1_.cid where classes0_.cid=?
案例三
<set name="students" lazy="true" fetch="subselect">
/** * 查询所有的班级的所有的学生 */ @Test public void testSubSelect(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); List<Classes> classesList = session.createQuery("from Classes").list(); for(Classes classes:classesList){ Set<Student> students = classes.getStudents(); for(Student student:students){ System.out.println(student.getName()); } } transaction.commit(); }
Hibernate: select classes0_.cid as cid0_, classes0_.name as name0_ from Classes classes0_Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.name as name1_0_, students0_.cid as cid1_0_ from Student students0_ where students0_.cid in ( select classes0_.cid from Classes classes0_ )
案例四
/** * 查询cid为1,2,3的班级的信息和这些班级中学生的信息 */ @Test public void testSubSelect_2(){ Session session = sessionFactory.getCurrentSession(); Transaction transaction = session.beginTransaction(); List<Classes> classesList = session.createQuery("from Classes where cid in(1,2,3)").list(); for(Classes classes:classesList){ Set<Student> students = classes.getStudents(); for(Student student:students){ System.out.println(student.getName()); } } transaction.commit(); }
Hibernate: select classes0_.cid as cid0_, classes0_.name as name0_ from Classes classes0_ where classes0_.cid in ( 1 , 2 , 3 )Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.name as name1_0_, students0_.cid as cid1_0_ from Student students0_ where students0_.cid in ( select classes0_.cid from Classes classes0_ where classes0_.cid in ( 1 , 2 , 3 ) )
总结
需要一次性把数据全部查询出来,用join
如果经过需求分析翻译出来有子查询,用subselect
默认情况下用select
抓取策略的研究前提必须是关联对象,是研究怎么样发出sql语句来提取数据的
抓取策略只不过是hibernate给大家提供的一种优化策略而已。
因为抓取策略是写在映射文件中的,所以只能写一次。如果要想改变sql语句的结构,则用hql语句。
Subselect可以防止n+1条sql语句的出现
抓取策略和懒加载
1、研究对象为set集合
2、如果抓取策略为join,则懒加载失效
3、如果抓取策略为select,则保持懒加载的策略
4、如果抓取策略为subselect,则保持懒加载的策略
二级缓存
概念
1、为sessionFactory级别的缓存
2、二级缓存存放的是公共的数据
3、二级缓存的生命周期和sessionFactory的生命周期一样
4、二级缓存的存和取的策略
把数据存放到二级缓存中
Get方法
@Test public void testGet(){ Session session = sessionFactory.openSession(); Classes classes = (Classes)session.get(Classes.class, 2L); System.out.println(sessionFactory.getStatistics().getEntityLoadCount()); session.close(); session = sessionFactory.openSession(); classes = (Classes)session.get(Classes.class, 2L); session.close(); }
Hibernate: select classes0_.cid as cid0_0_, classes0_.name as name0_0_ from Classes classes0_ where classes0_.cid=?
只发出了一条sql语句,第二个session.get方法的对象来自于二级缓存
2、当session执行save或者update方法的时候,没有必要放入到二级缓存中,因为修改的因素很大。
二级缓存的统计机制
<!-- 开启hibernate的统计机制 --> <property name="hibernate.generate_statistics">true</property>
二级缓存的特点
一般情况下把一个对象放入到二级缓存中,对象的属性一般是不会改变的。
利用CacheModel控制二级缓存的对象
Hibernate: select classes0_.cid as cid0_0_, classes0_.name as name0_0_ from Classes classes0_ where classes0_.cid=?1Hibernate: update Classes set name=? where cid=?222
二级缓存的磁盘化
<diskStore path="e:\\TEMP1"/> <Cache name="cn.itcast.sh08.hibernate.domain.Classes" maxElementsInMemory="3" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
0 0
- Hibernate(四)
- Hibernate基础知识(四)
- Hibernate(四)Hibernate常用配置文件详解
- Hibernate学习笔记(四)
- Hibernate学习笔记(四)
- Hibernate关联关系(四)
- Hibernate(四)主键属性
- hibernate学习笔记(四)
- 再次认识Hibernate(四)
- Hibernate (四)基本特性
- Hibernate知识点概况(四)
- 【Hibernate】(四)基础映射
- Hibernate学习笔记(四)
- Hibernate学习笔记(四)
- 【Hibernate】(四)基础映射
- Hibernate(四)---映射关系
- Hibernate(四)
- hibernate(四)
- 示波器入门之采样率、存储深度
- Android资源文件中各种XML的作用与解释
- 【VS开发】设置文档标题
- 解读VC++编程中的文件操作API和CFile类
- java io流中涉及的设计模式
- Hibernate(四)
- SpringMVC初步-----参数传递
- 如果是初学C语言请看完 一些成功人士的心得
- Linux 链接脚本分析
- UDP理论详解
- 汉字拼音声母计算类
- 实习日记7_2016.06.28
- Tensorflow : Basic Dataset generation
- 每天一个命令(19) uname - print system information