Hibernate 延迟加载

3 篇文章 0 订阅
2 篇文章 1 订阅

一、延迟加载(惰性加载、懒加载)

        使⽤延迟加载可以提⾼程序的运⾏效率,Java 程序与数据库交互的频次越低,程序运⾏的效率就越⾼, 所以我们应该尽量减少 Java 程序与数据库的交互次数,Hibernate 延迟加载就很好的做到了这⼀点。

        客户和订单,当我们查询客户对象时,因为有级联设置,所以会将对应的订单信息⼀并查询出来,这样 就需要发送两条 SQL 语句,分别查询客户信息和订单信息。

        延迟加载的思路是:当我们查询客户的时候,如果没有访问订单数据,只发送⼀条 SQL 语句查询客户信 息,如果需要访问订单数据,则发送两条 SQLL。 延迟加载可以看作是⼀种优化机制,根据具体的需求,⾃动选择要执⾏的 SQL 语句数量。

1、一对多 

1、查询 Customer,对 orders 进⾏延迟加载设置,在 customer.hbm.xml 进⾏设置,延迟加载默认开启。 

<!-- lazy=true开启延迟加载(默认开启) -->
<set name="orders" table="orders" lazy="true">
 <key column="cid"></key>
 <one-to-many class="com.southwind.entity.Orders"></one-to-many>
</set>

2、查询 Customer

import com.southwind.entity.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test4 {
 public static void main(String[] args) {
 //创建 Configuration
 Configuration configuration = new
Configuration().configure("hibernate.xml");
 //获取 SessionFactory
 SessionFactory sessionFactory = configuration.buildSessionFactory();
 //获取 Session
 Session session = sessionFactory.openSession();
 Customer customer = session.get(Customer.class,15);
 System.out.println(customer);
 session.close();
 }
}

这里没有使用到 Customer 的 orders 属性 所以只查询出Customer的数据

import com.southwind.entity.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test4 {
 public static void main(String[] args) {
 //创建 Configuration
 Configuration configuration = new
Configuration().configure("hibernate.xml");
 //获取 SessionFactory
 SessionFactory sessionFactory = configuration.buildSessionFactory();
 //获取 Session
 Session session = sessionFactory.openSession();
 Customer customer = session.get(Customer.class,15);
 //获取订单列表
 System.out.println(customer.getOrders()); 
 session.close();
 }
}

        这里我们获取用户的订单列表,用到了订单数据,所以额外执行了一条sql语句查询了订单列表数据。 

lazy 除了可以设置 true 和 false 之外,还可以设置 extra,extra 是⽐ true 更加懒惰的⼀种加载⽅式, 或者说是更加智能的⼀种加载⽅式,通过例⼦看区别:

查询 Customer 对象,打印该对象对应的 orders 集合的⻓度

import com.southwind.entity.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test4 {
 public static void main(String[] args) {
 //创建 Configuration
 Configuration configuration = new
Configuration().configure("hibernate.xml");
 //获取 SessionFactory
 SessionFactory sessionFactory = configuration.buildSessionFactory();
 //获取 Session
 Session session = sessionFactory.openSession();
 Customer customer = session.get(Customer.class,15);
 System.out.println(customer.getOrders().size());
 session.close();
 }
}

也可以通过 Orders 来设置 Customer 的延迟加载,orders.hbm.xml 中进⾏设置。

<many-to-one name="customer" class="com.southwind.entity.Customer"
column="cid" lazy="proxy"></many-to-one>
package com.southwind.test;
import com.southwind.entity.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test5 {
 public static void main(String[] args) {
 //创建 Configuration
 Configuration configuration = new
Configuration().configure("hibernate.xml");
 //获取 SessionFactory
 SessionFactory sessionFactory = configuration.buildSessionFactory();
 //获取 Session
 Session session = sessionFactory.openSession();
 Orders orders = session.get(Orders.class,26);
 //只打印订单信息
 System.out.println(orders); 
 session.close();
 }
}

没有获取订单信息,所以只执行一条sql语句。 

import com.southwind.entity.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test5 {
 public static void main(String[] args) {
 //创建 Configuration
 Configuration configuration = new
Configuration().configure("hibernate.xml");
 //获取 SessionFactory
 SessionFactory sessionFactory = configuration.buildSessionFactory();
 //获取 Session
 Session session = sessionFactory.openSession();
 Orders orders = session.get(Orders.class,26);
 //获取客户信息
 System.out.println(orders.getCustomer());
 session.close();
 }
}

这里通过订单获取了客户信息,所以额外执行了一条sql来获取客户信息。 

  • proxy:当调⽤⽅法需要访问 customer 的成员变量时,发送 SQL 语句查询 Customer,否则不查 询。
  • no-proxy:⽆论调⽤⽅法是否需要访问 customer 的成员变量,都会发送 SQL 语句查询 Customer。

2、多对多 

查询 Course,加载对应的 Account,默认延迟加载开启。 

import com.southwind.entity.Course;
import com.southwind.entity.Orders;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class Test6 {
 public static void main(String[] args) {
 //创建 Configuration
 Configuration configuration = new
Configuration().configure("hibernate.xml");
 //获取 SessionFactory
 SessionFactory sessionFactory = configuration.buildSessionFactory();
 //获取 Session
 Session session = sessionFactory.openSession();
 Course course = session.get(Course.class,5);
 System.out.println(course);
 session.close();
 }
}

public class Test6 {
 public static void main(String[] args) {
 //创建 Configuration
 Configuration configuration = new
Configuration().configure("hibernate.xml");
 //获取 SessionFactory
 SessionFactory sessionFactory = configuration.buildSessionFactory();
 //获取 Session
 Session session = sessionFactory.openSession();
 Course course = session.get(Course.class,5);
 System.out.println(course.getAccounts());
 session.close();
 }
}

关闭延迟加载 lazy=false

<!-- 关闭延迟加载 lazy=false -->
<set name="accounts" table="account_course" lazy="false">
 <key column="cid"></key>
 <many-to-many class="com.southwind.entity.Account" column="aid"></many-tomany>
</set>
public class Test6 {
 public static void main(String[] args) {
 //创建 Configuration
 Configuration configuration = new
Configuration().configure("hibernate.xml");
 //获取 SessionFactory
 SessionFactory sessionFactory = configuration.buildSessionFactory();
 //获取 Session
 Session session = sessionFactory.openSession();
 Course course = session.get(Course.class,5);
 System.out.println(course);
 session.close();
 }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值