Hibernate 懒加载

本文详细介绍了数据库懒加载的概念、作用、原理及其使用条件,并通过实例展示了懒加载在不同场景下的应用,包括与get和load方法的区别、类中其他类的lazy属性设置、仅部分需求立即加载的情况以及懒加载异常的解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

          1)懒加载定义:也就是在用到查询的对象的时候才会执行sql去数据库取数据,如果用不到那就不查了

          2)懒加载作用:可能能够节省查询数据库操作

          3)懒加载原理:也就是使用load方法获得的是类的代理,而不是类本身

          4)使用条件:

               1> 查询的类的lazy属性为true

               2> 查询时候使用的是load方法

               3> 查询的类不是final的(因为final就不能生成子类,所以就不能生成代理类)

          5)实例

public class Employee {
	private Long id;
	private String name;
	private Department department;
        ............
}
  <class name="cn.com.cpf.pojo.Department"   table="t_department" lazy="true">
     <id name="id" column="id">
         <generator class="native"/>
     </id>
     <property name="name"/>
     <set name="employees" inverse="false">
         <key column="departmentId"/>
         <one-to-many class="cn.com.cpf.pojo.Employee" />
     </set>
  </class>
SessionFactory factory = null;
Session session = null;
try 
{
    factory = new Configuration().configure().buildSessionFactory();
    session = factory.openSession();
    Transaction tx = session.beginTransaction();

    Department department = (Department) session.load(Department.class, 2l);

    tx.commit();
}
    结果:因为没有用到Department中任何信息,所以根本没有sql语句

             6)get和load

                  1.load方法是懒加载,在用到类中信息的时候才会去数据库中加载

                  2.get方法是立即执行sql,从数据库中去的数据

                    注意:如果类和其他类有一对多等关联关系,那么其他类是否懒加载,和本类是否懒加载无关系,可以单独设置

                    实例:

 <class name="cn.com.cpf.pojo.Department"   table="t_department" lazy="false">
   <id name="id" column="id">
      <generator class="native"/>
  </id>
  <property name="name"/>
  
  <set name="employees" inverse="false" lazy="true">
      <key column="departmentId"/>
      <one-to-many class="cn.com.cpf.pojo.Employee" />
  </set>
 </class>
factory = new Configuration().configure().buildSessionFactory();
session = factory.openSession();
Transaction tx = session.beginTransaction();

Department department = (Department) session.load(Department.class, 2l);

tx.commit();
      结果为:
Hibernate: select department0_.id as id1_3_0_, department0_.name as name2_3_0_ from t_department department0_ where department0_.id=?
     访问其他类信息:

factory = new Configuration().configure().buildSessionFactory();
session = factory.openSession();
Transaction tx = session.beginTransaction();

Department department = (Department) session.load(Department.class, 2l);
department.getEmployees().size();
     结果为:
Hibernate: select department0_.id as id1_3_0_, department0_.name as name2_3_0_ from t_department department0_ where department0_.id=?
Hibernate: select employees0_.departmentId as departme3_3_0_, employees0_.id as id1_4_0_, employees0_.id as id1_4_1_, employees0_.name as name2_4_1_, employees0_.departmentId as departme3_4_1_ from t_employee employees0_ where employees0_.departmentId=?
             7)本类中其他类的lazy属性还可以设置为extra,也就是根据访问的信息来生成不同的sql,而不是将整个类加载

 <class name="cn.com.cpf.pojo.Department"   table="t_department" lazy="false">
   <id name="id" column="id">
      <generator class="native"/>
  </id>
  <property name="name"/>
  
  <set name="employees" inverse="false" lazy="extra">
      <key column="departmentId"/>
      <one-to-many class="cn.com.cpf.pojo.Employee" />
  </set>
 </class>
factory = new Configuration().configure().buildSessionFactory();
session = factory.openSession();
Transaction tx = session.beginTransaction();

Department department = (Department) session.load(Department.class, 2l);
department.getEmployees().size();
          结果为:
Hibernate: select department0_.id as id1_3_0_, department0_.name as name2_3_0_ from t_department department0_ where department0_.id=?
Hibernate: select count(id) from t_employee where departmentId =?
         因为只是查询数量,所以使用count
                     8) 有可能只有此处需要立即加载,而其他地方都使用懒加载,也就是立即加载懒加载的对象
 <class name="cn.com.cpf.pojo.Department"   table="t_department" lazy="true">
   <id name="id" column="id">
      <generator class="native"/>
  </id>
  <property name="name"/>
  
  <set name="employees" inverse="false" lazy="true">
      <key column="departmentId"/>
      <one-to-many class="cn.com.cpf.pojo.Employee" />
  </set>
 </class>
factory = new Configuration().configure().buildSessionFactory();
session = factory.openSession();
Transaction tx = session.beginTransaction();

Department department = (Department) session.load(Department.class, 2l);
department.getEmployees();

tx.commit();
         结果为:
Hibernate: select department0_.id as id1_3_0_, department0_.name as name2_3_0_ from t_department department0_ where department0_.id=?
factory = new Configuration().configure().buildSessionFactory();
session = factory.openSession();
Transaction tx = session.beginTransaction();

Department department = (Department) session.load(Department.class, 2l);
Hibernate.initialize(department.getEmployees());
tx.commit();
         结果为:
Hibernate: select department0_.id as id1_3_0_, department0_.name as name2_3_0_ from t_department department0_ where department0_.id=?
Hibernate: select employees0_.departmentId as departme3_3_0_, employees0_.id as id1_4_0_, employees0_.id as id1_4_1_, employees0_.name as name2_4_1_, employees0_.departmentId as departme3_4_1_ from t_employee employees0_ where employees0_.departmentId=?
                 9) 懒加载异常

                     1>原因:真正获取数据时,session已经关闭

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

                     2>解决方法:

                          1.不用懒加载

                          2.在session关闭前获得数据

                          3.使用Hibernate.initialize来立即获得需要的对象 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值