Java笔记之hibernate(十):关系延迟加载
0.说在前面
1.概念
关系延迟加载是用在one-to-many、many-to-many、many-to-one关系配置上的
hibernate3之后默认开启关系延迟加载,当前项目就是使用的hibernate3
2.新建LazyTest类
package com.hibernate.demo.test; import java.util.Set; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; import com.hibernate.demo.bean.Department; import com.hibernate.demo.bean.Employee; public class LazyTest { public static void main(String[] args) { //加载配置文件,创建会话工厂对象 SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); //创建会话对象 Session session = sessionFactory.openSession(); System.out.println("log1"); //根据id获取Department对象 Department department = (Department) session.get(Department.class, 1); System.out.println("log2"); //获取对象中的Employee集合 Set<Employee> employees = department.getEmployees(); //遍历集合 for (Employee employee : employees) { System.out.println(employee.getEmpName()); } System.out.println("log3"); //关闭会话对象 session.close(); //关闭会话工厂对象 sessionFactory.close(); } }
说明:Department类Employee类是一对多的关系,此时Department.hbm.xml文件中两者的one-to-many配置上并没有添加延迟加载的配置
3.运行LazyTest类
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. log1 Hibernate: select department0_.dept_id as dept1_2_0_, department0_.dept_name as dept2_2_0_ from t_department department0_ where department0_.dept_id=? log2 Hibernate: select employees0_.dept_id as dept3_2_1_, employees0_.emp_id as emp1_1_, employees0_.emp_id as emp1_0_0_, employees0_.emp_name as emp2_0_0_, employees0_.dept_id as dept3_0_0_ from t_employee employees0_ where employees0_.dept_id=? 李四 王五 log3
4.总结
从3中打印的信息,可以看出查询Department时并没有发送SQL去查询Employee信息,而是在获取Employee的Set集合信息时才发送SQL去数据库查询,可见默认是开启延时加载的.
5.修改Department.hbm.xml文件,关闭Department与Employee之间的one-to-many延时加载
<?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.hibernate.demo.bean"> <!-- 映射Department类与表t_department --> <class name="Department" table="t_department"> <id name="deptId" column="dept_id"> <!-- 声明主键生成策略为自增 --> <generator class="native"></generator> </id> <property name="deptName" column="dept_name"></property> <!-- 用于设置一对多的关系 --> <set name="employees" lazy="false"> <!-- 声明多的一方对应的表中的外键列名,not-null设置可以为空 --> <key column="dept_id" not-null="false"></key> <!-- 声明一对多的关系,class设置多的一方对应的类名 --> <one-to-many class="Employee"/> </set> </class> </hibernate-mapping>
6.再次运行LazyTest类
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. log1 Hibernate: select department0_.dept_id as dept1_2_0_, department0_.dept_name as dept2_2_0_ from t_department department0_ where department0_.dept_id=? Hibernate: select employees0_.dept_id as dept3_2_1_, employees0_.emp_id as emp1_1_, employees0_.emp_id as emp1_0_0_, employees0_.emp_name as emp2_0_0_, employees0_.dept_id as dept3_0_0_ from t_employee employees0_ where employees0_.dept_id=? log2 李四 王五 log3
7.总结
从6中打印的信息可以看出,延迟加载被关闭后,在查询Department信息的时候也会发送SQL语句去查询Employee信息
8.关于many-to-one的延迟加载问题,新建LazyTest2类
package com.hibernate.demo.test; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.classic.Session; import com.hibernate.demo.bean.Department; import com.hibernate.demo.bean.Employee; public class LazyTest2 { public static void main(String[] args) { //加载配置文件,创建会话工厂对象 SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); //创建会话对象 Session session=sessionFactory.openSession(); System.out.println("log1"); //根据id获取Employee对象 Employee employee = (Employee) session.get(Employee.class, 2); System.out.println("log2"); //获取Department对象 Department department = employee.getDepartment(); System.out.println(department.getDeptName()); System.out.println("log3"); //关闭会话对象 session.close(); //关闭会话工厂对象 sessionFactory.close(); } }
9.运行LazyTest2类
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. log1 Hibernate: select employee0_.emp_id as emp1_0_0_, employee0_.emp_name as emp2_0_0_, employee0_.dept_id as dept3_0_0_ from t_employee employee0_ where employee0_.emp_id=? log2 Hibernate: select department0_.dept_id as dept1_2_0_, department0_.dept_name as dept2_2_0_ from t_department department0_ where department0_.dept_id=? Hibernate: select employees0_.dept_id as dept3_2_1_, employees0_.emp_id as emp1_1_, employees0_.emp_id as emp1_0_0_, employees0_.emp_name as emp2_0_0_, employees0_.dept_id as dept3_0_0_ from t_employee employees0_ where employees0_.dept_id=? 行政部 log3
说明:Employee.hbm.xml文件中关于Employee与Department的多对一配置中并没有手动设置延迟加载,而是使用的默认的延迟加载配置.
10.总结
从9中打印的信息可以看出,many-to-one是默认开启延迟加载的,不需要手动开启,如果手动开启反倒会报异常:Attribute "lazy" with value "true" must have a value from the list "false proxy no-proxy ".
11.将Employee.hbm.xml文件中与Department的many-to-one配置的延迟加载关闭,也就是设置lazy="false",再次运行LazyTest2类
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. log1 Hibernate: select employee0_.emp_id as emp1_0_0_, employee0_.emp_name as emp2_0_0_, employee0_.dept_id as dept3_0_0_ from t_employee employee0_ where employee0_.emp_id=? Hibernate: select department0_.dept_id as dept1_2_0_, department0_.dept_name as dept2_2_0_ from t_department department0_ where department0_.dept_id=? Hibernate: select employees0_.dept_id as dept3_2_1_, employees0_.emp_id as emp1_1_, employees0_.emp_id as emp1_0_0_, employees0_.emp_name as emp2_0_0_, employees0_.dept_id as dept3_0_0_ from t_employee employees0_ where employees0_.dept_id=? log2 行政部 log3
12.总结
从11中打印的信息可以看出,关闭了延迟加载,在查询Employee信息的时候也会发送SQL语句查询Department信息
13.综述
从上述各种情况的结果来看:
(1).hibernate3之后是默认开启延迟加载的;
(2).one-to-many、many-to-many、many-to-one虽然都是默认开启延迟加载的,但是前两者还可以手动开启延迟加载,最后一个就不可以手动开启延迟加载;
(3).many-to-many没有做示例,但也确实是默认开启延迟加载的;