一对多 、多对多 的检索策略
来源:互联网 发布:淘宝商城行车记录仪 编辑:程序博客网 时间:2024/05/22 12:39
在映射文件中, 用 <set> 元素来配置一对多关联及多对多关联关系. <set> 元素有 lazy 和 fetch 属性
lazy: 主要决定 orders 集合被初始化的时机. 即到底是在加载 Customer 对象时就被初始化, 还是在程序访问 orders 集合时被初始化
fetch: 取值为 “select” 或 “subselect” 时, 决定初始化 orders 的查询语句的形式; 若取值为”join”, 则决定 orders 集合被初始化的时机若把 fetch 设置为 “join”, lazy 属性将被忽略
② 当取fasle 时,
运行的SQL
①取值为 select
运行的SQL
lazy: 主要决定 orders 集合被初始化的时机. 即到底是在加载 Customer 对象时就被初始化, 还是在程序访问 orders 集合时被初始化
fetch: 取值为 “select” 或 “subselect” 时, 决定初始化 orders 的查询语句的形式; 若取值为”join”, 则决定 orders 集合被初始化的时机若把 fetch 设置为 “join”, lazy 属性将被忽略
<set> 元素的 batch-size属性:用来为延迟检索策略或立即检索策略设定批量检索的数量. 批量检索能减少 SELECT 语句的数目, 提高延迟检索或立即检索的运行性能.
Clazz 类 的对象关系映射,之一中的set 属性中的配置
<hibernate-mapping package="com.baidu.setStrategy"><!-- lazy 类级别的懒加载 --> <class name="Clazz" table="CLAZZS" > <id name="clazzId" type="java.lang.Integer"> <column name="CLAZZ_ID" /> <generator class="native" /> </id> <property name="clazzName" type="java.lang.String"> <column name="CLAZZ_NAME" /> </property> <set name="stus" table="STUDENTS" lazy="true"> <key> <column name="CLAZZ_ID" /> </key> <one-to-many class="Student" /> </set> </class> </hibernate-mapping>
/** * Set 的 lazy 属性 * 1. 1-n 或n-n 的集合属性默认使用懒加载检索策略 * 2. 可以通过设置set 的lazy 属性来修改默认的检索策略,默认为true * 并不建议设置为false * 3. lazy 还可以设置为extra,增强的延迟检索。该取值会尽可能的延迟集合初始化的时机 * 4.Hibernate.initialize() 静态方法显式初始化 */
Lazy 属性:默认值是true
① 当取true 时,
@Testpublic void testOne2ManyLevelStrategy() {Clazz clazz =(Clazz) session.get(Clazz.class, 1); System.out.println(clazz.getClass());System.out.println(clazz.getStus().size());}运行的SQL
Hibernate: select clazz0_.CLAZZ_ID as CLAZZ_ID1_0_0_, clazz0_.CLAZZ_NAME as CLAZZ_NA2_0_0_ from CLAZZS clazz0_ where clazz0_.CLAZZ_ID=?class com.baidu.setStrategy.ClazzHibernate: select stus0_.CLAZZ_ID as CLAZZ_ID3_0_1_, stus0_.STU_ID as STU_ID1_1_1_, stus0_.STU_ID as STU_ID1_1_0_, stus0_.STU_NAME as STU_NAME2_1_0_ from STUDENTS stus0_ where stus0_.CLAZZ_ID=?2
② 当取fasle 时,
运行的SQL
Hibernate: select clazz0_.CLAZZ_ID as CLAZZ_ID1_0_0_, clazz0_.CLAZZ_NAME as CLAZZ_NA2_0_0_ from CLAZZS clazz0_ where clazz0_.CLAZZ_ID=?Hibernate: select stus0_.CLAZZ_ID as CLAZZ_ID3_0_1_, stus0_.STU_ID as STU_ID1_1_1_, stus0_.STU_ID as STU_ID1_1_0_, stus0_.STU_NAME as STU_NAME2_1_0_ from STUDENTS stus0_ where stus0_.CLAZZ_ID=?class com.baidu.setStrategy.Clazz2
③ 当取extra 时,
运行的SQL
Hibernate: select clazz0_.CLAZZ_ID as CLAZZ_ID1_0_0_, clazz0_.CLAZZ_NAME as CLAZZ_NA2_0_0_ from CLAZZS clazz0_ where clazz0_.CLAZZ_ID=?class com.baidu.setStrategy.ClazzHibernate: select count(STU_ID) from STUDENTS where CLAZZ_ID =?2在添加测试方法中添加代码
@Testpublic void testOne2ManyLevelStrategy() {Clazz clazz =(Clazz) session.get(Clazz.class, 1); System.out.println(clazz.getClass());System.out.println(clazz.getStus().size());Student student = new Student();student.setStuId(1);System.out.println(clazz.getStus().contains(student));}运行的SQL
Hibernate: select clazz0_.CLAZZ_ID as CLAZZ_ID1_0_0_, clazz0_.CLAZZ_NAME as CLAZZ_NA2_0_0_ from CLAZZS clazz0_ where clazz0_.CLAZZ_ID=?class com.baidu.setStrategy.ClazzHibernate: select count(STU_ID) from STUDENTS where CLAZZ_ID =?2Hibernate: select 1 from STUDENTS where CLAZZ_ID =? and STU_ID =?true④ 当使用Hibernate.initialize() 静态方法 时
@Testpublic void testOne2ManyLevelStrategy() {Clazz clazz =(Clazz) session.get(Clazz.class, 1); System.out.println(clazz.getClass());System.out.println(clazz.getStus().size());Student student = new Student();student.setStuId(1);System.out.println(clazz.getStus().contains(student));Hibernate.initialize(clazz.getStus());}运行的SQL
Hibernate: select clazz0_.CLAZZ_ID as CLAZZ_ID1_0_0_, clazz0_.CLAZZ_NAME as CLAZZ_NA2_0_0_ from CLAZZS clazz0_ where clazz0_.CLAZZ_ID=?class com.baidu.setStrategy.ClazzHibernate: select count(STU_ID) from STUDENTS where CLAZZ_ID =?2Hibernate: select 1 from STUDENTS where CLAZZ_ID =? and STU_ID =?trueHibernate: select stus0_.CLAZZ_ID as CLAZZ_ID3_0_1_, stus0_.STU_ID as STU_ID1_1_1_, stus0_.STU_ID as STU_ID1_1_0_, stus0_.STU_NAME as STU_NAME2_1_0_ from STUDENTS stus0_ where stus0_.CLAZZ_ID=?
/** * Set 的 batch-size 属性: 设定一次初始化 set 集合的数量 */batch-size 属性
@Testpublic void testSetBatchSize() {List<Clazz> clazzs = session.createQuery("FROM Clazz").list();System.out.println(clazzs.size());for(Clazz clazz:clazzs ){if(clazz.getStus() != null)System.out.println(clazz.getStus().size());}}① 当没有使用batch-size 属性时,
运行的SQL
Hibernate: select clazz0_.CLAZZ_ID as CLAZZ_ID1_0_, clazz0_.CLAZZ_NAME as CLAZZ_NA2_0_ from CLAZZS clazz0_3Hibernate: select stus0_.CLAZZ_ID as CLAZZ_ID3_0_1_, stus0_.STU_ID as STU_ID1_1_1_, stus0_.STU_ID as STU_ID1_1_0_, stus0_.STU_NAME as STU_NAME2_1_0_ from STUDENTS stus0_ where stus0_.CLAZZ_ID=?2Hibernate: select stus0_.CLAZZ_ID as CLAZZ_ID3_0_1_, stus0_.STU_ID as STU_ID1_1_1_, stus0_.STU_ID as STU_ID1_1_0_, stus0_.STU_NAME as STU_NAME2_1_0_ from STUDENTS stus0_ where stus0_.CLAZZ_ID=?2Hibernate: select stus0_.CLAZZ_ID as CLAZZ_ID3_0_1_, stus0_.STU_ID as STU_ID1_1_1_, stus0_.STU_ID as STU_ID1_1_0_, stus0_.STU_NAME as STU_NAME2_1_0_ from STUDENTS stus0_ where stus0_.CLAZZ_ID=?2当在clazz的配置文件的set属性中添加batch-size = "5" :表示一次初始化5条记录
<set name="stus" table="STUDENTS" lazy="true" batch-size="5"> <key> <column name="CLAZZ_ID" /> </key> <one-to-many class="Student" /> </set>
运行的SQL
Hibernate: select clazz0_.CLAZZ_ID as CLAZZ_ID1_0_, clazz0_.CLAZZ_NAME as CLAZZ_NA2_0_ from CLAZZS clazz0_3Hibernate: select stus0_.CLAZZ_ID as CLAZZ_ID3_0_1_, stus0_.STU_ID as STU_ID1_1_1_, stus0_.STU_ID as STU_ID1_1_0_, stus0_.STU_NAME as STU_NAME2_1_0_ from STUDENTS stus0_ where stus0_.CLAZZ_ID in ( ?, ?, ? )222
fetch属性: 取值为 “select” 或 “subselect” 时, 决定初始化 students 的查询语句的形式;
若取值为”join”, 则决定orders 集合被初始化的时机
/** * Set 的 fetch 属性: * 1. 默认值为select:通过正常的方式来初始化set元素 * 2. 可以取值subselect: * ① 通过子查询的方式来初始化所有的 set 集合。子查询作为where 子句的 in的条件出现, * 子查询查询所有1 的一端的ID * ② 此时lazy 有效,但是batch-size 属性将被忽略,不再起作用。 */
/** * Set 的 fetch 属性: * 3. 可以取值为join: batch-size有效 * ① 在加载 1 的一端的对象时,使用迫切左外连接的方式检索 n 的一端的集合属性 * * ② 会忽略lazy 属性 * * ③ 使用HQL 查询时,会 忽略fetch=join * * * 迫切左外连接:使用左外连接进行查询,且把集合属性进行初始化 */fetch:
①取值为 select
<set name="stus" table="STUDENTS" lazy="true" batch-size="2" fetch="subselect"> <key> <column name="CLAZZ_ID" /> </key> <one-to-many class="Student" /> </set>
@Testpublic void testSetFetchSelectOrSubselect() {List<Clazz> clazzs = session.createQuery("FROM Clazz").list();System.out.println(clazzs.size());for(Clazz clazz:clazzs ){if(clazz.getStus() != null)System.out.println(clazz.getStus().size());}}运行的SQL
Hibernate: select clazz0_.CLAZZ_ID as CLAZZ_ID1_0_, clazz0_.CLAZZ_NAME as CLAZZ_NA2_0_ from CLAZZS clazz0_3Hibernate: select stus0_.CLAZZ_ID as CLAZZ_ID3_0_1_, stus0_.STU_ID as STU_ID1_1_1_, stus0_.STU_ID as STU_ID1_1_0_, stus0_.STU_NAME as STU_NAME2_1_0_ from STUDENTS stus0_ where stus0_.CLAZZ_ID in ( ?, ? )22Hibernate: select stus0_.CLAZZ_ID as CLAZZ_ID3_0_1_, stus0_.STU_ID as STU_ID1_1_1_, stus0_.STU_ID as STU_ID1_1_0_, stus0_.STU_NAME as STU_NAME2_1_0_ from STUDENTS stus0_ where stus0_.CLAZZ_ID=?2
② 取值为usubselect
Hibernate: select clazz0_.CLAZZ_ID as CLAZZ_ID1_0_, clazz0_.CLAZZ_NAME as CLAZZ_NA2_0_ from CLAZZS clazz0_3Hibernate: select stus0_.CLAZZ_ID as CLAZZ_ID3_0_1_, stus0_.STU_ID as STU_ID1_1_1_, stus0_.STU_ID as STU_ID1_1_0_, stus0_.STU_NAME as STU_NAME2_1_0_ from STUDENTS stus0_ where stus0_.CLAZZ_ID in ( select clazz0_.CLAZZ_ID from CLAZZS clazz0_ )222③ 取值为 join
<set name="stus" table="STUDENTS" lazy="true" batch-size="2" fetch="join"> <key> <column name="CLAZZ_ID" /> </key> <one-to-many class="Student" /> </set>
@Testpublic void testSetFetchJoin() {Clazz clazz = (Clazz) session.get(Clazz.class, 1);System.out.println(clazz.getStus().size());}
使用HQL 查询时,batch-size有效, 但会 忽略fetch=join ,
Hibernate: select clazz0_.CLAZZ_ID as CLAZZ_ID1_0_, clazz0_.CLAZZ_NAME as CLAZZ_NA2_0_ from CLAZZS clazz0_3Hibernate: select stus0_.CLAZZ_ID as CLAZZ_ID3_0_1_, stus0_.STU_ID as STU_ID1_1_1_, stus0_.STU_ID as STU_ID1_1_0_, stus0_.STU_NAME as STU_NAME2_1_0_ from STUDENTS stus0_ where stus0_.CLAZZ_ID in ( ?, ? )22Hibernate: select stus0_.CLAZZ_ID as CLAZZ_ID3_0_1_, stus0_.STU_ID as STU_ID1_1_1_, stus0_.STU_ID as STU_ID1_1_0_, stus0_.STU_NAME as STU_NAME2_1_0_ from STUDENTS stus0_ where stus0_.CLAZZ_ID=?2
@Testpublic void testSetFetchJoin() {Clazz clazz = (Clazz) session.get(Clazz.class, 1);System.out.println(clazz.getStus().size());}
运行的SQL
Hibernate: select clazz0_.CLAZZ_ID as CLAZZ_ID1_0_1_, clazz0_.CLAZZ_NAME as CLAZZ_NA2_0_1_, stus1_.CLAZZ_ID as CLAZZ_ID3_0_3_, stus1_.STU_ID as STU_ID1_1_3_, stus1_.STU_ID as STU_ID1_1_0_, stus1_.STU_NAME as STU_NAME2_1_0_ from CLAZZS clazz0_ left outer join STUDENTS stus1_ on clazz0_.CLAZZ_ID=stus1_.CLAZZ_ID where clazz0_.CLAZZ_ID=?2
0 0
- 一对多 、多对多 的检索策略
- Hibernate的检索策略-一对多和多对多关联
- 多对一和一对一关联的检索策略
- hibernate 一对多主键策略
- Mybatis的多对一,一对多
- 一对多里对 set 的排序
- mybatis一对多的策略,嵌套对象分装
- 多对一 检索
- 一对多 多对多
- 关于Hibernate一对多、多对一(单向一对多)、双向一对多的一些个人理解。
- SQL 一对多关系检索多行中的一条记录
- hibernate 一对一、一对多、多对多的情况
- 数据库的一对一,一对多,多对多
- hql:一对多和多对多的结合
- 一对多和多对多的区别
- Hibernate中一对一,一对多,多对多的写法
- mybatis的一对多和多对多查询
- mybatis的一对多和多对多查询
- 线程等待例子,来自微软
- 下载的网页模板只显示英文不显示中文
- 文章标题
- ExecutorService对象的shutdown()和shutdownNow()的区别
- 萌妹子Python入门指北(五)
- 一对多 、多对多 的检索策略
- 建立高效的并发模型 in cpp
- Quartz的任务的临时启动和暂停和恢复
- 设置TaxtView的监听
- 流(3.5.1~3.5.2)
- 文章标题
- Live Stream Procedure
- Centos下vim、ctags的配置及基本用法
- Spring 3整合Quartz 2实现定时任务--转