(11)Hibernate懒加载
1、get、load方法区别?
get: 及时加载,只要调用get方法立刻向数据库查询
load:默认使用懒加载,当用到数据的时候才向数据库查询。
2、懒加载(lazy)
2.1、概念
概念:当用到数据的时候才向数据库查询,这就是hibernate的懒加载特性。
目的:提升程序执行效率!
2.2、lazy属性的值
在Hibernate中,懒加载对应lazy属性的值。
序号 | 值 | 含义 |
---|---|---|
1 | true | 使用懒加载 |
2 | false | 关闭懒加载 |
3 | extra | 在集合属性(配置当中使用set标签)懒加载的时候提升效率 在真正使用数据的时候才向数据库发送查询的sql; 如果调用集合的size()/isEmpty()方法,只是统计,不真正查询数据! |
2.3、懒加载异常
(1)Session关闭后,不能使用懒加载数据!
(2)如果session关闭后,使用懒加载数据报错:org.hibernate.LazyInitializationException: could not initialize proxy - no Session
(3)如何解决session关闭后不能使用懒加载数据的问题?
方式1: 先使用一下数据
dept.getDeptName();
方式2:强迫代理对象初始化
Hibernate.initialize(dept);
方式3:关闭懒加载
在.hbm.xml配置文件中设置lazy=false;
方式4: 在使用数据之后,再关闭session!
方式1和方式4的区别是:方式1是说,如果想在关闭Session后,仍然想用懒加载的数据,可以先使用一下需要懒加载的数据,这样就会提前加载那些数据;方式4是说,既然懒加载的数据在Session关闭后不能再进行访问,那么它就想办法延迟Session的关闭。
3、示例代码
Department.java
package com.rk.hibernate.j_lazy;
import java.util.Set;
public class Department
{
private int deptId;
private String deptName;
private Set<Employee> emps;
public int getDeptId()
{
return deptId;
}
public void setDeptId(int deptId)
{
this.deptId = deptId;
}
public String getDeptName()
{
return deptName;
}
public void setDeptName(String deptName)
{
this.deptName = deptName;
}
public Set<Employee> getEmps()
{
return emps;
}
public void setEmps(Set<Employee> emps)
{
this.emps = emps;
}
@Override
public String toString()
{
return "Deparment [deptId=" + deptId + ", deptName=" + deptName + "]";
}
}
Department.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.rk.hibernate.j_lazy" auto-import="true">
<!-- class标签内可以设置lazy属性 -->
<class name="Department" table="T_Department" lazy="false">
<id name="deptId" column="id">
<generator class="native"></generator>
</id>
<property name="deptName" column="name"></property>
<!--
集合属性,默认使用懒加载
lazy
true 懒加载
extra 懒加载(智能)
false 关闭懒加载
-->
<set name="emps" table="T_Employee" lazy="extra">
<key column="deptId"></key>
<one-to-many class="Employee"/>
</set>
</class>
</hibernate-mapping>
Employee.java
package com.rk.hibernate.j_lazy;
public class Employee
{
private int empId;
private String empName;
private int salary;
private Department dept;
public int getEmpId()
{
return empId;
}
public void setEmpId(int empId)
{
this.empId = empId;
}
public String getEmpName()
{
return empName;
}
public void setEmpName(String empName)
{
this.empName = empName;
}
public int getSalary()
{
return salary;
}
public void setSalary(int salary)
{
this.salary = salary;
}
public Department getDept()
{
return dept;
}
public void setDept(Department dept)
{
this.dept = dept;
}
@Override
public String toString()
{
return "Employee [empId=" + empId + ", empName=" + empName + ", salary=" + salary + "]";
}
}
Employee.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.rk.hibernate.j_lazy" auto-import="true">
<class name="Employee" table="T_Employee">
<id name="empId" column="id">
<generator class="native"></generator>
</id>
<property name="empName" column="name"></property>
<property name="salary" column="salary"></property>
<many-to-one name="dept" column="deptId" class="Department"></many-to-one>
</class>
</hibernate-mapping>
App.java
package com.rk.hibernate.j_lazy;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class App
{
private static SessionFactory sf;
static
{
sf = new Configuration()
.configure()
.addClass(Department.class)
.addClass(Employee.class)
.buildSessionFactory();
}
//1. 主键查询,get和load的区别
//这里是对JavaBean类的懒加载
@Test
public void testClassGetLoad()
{
Session session = sf.openSession();
session.beginTransaction();
// get: 及时查询
// Department dept = (Department)session.get(Department.class, 1);
// System.out.println(dept.getDeptName());
// System.out.println(dept.getEmps());
// load,默认懒加载, 及在使用数据的时候,才向数据库发送查询的sql语句!
Department dept = (Department)session.load(Department.class, 1);
// 方式1: 先使用一下数据
// dept.getDeptName();
// 方式2:强迫代理对象初始化
// Hibernate.initialize(dept);
// 方式3:关闭懒加载
// 配置文件中将lazy设置为false。<class name="Department" table="T_Department" lazy="false">
session.getTransaction().commit();
session.close();
// session关闭后,是否能够使用
System.out.println(dept.getDeptName());
}
//2.这里是对属性(外键关联)的懒加载
@Test
public void testProperty()
{
Session session = sf.openSession();
session.beginTransaction();
Department dept = (Department)session.get(Department.class, 1);
System.out.println(dept.getDeptName());
System.out.println("--------------------------");
System.out.println(dept.getEmps().size());
System.out.println(dept.getEmps().isEmpty());
System.out.println(dept.getEmps());
session.getTransaction().commit();
session.close();
}
}
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341