Mybatis中的延迟加载案例解析

Mybatis中的延迟加载案例解析

Mybatis是一款优秀的基于Java的持久层框架,采用了ORM(对象关系映射)思想,可以将Java对象和数据库表中的数据进行映射。Mybatis中的延迟加载功能非常实用,可以大幅提升系统的性能和响应速度。下面我们来详细讲解Mybatis中的延迟加载案例解析。

延迟加载的概念

延迟加载是指在需要实际使用对象时再进行加载和初始化,可以有效减少程序的开销和响应时间。在Mybatis框架中,如果开启了延迟加载功能,当查询某个数据库实体时,只会查询出该实体的基本信息或者ID等,而不会马上查询相应的关联信息或者子实体信息,只有在使用时才会进行查询和加载。

Mybatis中的延迟加载示例1

在Mybatis中,开启延迟加载功能非常简单,只需要在mybatis-config.xml配置文件中将lazyLoadingEnabled设置为true即可:

<settings>
  <setting name="lazyLoadingEnabled" value="true" />
</settings>

假设我们有两个实体类:Department和Employee,它们之间的关系是一对多,即一个Department对应多个Employee。下面是Department类和Employee类的定义:

public class Department {
    private Integer id;
    private String name;
    private List<Employee> employees;
    // getter和setter方法
}

public class Employee {
    private Integer id;
    private String name;
    private Integer age;
    private Integer salary;
    private Integer deptId;
    private Department department;
    // getter和setter方法
}

这里Employee类中包含了一个Department对象,表示Employee所属的部门。而Department类中包含了一个List集合,用于存储该部门下的所有员工。

假设我们要查询一个Department对象,并且需要获取该部门下的所有员工信息,但是我们又不想马上查询所有的员工信息,而是在需要使用时再进行查询。这时我们只需要在Department类中的employees属性上加上@LazyCollection和@LazyCollectionOption注解即可:

public class Department {
    private Integer id;
    private String name;
    @LazyCollection(LazyCollectionOption.EXTRA)
    private List<Employee> employees;
    // getter和setter方法
}

@LazyCollection注解表示开启延迟加载功能,@LazyCollectionOption(EXTRA)表示不会影响查询Department实体本身的查询操作,只会在需要使用employees属性时查询。

下面是查询Department实体的示例代码:

try(SqlSession session = factory.openSession()){
    DepartmentMapper departmentMapper = session.getMapper(DepartmentMapper.class);
    Department department = departmentMapper.getDepartmentById(1);
    System.out.println(department.getName());
    List<Employee> employees = department.getEmployees();
    for (Employee employee : employees) {
        System.out.println(employee.getName());
    }
}

在这里,我们首先查询了ID为1的Department实体对象,并获取了该Department下的所有员工信息,但实际上只有在遍历employees属性时才会进行员工信息的查询操作。

Mybatis中的延迟加载示例2

除了使用@LazyCollection注解之外,Mybatis中还提供了另一种开启延迟加载功能的方式,那就是使用标签中的fetchType属性设置为lazy:

<select id="getOrderById" resultMap="orderResultMap">
    SELECT id, user_id, create_time
    FROM t_order
    WHERE id = #{id}
</select>
<select id="getOrderItemsByOrderId" resultMap="orderItemResultMap" fetchType="lazy">
    SELECT id, order_id, product_id, quantity, price
    FROM t_order_item
    WHERE order_id = #{orderId}
</select>
<resultMap id="orderResultMap" type="Order">
    <id property="id" column="id"/>
    <result property="userId" column="user_id"/>
    <result property="createTime" column="create_time"/>
    <collection property="orderItems" ofType="OrderItem">
        <id property="id" column="id"/>
        <result property="orderId" column="order_id"/>
        <result property="productId" column="product_id"/>
        <result property="quantity" column="quantity"/>
        <result property="price" column="price"/>
    </collection>
</resultMap>
<resultMap id="orderItemResultMap" type="OrderItem">
    <id property="id" column="id"/>
    <result property="orderId" column="order_id"/>
    <result property="productId" column="product_id"/>
    <result property="quantity" column="quantity"/>
    <result property="price" column="price"/>
</resultMap>

在这里,我们将关联查询OrderItem的SQL语句中的fetchType属性设置为lazy,表示开启延迟加载功能。这样,在查询Order实体对象时,只会查询出该订单的基本信息,而不会马上查询相应的商品项信息,只有在需要使用时才进行查询和加载。

下面是查询Order实体对象的示例代码:

try(SqlSession session = factory.openSession()){
    OrderMapper orderMapper = session.getMapper(OrderMapper.class);
    Order order = orderMapper.getOrderById(1L);
    System.out.println(order.getId() + " " + order.getUserId() + " " + order.getCreateTime());
    // 进行OrderItem的查询和遍历
    List<OrderItem> orderItems = orderMapper.getOrderItemsByOrderId(order.getId());
    for (OrderItem item : orderItems) {
        System.out.println(item.getId() + " " + item.getProductId() + " " + item.getQuantity() + " " + item.getPrice());
    }
}

在这里,我们首先查询ID为1的Order实体对象,并获取了该订单下的所有商品项信息,但实际上只有在遍历orderItems属性时才会进行商品项信息的查询操作。

总结

Mybatis中的延迟加载功能非常实用,在需要查询大批量数据或者数据关联比较复杂的情况下,可以有效减少程序的开销和响应时间。本文中,我们介绍了两个Mybatis中的延迟加载示例,一个是使用@LazyCollection注解,另一个是使用