MyBatis Plus延迟加载

MyBatis Plus延迟加载

MyBatis Plus延迟加载:

MyBatis/MyBatis Plus 是支持延迟加载的,默认没有开启,需要手动开启,以 MyBatis Plus 为例作为演示。

假设有两个用户表 orderuser

DROP TABLE IF EXISTS `order`;
CREATE TABLE `order` (
  `id` int NOT NULL AUTO_INCREMENT,
  `user_id` int DEFAULT NULL,
  `order_content` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_000_ai_ci;
INSERT INTO `order` VALUES (1,1,'computer'),(2,1,'phone');

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
INSERT INTO `user` VALUES (1,'Jack');

实体类 OrderUser

@Data
@TableName(value ="order")
public class Order implements Serializable {
    private Integer id;
    private Integer userId;
    private String orderContent;
}

@Data
@TableName(value ="user")
public class User implements Serializable {
    private Integer id;
    private String name;
    @TableField(exist = false)
    private List<Order> orderList;
}

Mapper接口:

@Mapper
public interface OrderMapper extends BaseMapper<Order> {
    @Select("select o.id, o.user_id, o.order_content from `order` o where user_id = #{userId}")
    List<Order> getOrderListByUserId(@Param("userId") Integer userId);
}

@Mapper
public interface UserMapper extends BaseMapper<User> {
    @Select("select u.id, u.name from `user` u where id = #{id}")
    @Results({
            @Result(property = "orderList",
                    column = "id",
                    javaType = List.class,
                    many = @Many(select = "com.checo.mapper.OrderMapper.getOrderListByUserId",
                            fetchType = FetchType.LAZY)) // fetchType = FetchType.LAZY 即开启延迟加载
    })
    User getUserById(@Param("id") Integer id);
}

添加配置,让我们可以看到 SQL 执行日志:

mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

测试延迟加载:

@SpringBootTest
class SpringBootDemoApplicationTests {
    @Autowired
    private UserMapper userMapper;

    @Test
    public void testMyBatisPlusLazy() {
        User jack = userMapper.getUserById(1);
        System.out.println(jack.getName());
        System.out.println("--------------");
        List<Order> orderList = jack.getOrderList();
        System.out.println(orderList);
    }
}

运行结果:

==>  Preparing: select u.id, u.name from `user` u where id = ?
==> Parameters: 1(Integer)
<==    Columns: id, name
<==        Row: 1, Jack
<==      Total: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@149b0577]
Jack
------- 分割线 -------
JDBC Connection [HikariProxyConnection@993343057 wrapping com.mysql.cj.jdbc.ConnectionImpl@5ec1963c] will not be managed by Spring
==>  Preparing: select o.id, o.user_id, o.order_content from `order` o where user_id = ?
==> Parameters: 1(Integer)
<==    Columns: id, user_id, order_content
<==        Row: 1, 1, computer
<==        Row: 2, 1, phone
<==      Total: 2
[Order(id=1, userId=1, orderContent=computer), Order(id=2, userId=1, orderContent=phone)]

可以看出,在执行 jack.getOrderList() 时,才执行的订单查询,即实现了延迟加载。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。