Hibernate fetch 抓取策略

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate fetch 抓取策略相关的知识,希望对你有一定的参考价值。

上一篇文章(Hibernate的延迟加载 ,懒加载,lazy)说到Hibernate的延迟加载跟fetch的配置还有一定关系,下面就来讨论下fetch的用法。

抓取策略(fetch)是指当我们去查询一个对象里面所关联的其他对象时,按照哪种方法去抓取关联对象。

fetch策略一共有四种:select、subselect、join、batch,下面我们一一介绍。我们还是用上面介绍延迟加载的相关表和实体类。

Company表:

技术分享

Employee表(employee_company_id为外键)

技术分享

Company实体类:

import java.util.Set;

public class Company {
    private int companyId;
    private String companyName;
    private Set<Employee> companyEmployees;
    public int getCompanyId() {
        return companyId;
    }
    public void setCompanyId(int companyId) {
        this.companyId = companyId;
    }
    public String getCompanyName() {
        return companyName;
    }
    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }
    public Set<Employee> getCompanyEmployees() {
        return companyEmployees;
    }
    public void setCompanyEmployees(Set<Employee> companyEmployees) {
        this.companyEmployees = companyEmployees;
    }
}

Employee实体类:

public class Employee {
    private int employeeId;
    private String employeeName;
    private Company employeeCompany;
    public int getEmployeeId() {
        return employeeId;
    }
    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }
    public String getEmployeeName() {
        return employeeName;
    }
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }
    public Company getEmployeeCompany() {
        return employeeCompany;
    }
    public void setEmployeeCompany(Company employeeCompany) {
        this.employeeCompany = employeeCompany;
    }
}

Company hbm配置:

<hibernate-mapping>
    <class name="com.jaeger.hibernatetest.day7.lazy.Company" table="company">
        <id name="companyId" column="company_id">
            <generator class="native"></generator>
     </id>

     <property name="companyName" column="company_name"/>
      <set name="companyEmployees" cascade="all">
           <key column="employee_company_id"></key>
        <one-to-many class="com.jaeger.hibernatetest.day7.lazy.Employee"/>
      </set>
   </class>
</hibernate-mapping>

Employee hbm配置:

<hibernate-mapping>
    <class name="com.jaeger.hibernatetest.day7.lazy.Employee" table="employee">
       <id name="employeeId" column="employee_id">
         <generator class="native"></generator>
     </id>

        <property name="employeeName" column="employee_name"/>
        <many-to-one name="employeeCompany" class="com.jaeger.hibernatetest.day7.lazy.Company" 
            foreign-key="fk_employee_company" column="employee_company_id" cascade="save-update">
        </many-to-one>
   </class>
</hibernate-mapping>

fetch属性用在<many-to-one><one-to-many>等关联标签里,我们就用<many-to-one>来介绍,从数据库取数据就用get()方法,让外层对象不用延迟加载。


1. select
查询关联对象时,是拿外层对象的外键,向数据库再发送select语句去抓取关联对象。

修改上面Employee hbm的配置:

<many-to-one name="employeeCompany" class="com.jaeger.hibernatetest.day7.lazy.Company" 
            foreign-key="fk_employee_company" column="employee_company_id" cascade="save-update" fetch="select">
</many-to-one>

在<many-to-one>标签中我们添加了fetch="select",下面是测试代码:

Employee employee = (Employee)session.get(Employee.class, 1); //A
System.out.println(employee.getEmployeeName());
Company company = employee.getEmployeeCompany(); //B
System.out.println(company.getCompanyName()); //C

A:此处会生成sql语句去查询employee的信息。

select
     employee0_.employee_id as employee1_1_0_,
     employee0_.employee_name as employee2_1_0_,
     employee0_.employee_company_id as employee3_1_0_ 
  from
     employee employee0_ 
 where
     employee0_.employee_id=?

B:此处不会马上去取company的信息,因为<many-to-one>里面默认是lazy="proxy"支持懒加载的。

C:此处会根据employee的外键去查找company的信息,用的就是select fetch策略。

select
     company0_.company_id as company_1_0_0_,
     company0_.company_name as company_2_0_0_ 
  from
     company company0_ 
 where
     company0_.company_id=?

注意:<many-to-one><one-to-many>等关联标签默认是fetch="select"的,所以我们不配置也会采用多条select语句的方式去查询关联对象。

本文出自 “銅鑼衛門” 博客,请务必保留此出处http://jaeger.blog.51cto.com/11064196/1748526

以上是关于Hibernate fetch 抓取策略的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate中fetch和lazy介绍

Hibernate中fetch和lazy介绍

Hibernate之抓取策略

Hibernate的抓取策略

八 Hibernate延迟加载&抓取策略(优化)

Hibernate(十四)抓取策略