MybatisPlusJoin 完整样例

1、数据库

复制代码
CREATE TABLE `mp_order` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `order_no` varchar(50) NOT NULL COMMENT '订单编号',
  `user_id` bigint NOT NULL COMMENT '关联用户ID',
  `amount` decimal(10,2) NOT NULL COMMENT '订单金额',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='订单表';

CREATE TABLE `mp_user` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `age` int DEFAULT NULL COMMENT '年龄',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户表';

INSERT INTO `mp_order` (`id`, `order_no`, `user_id`, `amount`, `create_time`) VALUES (1, 'ORDER_001', 1, 100.00, '2025-12-24 09:44:08');
INSERT INTO `mp_order` (`id`, `order_no`, `user_id`, `amount`, `create_time`) VALUES (2, 'ORDER_002', 1, 200.00, '2025-12-24 09:44:08');
INSERT INTO `mp_order` (`id`, `order_no`, `user_id`, `amount`, `create_time`) VALUES (3, 'ORDER_003', 2, 150.00, '2025-12-24 09:44:08');

INSERT INTO `mp_user` (`id`, `username`, `age`, `create_time`) VALUES (1, '张三', 20, '2025-12-24 09:44:08');
INSERT INTO `mp_user` (`id`, `username`, `age`, `create_time`) VALUES (2, '李四', 25, '2025-12-24 09:44:08');
INSERT INTO `mp_user` (`id`, `username`, `age`, `create_time`) VALUES (3, '王五', 30, '2025-12-24 09:44:08');

2、pom.xml文件

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.18</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>springboot-mp-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-mp-demo</name>
    <description>Spring Boot + MyBatis Plus 分页多表查询样例</description>

    <properties>
        <java.version>1.8</java.version>
        <mybatis-plus.version>3.5.14</mybatis-plus.version>
        <mybatis-plus-join.version>1.5.5</mybatis-plus-join.version>
        <hutool.version>5.8.23</hutool.version>
    </properties>

    <dependencies>
        <!-- Spring Boot Web核心 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- MySQL驱动(适配8.0) -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
            <scope>runtime</scope>
        </dependency>

        <!-- jdk 8+ 引入可选模块 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-jsqlparser-4.9</artifactId>
            <version>3.5.14</version>
        </dependency>

        <!-- MyBatis Plus 核心 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>

        <!-- MyBatis Plus Join(多表连接) -->
        <dependency>
            <groupId>com.github.yulichang</groupId>
            <artifactId>mybatis-plus-join-boot-starter</artifactId>
            <version>${mybatis-plus-join.version}</version>
        </dependency>

        <!-- Hutool 工具库 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>

        <!-- Lombok(简化实体类) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- 测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

3、mybatis plus分页配置

复制代码
package com.example.demo.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * MyBatis Plus 配置类(核心:分页插件)
 */
@Configuration
public class MyBatisPlusConfig {

    /**
     * 分页插件(必须配置,否则分页查询无效)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 适配MySQL的分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

4、业务代码

复制代码
package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 订单实体(对应order表)
 */
@Data
@TableName("mp_order") // 指定数据库表名
public class Order {
    /**
     * 主键ID
     */
    private Long id;
    /**
     * 订单编号
     */
    private String orderNo;
    /**
     * 关联用户ID
     */
    private Long userId;
    /**
     * 订单金额
     */
    private BigDecimal amount;
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
}








package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;

/**
 * 用户实体(对应user表)
 */
@Data
@TableName("mp_user") // 指定数据库表名
public class User {
    /**
     * 主键ID
     */
    private Long id;
    /**
     * 用户名
     */
    private String username;
    /**
     * 年龄
     */
    private Integer age;
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
}









package com.example.demo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.Order;
import com.github.yulichang.base.MPJBaseMapper;

/**
 * 订单Mapper(基础MyBatis Plus Mapper)
 */
public interface OrderMapper extends MPJBaseMapper<Order> {
}





package com.example.demo.mapper;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.example.demo.entity.User;
import com.example.demo.vo.UserOrderVO;
import com.github.yulichang.base.MPJBaseMapper;
import org.apache.ibatis.annotations.Param;

/**
 * 用户Mapper(继承MPJBaseMapper支持多表连接)
 */
public interface UserMapper extends MPJBaseMapper<User> {

    /**
     * 单表分页查询用户(基础用法)
     */
    IPage<User> selectUserPage(Page<User> page, @Param("age") Integer age);

    /**
     * 多表连接分页查询(用户+订单)
     */
    IPage<UserOrderVO> selectUserOrderPage(Page<UserOrderVO> page, @Param("username") String username);
}








package com.example.demo.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.entity.User;
import com.example.demo.vo.UserOrderVO;

/**
 * 用户Service接口
 */
public interface UserService extends IService<User> {

    /**
     * 单表分页查询用户
     * @param pageNum 页码
     * @param pageSize 页大小
     * @param age 年龄(可选条件)
     * @return 分页结果
     */
    IPage<User> getUserPage(Integer pageNum, Integer pageSize, Integer age);

    /**
     * 多表连接分页查询(用户+订单)
     * @param pageNum 页码
     * @param pageSize 页大小
     * @param username 用户名(可选条件)
     * @return 分页结果
     */
    IPage<UserOrderVO> getUserOrderPage(Integer pageNum, Integer pageSize, String username);
}







package com.example.demo.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.entity.Order;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import com.example.demo.vo.UserOrderVO;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 用户Service实现类
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    /**
     * 单表分页查询用户
     */
    @Override
    public IPage<User> getUserPage(Integer pageNum, Integer pageSize, Integer age) {
        // 1. 构建分页对象
        Page<User> page = new Page<>(pageNum, pageSize);
        // 2. 构建查询条件
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        if (age != null) {
            queryWrapper.ge(User::getAge, age); // 年龄大于等于指定值
        }
        // 3. 分页查询(MyBatis Plus内置分页方法)
        return userMapper.selectPage(page, queryWrapper);
    }

    /**
     * 多表连接分页查询(用户+订单)
     * 使用MyBatis Plus Join实现多表连接
     */
    @Override
    public IPage<UserOrderVO> getUserOrderPage(Integer pageNum, Integer pageSize, String username) {
        // 1. 构建分页对象
        Page<UserOrderVO> page = new Page<>(pageNum, pageSize);

        // 2. 构建多表连接查询条件(MPJ核心用法)
        MPJLambdaWrapper<User> wrapper = new MPJLambdaWrapper<User>()
                // 主表:user
                .selectAll(User.class) // 查询user表所有字段
                .leftJoin(Order.class, Order::getUserId, User::getId)
                // 自定义查询字段(指定别名,匹配VO的字段)
                .selectAs(User::getId, UserOrderVO::getUserId)
                .selectAs(Order::getId, UserOrderVO::getOrderId)
                .select(Order::getOrderNo)
                .select(Order::getAmount)
                .selectAs(Order::getCreateTime, UserOrderVO::getOrderCreateTime)
                // 条件:用户名模糊查询(Hutool工具类判空)
                .like(StrUtil.isNotBlank(username), User::getUsername, username);

        // 3. 多表分页查询
        return userMapper.selectJoinPage(page, UserOrderVO.class, wrapper);
    }
}









package com.example.demo.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import com.example.demo.vo.UserOrderVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 用户接口控制器
 */
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 单表分页查询用户接口
     * @param pageNum 页码(默认1)
     * @param pageSize 页大小(默认10)
     * @param age 年龄(可选)
     * @return 分页结果
     */
    @GetMapping("/user/page")
    public IPage<User> getUserPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) Integer age) {
        return userService.getUserPage(pageNum, pageSize, age);
    }

    /**
     * 多表连接分页查询接口(用户+订单)
     * @param pageNum 页码(默认1)
     * @param pageSize 页大小(默认10)
     * @param username 用户名(可选)
     * @return 分页结果
     */
    @GetMapping("/user/joinPage")
    public IPage<UserOrderVO> getUserOrderPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String username) {
        return userService.getUserOrderPage(pageNum, pageSize, username);
    }
}

5、接口测试

复制代码
2. 接口测试(使用 Postman / 浏览器)
   (1)单表分页查询用户
   请求地址:http://localhost:8080/user/page?pageNum=1&pageSize=2&age=20

(2)多表连接分页查询
请求地址:http://localhost:8080/user/joinPage?pageNum=1&pageSize=2&username=张三
相关推荐
float_六七2 小时前
Java JAR包运行与反编译全攻略
java·开发语言·jar
l1t2 小时前
修改一个触发PostgreSQL 17.2 bug的SQL
sql·postgresql·bug
运维行者_2 小时前
不同规模企业如何选 OPM?参考局域网管理软件与 cpu 温度监控适配指南
大数据·运维·服务器·网络·数据库·postgresql·snmp
老秦包你会2 小时前
C++进阶------C++的类型转换
java·开发语言·c++
星辰烈龙2 小时前
黑马程序员JavaSE基础加强d2
java·开发语言
冰冰菜的扣jio2 小时前
MySQL高性能优化合集
数据库·mysql
weixin_404679312 小时前
vscode 配置cpp调试环境
数据库·ide·vscode·编辑器
ps酷教程2 小时前
HttpObjectDecoder源码浅析
java·netty·httpaggregator
TG:@yunlaoda360 云老大2 小时前
华为云国际站代理商GaussDB主要有什么作用呢?
服务器·数据库·华为云·gaussdb