文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

(11)Hibernate懒加载

2024-04-02 19:55

关注


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();
	}
}








阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯