温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

(11)Hibernate懒加载

发布时间:2020-07-02 23:03:50 来源:网络 阅读:529 作者:lsieun 栏目:数据库


1、get、load方法区别?

get: 及时加载,只要调用get方法立刻向数据库查询

load:默认使用懒加载,当用到数据的时候才向数据库查询。

2、懒加载(lazy)


2.1、概念

概念:当用到数据的时候才向数据库查询,这就是hibernate的懒加载特性。

目的:提升程序执行效率!

2.2、lazy属性的值

在Hibernate中,懒加载对应lazy属性的值。

lazy属性的值
序号含义
1true使用懒加载
2false关闭懒加载
3extra

在集合属性(配置当中使用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();	} }








向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI