JavaWeb 笔记之 Hibernate 检索策略

类级别的检索策略

  • 类级别可选的检索策略包括立即检索和延迟检索, 默认为延迟检索
  • 延迟检索仅对 Session 的 load()方法有效,(无论 <class> 元素的 lazy 属性是 true 还是 false, Session 的 get() 方法及 Query 的 list() 方法在类级别总是使用立即检索策略)
  • 配置方式: 类级别的检索策略可以通过 <class> 元素的 lazy 属性进行设置
  • 示例
    //*.hbm.xml中<class>元素设置 lazy 属性
    <hibernate-mapping package="com.atguigu.hibernate.strategy">
    
    <class name="Customer" table="CUSTOMERS" lazy="true">
    
        <id name="customerId" type="java.lang.Integer">
            <column name="CUSTOMER_ID" />
            <generator class="native" />
        </id>
        ...
        
    @Test
	public void testClassLevelStrategy(){
		Customer customer = (Customer) session.load(Customer.class, 1);
		System.out.println(customer.getClass()); 
		
		System.out.println(customer.getCustomerId()); 
		System.out.println(customer.getCustomerName()); 
	}

一对多和多对多的检索策略

  • 配置方式:用 <set> 元素来配置一对多关联及多对多关联关系. <set> 元素有 lazy 、 fetch、batch-size 属性
  • lazy 取值为 true、 false 或 extra,默认为 true(extra:采用增强的延迟检索策略)
  • fetch 取值为 select、subselect 或 join,默认取值 select(取值为 select 或 subselect :决定初始化查询的语句形式;取值为 join :采用迫切左外链接的形式查询语句,忽略 lazy 属性)
  • batch-size 属性 设定批量检索的数量,批量检索能减少 SELECT 语句的数目, 提高延迟检索或立即检索的运行性能(默认值为1)
  • 示例 1:
    //*.hbm.xml中配置
    <hibernate-mapping package="com.atguigu.hibernate.strategy">
    
    <class name="Customer" table="CUSTOMERS">
    
        <id name="customerId" type="java.lang.Integer">
            <column name="CUSTOMER_ID" />
            <generator class="native" />
        </id>
    
        <property name="customerName" type="java.lang.String">
            <column name="CUSTOMER_NAME" />
        </property>
        
        //set中配置 lazy、fetch、batch-size
        <set name="orders" table="ORDERS" 
        	inverse="true" lazy="true"
        	batch-size="2" fetch="subselect">
        	<key column="CUSTOMER_ID"></key>
        	<one-to-many class="Order"/>
        </set>
        
    </class>
    
</hibernate-mapping>

    //---------------set 的 lazy 属性------------------
	//1. 1-n 或 n-n 的集合属性默认使用懒加载检索策略.
	//2. 可以通过设置 set 的 lazy 属性来修改默认的检索策略. 默认为 true
	//并不建议设置为  false. 
	//3. lazy 还可以设置为 extra. 增强的延迟检索. 该取值会尽可能的延迟集合初始化的时机!
	//4. lazy 属性值为 true 时,应用程序第一次访问集合属性: iterator(), size(), isEmpty(), contains() 等方法以及调用 Hibernate.initialize() 方法时 会初始化集合代理类实例 
	//5. lazy 属性值为 extra 时,当程序第一次访问 orders 属性的 iterator() 方法时, 会导致 orders 集合代理类实例的初始化;当程序第一次访问 order 属性的 size(), contains() 和 isEmpty() 方法时, Hibernate 不会初始化 orders 集合类的实例, 仅通过特定的 select 语句查询必要的信息, 不会检索所有的 Order 对象


	@Test
	public void testOne2ManyLevelStrategy(){
		Customer customer = (Customer) session.get(Customer.class, 1);
		System.out.println(customer.getCustomerName()); 
		
		System.out.println(customer.getOrders().size());
		Order order = new Order();
		order.setOrderId(1);
		System.out.println(customer.getOrders().contains(order));
		
		Hibernate.initialize(customer.getOrders()); 
		
	}
  • 示例 2:
    @Test
	public void testSetFetch(){
		List<Customer> customers = session.createQuery("FROM Customer").list();
		
		System.out.println(customers.size()); 
		
		for(Customer customer: customers){
			if(customer.getOrders() != null)
				System.out.println(customer.getOrders().size());
		}
		
		//set 集合的 fetch 属性: 确定初始化 orders 集合的方式. 
		//1. 默认值为 select. 通过正常的方式来初始化 set 元素
		//2. 可以取值为 subselect. 通过子查询的方式来初始化所有的 set 集合. 子查询
		//作为 where 子句的 in 的条件出现, 子查询查询所有 1 的一端的 ID. 此时 lazy 有效.
		//但 batch-size 失效. 
		//3. 若取值为 join. 则
		//3.1 在加载 1 的一端的对象时, 使用迫切左外连接(使用左外链接进行查询, 且把集合属性进行初始化)的方式检索 n 的一端的集合属性
		//3.2 忽略 lazy 属性.
		//3.3 HQL 查询忽略 fetch=join 的取值,依旧采用 延迟加载策略
	}

多对一和一对一关联的检索策略

  • 配置方式:和 <set> 一样, <many-to-one> 元素也有一个 lazy 属性和 fetch 属性以及 batch-size 属性.
  • lazy 属性取值为 proxy(延迟检索)、no-proxy(无代理延迟检索),false(立即检索);默认取值 proxy;
  • fetch 属性取值:select、join(迫切左外连接检索方式),默认取值为 select;
  • 示例:
    // *.hbm.xml中 配置
    <hibernate-mapping package="com.atguigu.hibernate.strategy">

    <class name="Order" table="ORDERS">

        <id name="orderId" type="java.lang.Integer">
            <column name="ORDER_ID" />
            <generator class="native" />
        </id>
        
        <property name="orderName" type="java.lang.String">
            <column name="ORDER_NAME" />
        </property>
        
        //<many-to-one>中配置lazy、fetch
		<many-to-one 
			name="customer" class="Customer" 
			column="CUSTOMER_ID"
			lazy="false"
			fetch="join"></many-to-one>

    </class>
    </hibernate-mapping>

    @Test
	public void testMany2OneStrategy(){
//		Order order = (Order) session.get(Order.class, 1);
//		System.out.println(order.getCustomer().getCustomerName()); 
		
		List<Order> orders = session.createQuery("FROM Order o").list();
		for(Order order: orders){
			if(order.getCustomer() != null){
				System.out.println(order.getCustomer().getCustomerName()); 
			}
		}
		
		//1. lazy 取值为 proxy 和 false 分别代表对应对应的属性采用延迟检索和立即检索
		//2. fetch 取值为 join, 表示使用迫切左外连接的方式初始化 n 关联的 1 的一端的属性
		//忽略 lazy 属性. 
		//3. batch-size, 该属性需要设置在 1 那一端的 class 元素中: 
		//<class name="Customer" table="CUSTOMERS" lazy="true" batch-size="5">
		//作用: 一次初始化 1 的这一段代理对象的个数. 
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值