hibernate关联级别策略

1.数据表和实体

实体关系:客户和联系人之间是一对多的关系
主表:cst_customer,客户的cust_id作为联系人的外键
从表:cst_linkman,一个客户可以对应多个联系人
Customer对象中有linkMens集合
LinkMan对象中有customer对象

2.关联级别策略

有两种:集合关联策略、属性关联策略

集合策略:在Customer.hbm.xml中配置
			fetch属性:决定加载策略:使用什么类型的sql语句加载集合数据
				select:默认值,单表查询加载 
				join:使用多表查询加载集合
				subselect:使用子查询加载集合
			lazy属性:决定是否延迟加载
				true:延迟加载(默认),懒加载
				false:立即加载
				extra:极其懒惰
<class name="Customer" table="cst_customer" lazy="true">
//这里lazy表时Customer对象使用时候才加载SQL语句执行
	......各种其他配置
	<set name="linkMens"  lazy="extra" fetch="subselect">
				<key column="lkm_cust_id"></key>
				<one-to-many class="LinkMan" />
	</set>
</class>
关联属性策略:在LinkMan.hbm.xml中配置
				fetch:决定加载的SQL语句
					select默认值,单表查询
					join多表查询
				lazy:决定加载时机
					false:立即加载
					proxy:加载时机由别人(Customer对象)替我决定(默认值)
<class name="LinkMan" table="cst_linkman" >
	......其他配置
	<many-to-one name="customer" column="lkm_cust_id" class="Customer" 
		fetch="select" lazy="proxy">
	</many-to-one>
</class>

3.具体使用组合

3.1集合策略
	//集合级别的关联
	//fetch:select 单表查询
	//lazy:true 使用时才加载集合数据
	@Test
	public void fun1(){
		Session session=HibernateUtils.openSession();
		Transaction tx=session.beginTransaction();
		//----------------------------------
		Customer c=session.get(Customer.class, 2l);//这个时候并没有加载LinkMan
		Set<LinkMan> linkMens= c.getLinkMens();//这时也没打印
		System.out.println(linkMens.size());//只加载count的语句
		System.out.println(linkMens);//这个时候就把LinkMan加载出来了
		//----------------------------------
		tx.commit();
		session.close();
	}
//集合级别的关联
	//fetch:select 单表查询
	//lazy:false 立即加载加载集合数据
	@Test
	public void fun2(){
		Session session=HibernateUtils.openSession();
		Transaction tx=session.beginTransaction();
		//----------------------------------
		Customer c=session.get(Customer.class, 2l);//customer和LinkMan都加载了
		Set<LinkMan> linkMens= c.getLinkMens();
		System.out.println(linkMens.size());//也是只加载了count语句
		System.out.println(linkMens);//这个时候就把LinkMan加载出来了
		//----------------------------------
		tx.commit();
		session.close();
	}
//集合级别的关联
	//fetch:select 单表
	//lazy:extra极其懒惰  其实跟懒惰没啥区别
	@Test
	public void fun3(){
		Session session=HibernateUtils.openSession();
		Transaction tx=session.beginTransaction();
		//----------------------------------
		Customer c=session.get(Customer.class, 2l);//只加载了customer
		Set<LinkMan> linkMens= c.getLinkMens();//这时也没打印
		System.out.println(linkMens.size());//只加载count的语句
		System.out.println(linkMens);//这个时候就把LinkMan加载出来了
		//----------------------------------
		tx.commit();
		session.close();
	}
//集合级别的关联
	//fetch:join 多表查询  
	//lazy:true|false|extra 失效。立即加载,一口气全查出来
	@Test
	public void fun4(){
		Session session=HibernateUtils.openSession();
		Transaction tx=session.beginTransaction();
		//----------------------------------
		Customer c=session.get(Customer.class, 2l);//全查出来了
		Set<LinkMan> linkMens= c.getLinkMens();//
		System.out.println(linkMens.size());//
		System.out.println(linkMens);
		//----------------------------------
		tx.commit();
		session.close();
	}
//集合级别的关联
	//fetch:subset 子查询  
	//lazy:true 懒加载
	@Test
	public void fun5(){
		Session session=HibernateUtils.openSession();
		Transaction tx=session.beginTransaction();
		//----------------------------------
		String hql="from Customer";
		Query query= session.createQuery(hql);
		List<Customer> list=query.list();//加载了customer
		for(Customer c:list){
			System.out.println(c);
			System.out.println(c.getLinkMens().size());//直接加载了LinkMan(使用了子查询:select from where in (子查询))
			System.out.println(c.getLinkMens());
		}
		//----------------------------------
		tx.commit();
		session.close();
	}
//集合级别的关联
	//fetch:subset 子查询  
	//lazy:false 立即加载
	@Test
	public void fun6(){
		Session session=HibernateUtils.openSession();
		Transaction tx=session.beginTransaction();
		//----------------------------------
		String hql="from Customer";
		Query query= session.createQuery(hql);
		List<Customer> list=query.list();//加载了customer、LinkMan(使用了子查询:select from where in (子)
		for(Customer c:list){
			System.out.println(c);
			System.out.println(c.getLinkMens().size());
			System.out.println(c.getLinkMens());
		}
		//----------------------------------
		tx.commit();
		session.close();
	}
	//集合级别的关联
		//fetch:subset 子查询  
		//lazy:extra 极其懒惰
		@Test
		public void fun7(){
			Session session=HibernateUtils.openSession();
			Transaction tx=session.beginTransaction();
			//----------------------------------
			String hql="from Customer";
			Query query= session.createQuery(hql);
			List<Customer> list=query.list();//加载了customer
			for(Customer c:list){
				System.out.println(c);
				System.out.println(c.getLinkMens().size());//只加载size语句
				System.out.println(c.getLinkMens());//加载LinkMan的子查询
			}
			//----------------------------------
			tx.commit();
			session.close();
		}
3.2关联属性策略
	//属性的关联级别
	//fetch:select单表查询
	//lazy:proxy 
		//Customer为true:使用时候加载
		//false时候就是立即加载,一口气加载LinkMan和Customer两个单表查询
	public void fun1(){
		Session session=HibernateUtils.openSession();
		Transaction tx=session.beginTransaction();
		//----------------------------------
		LinkMan lm=session.get(LinkMan.class,1l);//加载LinkMan语句
		Customer customer=lm.getCustomer();//没反应
		System.out.println(customer);//加载Customer语句
		//----------------------------------
		tx.commit();
		session.close();
	}
//属性的关联级别
	//fetch:join多表查询
	//lazy:失效了额,因为是多表查询,一下子就要把两个都查出来
	public void fun2(){
		Session session=HibernateUtils.openSession();
		Transaction tx=session.beginTransaction();
		//----------------------------------
		LinkMan lm=session.get(LinkMan.class,1l);//加载多表查询语句
		Customer customer=lm.getCustomer();
		System.out.println(customer);
		//----------------------------------
		tx.commit();
		session.close();
	}

4.结论

为了提高效率,fetch的选择上应该选择select(不要一下子全部查出来,会占用资源),lazy的取值应该选择true(懒加载,用到才加载(这里就用到了代理的机制来强化实体类的功能:使用实体的某个未初始化的属性的时候会自动去执行sql查询))。而这两个属性都是默认值。

5.问题

no-session问题怎么解决:
扩大session的作用范围,使用Filter拦截器进行扩展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值