MyBatis-Plus 中实现 多表查询 主要有以下几种方式:

🔥 方式 1:使用 @Select 注解(最简单)

适用于 少量自定义查询,直接在 Mapper 接口 中使用 SQL 语句

🔥 方式 2:使用 XML 方式(推荐复杂 SQL)

如果 SQL 比较复杂,可以使用 XML 配置

<select id="getUserWithDepartment" resultType="com.example.dto.UserDTO">
    SELECT u.*, d.department_name 
    FROM user u 
    LEFT JOIN department d ON u.department_id = d.id
    WHERE u.id = #{id}
</select>

🔥 方式 3:使用 MyBatis-Plus Wrapper(代码构造查询)

适用于 动态 SQL 查询,但 MyBatis-Plus 默认不支持 JOIN,需要结合 QueryWrapper + select

@Autowired
private UserMapper userMapper;

public List<UserDTO> getUserWithDepartment() {
    return userMapper.selectJoinList(UserDTO.class, new MPJLambdaWrapper<User>()
        .selectAll(User.class)
        .select(Department::getDepartmentName)
        .leftJoin(Department.class, Department::getId, User::getDepartmentId)
    );
}

📌 说明

  • MPJLambdaWrapper<User>()MyBatis-Plus-Join(MPJ)扩展库,可以 优雅支持 JOIN

  • selectJoinList(UserDTO.class, wrapper) 自动映射查询结果。

<dependency>
    <groupId>com.github.yulichang</groupId>
    <artifactId>mybatis-plus-join</artifactId>
    <version>1.4.8</version>
</dependency>

🔥 方式 4:使用 自定义 Mapper + DTO 组合

有时候,我们可能不希望直接用 JOIN 查询,而是分步查询后 组合数据

public UserDTO getUserWithDepartment(Long userId) {
    User user = userMapper.selectById(userId);
    Department department = departmentMapper.selectById(user.getDepartmentId());

    UserDTO userDTO = new UserDTO();
    BeanUtils.copyProperties(user, userDTO);
    userDTO.setDepartmentName(department.getDepartmentName());

    return userDTO;
}

💡 总结

方式

适用场景

优势

劣势

@Select 注解

简单 SQL

代码简洁,方便

适合小 SQL,不适合复杂查询

XML 配置

复杂 SQL

可读性高,可维护

需要额外 XML 文件

MPJ Lambda Wrapper

代码构造查询

避免手写 SQL,类型安全

需要引入扩展库

自定义查询 & DTO 组合

高并发、微服务

可扩展性强,可缓存

需要多次查询

如果 SQL 逻辑复杂,推荐 XML 方式
如果 查询字段动态变化,推荐 MPJ Lambda Wrapper
如果 高并发场景,推荐 DTO 组合方式