hibernate学习——加载策略(优化)

Posted 小企鹅ITgo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate学习——加载策略(优化)相关的知识,希望对你有一定的参考价值。

1、 检索方式

1  立即检索:立即查询,在执行查询语句时,立即查询所有的数据。

2 延迟检索:延迟查询,在执行查询语句之后,在需要时在查询。(懒加载)

2、  检查策略

1  类级别检索:当前的类的属性获取是否需要延迟。

2  关联级别的检索:当前类 关联 另一个类是否需要延迟。

3、类级别检索

1  get:立即检索。get方法一执行,立即查询所有字段的数据。

2 load:延迟检索。默认情况,load方法执行后,如果只使用OID的值不进行查询,如果要使用其他属性值将查询 。 Customer.hbm.xml  <class  lazy="true | false">

              lazy 默认值true,表示延迟检索,如果设置false表示立即检索,相当于get方法。

package com.alice.hibernate02.lazy;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.alice.hibernate02.util.HibernateUtil;
import com.alice.hibernate02.vo.Customer;

public class Demo1 {
	// 类级别懒加载
	// load方法
	// class lazy属性
	// 默认值: true load获得时,会返回代理对象,不查询数据库.使用时才查询
	@Test
	public void test01(){
		Session session = HibernateUtil.openSession();
		Transaction tran = session.beginTransaction();
		
		Customer cus = (Customer) session.load(Customer.class, 6);
		
		System.out.println(cus.getName());
		
		tran.commit();
		session.close();
	}
	//类级别懒加载
		//load方法
		// class lazy属性
		// lazy: false  load方法执行就会发送sql语句.与get方法一致.
	@Test
	public void test02(){
		Session session = HibernateUtil.openSession();
		Transaction tran = session.beginTransaction();
		
		Customer cus = (Customer) session.load(Customer.class, 6);
		
		System.out.println(cus.getName());
		
		tran.commit();
		session.close();
	}
}

4、  关联级别检索

在查询有关联关系的数据时,加载一方的数据是否需要将另一方立即查询出.
默认: 与我关联的数据,在使用时才会加载.

集合(一对多):
set
lazy: 是否对set数据使用懒加载
        true:(默认值) 对集合使用才加载
        false: 集合将会被立即加载
        extra: 极其懒惰,如果使用集合时,之调用size方法查询数量, Hibernate会发送count语句,只查询数量.不加载集合内数据.
fetch : 决定加载集合使用的sql语句种类
         select: (默认值) 普通select查询
         join: 表链接语句查询集合数据
         subselect: 使用子查询 一次加载多个Customer的订单数据

fetch lazy 结论
select true 默认值, 会在使用集合时加载,普通select语句
select false 立刻使用select语句加载集合数据
select extra 会在使用集合时加载,普通select语句,如果只是获得集合的长度,会发送Count语句查询长度
join true 查询集合时使用表链接查询,会立刻加载集合数据
join false 查询集合时使用表链接查询,会立刻加载集合数据
jojn extra 查询集合时使用表链接查询,会立刻加载集合数据
subselect true 会在使用集合时加载,子查询语句
subselect false 会在查询用户时,立即使用子查询加载客户的订单数据
subselect extra 会在使用集合时加载,子查询语句,如果只是获得集合的长度,会发送Count语句查询长度.

代码测试:

package com.alice.hibernate02.lazy;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;


import com.alice.hibernate02.util.HibernateUtil;
import com.alice.hibernate02.vo.Customer;
import com.alice.hibernate02.vo.Order;

public class Demo02 {
	// 关联级别懒加载
	// 默认: 与我关联的数据,在使用时才会加载.
	@Test
	public void test01() {
		Session session = HibernateUtil.openSession();
		Transaction tran = session.beginTransaction();

		Customer cus = (Customer) session.get(Customer.class, 6);

		for (Order o : cus.getOrders()) {
			System.out.println(o.getName());
		}

		tran.commit();
		session.close();
	}
	//关联级别懒加载
		//lazy: false
	@Test
	public void test02() {
		Session session = HibernateUtil.openSession();
		Transaction tran = session.beginTransaction();

		Customer cus = (Customer) session.get(Customer.class, 6);

		for (Order o : cus.getOrders()) {
			System.out.println(o.getName());
		}

		tran.commit();
		session.close();
	}
	
	//关联级别懒加载
		//lazy:false
		//fetch:subselect
	@Test
	public void test03() {
		Session session = HibernateUtil.openSession();
		Transaction tran = session.beginTransaction();

		Customer cus = (Customer) session.get(Customer.class, 6);

		for (Order o : cus.getOrders()) {
			System.out.println(o.getName());
		}

		tran.commit();
		session.close();
	}
	//关联级别懒加载
		//lazy:true/false
		//fetch:subselect
	@Test
	public void test04() {
		Session session = HibernateUtil.openSession();
		Transaction tran = session.beginTransaction();

		List<Customer> list = session.createQuery("from Customer").list();

		for (Customer c: list) {
			System.out.println(c.getName()+"下单数量"+c.getOrders().size());
		}

		tran.commit();
		session.close();
	}
	
	//关联级别懒加载
		//lazy:extra
		//fetch:select
	@Test
	public void test05() {
		Session session = HibernateUtil.openSession();
		Transaction tran = session.beginTransaction();

		Customer cus = (Customer) session.get(Customer.class, 6);
		//查询Customer下订单 数量
		System.out.println(cus.getOrders().size());
        
		//真正使用订单中的数据
		for (Order o: cus.getOrders()) {
			System.out.println(o.getName());
		}

		tran.commit();
		session.close();
	}
	//关联级别懒加载
		//lazy:extra
		//fetch:subselect
	@Test
	public void test06() {
		Session session = HibernateUtil.openSession();
		Transaction tran = session.beginTransaction();

		@SuppressWarnings("unchecked")
		List<Customer> list = session.createQuery("from Customer").list();
		for(Customer c:list){
			System.out.println(c.getName()+"下单数量:"+c.getOrders().size());
		}
        for(Customer c:list){
        	for(Order o :c.getOrders()){
        		System.out.println(c.getName()+"下单名称:"+o.getName());
        	}
        }
		tran.commit();
		session.close();
	}
	
}

  多对一:

<many-to-one>

lazy
     false:  加载订单时,会立即加载客户
     proxy:看客户对象的类加载策略来决定
no-proxy : 不做研究.
fetch
     select : (默认值)使用普通select加载

     join : 使用表链接加载数据

 

 

fetch lazy 结果
select false 加载订单时,立即加载客户数据.普通select语句加载客户.
select proxy

类加载策略为:lazy=false 同上
lazy=true 加载订单时,先不加载客户数据.使用客户数据时才加载

join false 使用表链接查询订单以及对应客户信息.lazy属性无效
join proxy 使用表链接查询订单以及对应客户信息.lazy属性无效

 

package com.alice.hibernate02.lazy;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.alice.hibernate02.util.HibernateUtil;
import com.alice.hibernate02.vo.Order;

//多对一检索策略
public class Demo03 {
    // 多对一检索策略
    @Test
    // fetch: select
    // lazy: false
    public void test01() {
        Session session = HibernateUtil.openSession();
        Transaction tran = session.beginTransaction();

        Order o = (Order) session.get(Order.class, 8);
        System.out.println(o.getCustomer().getName());

        tran.commit();
        session.close();
    }

    // fetch: select
    // lazy: proxy
    // Customer lazy:false
    @Test
    public void test02() {
        Session session = HibernateUtil.openSession();
        Transaction tran = session.beginTransaction();

        Order o = (Order) session.get(Order.class, 8);
        System.out.println(o.getCustomer().getName());

        tran.commit();
        session.close();
    }

    // fetch: select
    // lazy: proxy
    // Customer lazy:true
    @Test
    public void test03() {
        Session session = HibernateUtil.openSession();
        Transaction tran = session.beginTransaction();

        Order o = (Order) session.get(Order.class, 8);
        System.out.println(o.getCustomer().getName());

        tran.commit();
        session.close();
    }

    // fetch: join
    // lazy: proxy|false
    @Test
    public void test04() {
        Session session = HibernateUtil.openSession();
        Transaction tran = session.beginTransaction();

        Order o = (Order) session.get(Order.class, 8);
        System.out.println(o.getCustomer().getName());

        tran.commit();
        session.close();
    }
}

5、批量加载

set
batch-size: 决定一次加载几个对象的集合数据. in 条件加载多个用户的订单.

package com.alice.hibernate02.lazy;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.alice.hibernate02.util.HibernateUtil;
import com.alice.hibernate02.vo.Customer;
import com.alice.hibernate02.vo.Order;
//批量策略
public class Demo04 {

    @Test
    //查询所有客户
    //遍历客户,打印客户下的订单信息
    public void test() {
        Session session = HibernateUtil.openSession();
        Transaction tran = session.beginTransaction();

        List<Customer> list = session.createQuery("from Customer").list();
        
        for(Customer c:list){
            System.out.println(c.getOrders().size());
        }

        tran.commit();
        session.close();
    }
}

 

Customer  Get(int id)

       Return Session.load(Customer.class,id);

  1. layz=false
  2. 在Service层获得在页面要上要用到的属性=> 在Service层中确保数据已经

以上是关于hibernate学习——加载策略(优化)的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate框架学习——查询优化

Hibernate的抓取策略(优化)

Hibernate优化---抓取策略

Hibernate(十四)抓取策略

Hibernate的检索策略

Hibernate学习笔记 — 懒加载与抓取策略