Hibernate 抓取策略

    定义:通过一个对象,如何对关联对象发出sql语句,就是~。
        研究的主要是 set 集合如何提取数据。
        在Classes.hbm.xml 文件中<set   name=''  cascade=''   inverse=''   lazy=''   fetch='join/select/subselect'>,其中:
            join:左外连接,如果把需求分析翻译成sql语句存在子查询,这时候用join策略不起作用。
            select:默认的,先查询一的一端,再查询多的一端。
            subselect:子查询

    懒加载:决定什么时候发出sql语句。
    抓取策略:决定怎么样发出sql语句。



    子查询:select  *  
            from student  
            where  cid  in (select  cid  from  classes)


    1、项目 hibernante_sh_optimize

    2、建包和类 cn.google.hibernate.sh.test.FetchTest

		public class FetchTest extends HiberanteUtils{
			static{
				url = "hibernate.cfg.xml";
			}

			/**
			 * n+1 条查询
			 * 解决问题的方案:子查询
			 * 查询n个班级,再根据所有班级id,查询学生表(一共发出n+1条 sql 语句)
			 */
			@Test
			public  void  testAll_Classes(){
				Session session =  factory.openSession();
				List<Classes>  cList = session.createQuery("from  Classes").list();
				for(Classes  classes: cList){
					Set<Student>  students = classes.getStudents();
					for(Student  student:  students){
						s.o.p(student.getSname());
					}
				}
				session.close();
			}


			/**
			 * 代码相同,但是把Classes.hbm.xml中的<set   name=''  cascade=''   inverse=''   lazy=''   fetch='subselect'>
			 * 发出的sql 语句立刻变为“子查询”格式
			 */
			@Test
			public  void  testAll_Classes(){
				Session session =  factory.openSession();
				List<Classes>  cList = session.createQuery("from  Classes").list();
				for(Classes  classes: cList){
					Set<Student>  students = classes.getStudents();
					for(Student  student:  students){
						s.o.p(student.getSname());
					}
				}
				session.close();
			}
			
		}


        结论:如果需求分析翻译成sql 语句存在子查询,这时候用“子查询”效率最高。


    ------------------------------------------------------------------------------
    需求:查询某一个班级所有学生
    

		// <set   name=''  cascade=''   inverse=''   lazy=''   fetch='subselect'>  子查询
		@Test
		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();
		}

        结果:发出两条 sql 语句

        同样的代码,修改<set   name=''  cascade=''   inverse=''   lazy=''   fetch='join'>,结果只发出一条 sql 语句


    ---------------------------------------------------------------------------------------------------------------------


    结合懒加载和抓取策略:研究对象是set集合

fetch策略lazy有没有子查询什么时候发出sql语句说明
selecttrue/false 发出n+1条sql

如果lazy=true,在遍历集合时发出。

如果lazy=false    ,在一开始发出

subselect true/false存在子查询发出两条sql语句同上
joinfalse存在子查询当查询classes时,把 classes 和 student 全查询出来此时 join没用
 join true存在子查询当遍历student时发出查询studentjoin没用
 join true不是子查询在session.get(classes)时全部查询出来这时lazy没用


        注:抓取策略和懒加载只是优化策略的一种方式而已。HQL语句可以达到同样的效果,具体用哪个视情况而定。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值