MP 自定义业务方法 (二)

一、项目结构(标准后端结构)

复制代码
src/main
├── java/com/example/demo
│   ├── DemoApplication.java          # 启动类
│   ├── common/
│   │   └── Result.java               # 全局统一返回
│   ├── entity/                       # 数据库实体
│   │   ├── User.java
│   │   └── SysUnit.java
│   ├── dto/                          # 查询参数封装
│   │   └── UserQueryDTO.java
│   ├── vo/                           # 视图对象(连表/返回前端)
│   │   └── UserUnitVO.java
│   ├── mapper/                       # Mapper接口
│   │   └── UserMapper.java
│   ├── service/
│   │   ├── UserService.java          # 业务接口
│   │   └── impl/
│   │       └── UserServiceImpl.java  # 业务实现
│   └── controller/
│       └── UserController.java       # 接口层
└── resources/                        # 资源目录(核心!)
    ├── mapper/
    │   └── xml/
    │       └── UserMapper.xml        # XML SQL文件(放这里!)
    └── application.yml               # 配置文件

二、核心依赖(pom.xml)

xml 复制代码
<!-- Spring Web -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- MyBatis-Plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

<!-- MySQL驱动 -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <scope>runtime</scope>
</dependency>

<!-- Lombok 简化代码 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

三、配置文件(application.yml)

yaml 复制代码
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/your_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456

mybatis-plus:
  mapper-locations: classpath:mapper/xml/*.xml
  # ✅ 修复:同时扫描 entity 和 vo
  type-aliases-package: com.example.demo.entity,com.example.demo.vo
  configuration:
    map-unders-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

四、基础代码编写

0. 配置类
java 复制代码
package com.example.demo.common;

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;
    }
}
1. 全局统一返回结果(Result.java)

实际开发必须用统一返回体,前端方便解析

java 复制代码
package com.example.demo.common;

import lombok.Data;

/**
 * 全局统一返回结果
 */
@Data
public class Result<T> {
    private int code;
    private String msg;
    private T data;

    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMsg("操作成功");
        result.setData(data);
        return result;
    }

    public static <T> Result<T> fail(String msg) {
        Result<T> result = new Result<>();
        result.setCode(500);
        result.setMsg(msg);
        return result;
    }
}
2.1. 实体类 User.java

对应数据库表 sys_user(企业标准表名)

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

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

/**
 * 用户实体类
 */
@Data
@TableName("sys_user") // 绑定数据库表名
public class User {
    // 主键自增
    @TableId(type = IdType.AUTO)
    private Long id;

    // 用户名
    private String username;

    // 单位ID(核心查询条件)
    private Long unitId;

    // 手机号
    private String phone;

    // 创建时间
    private LocalDateTime createTime;
}
2.2 实体类 SysUnit.java
java 复制代码
package com.example.demo.entity;

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

@Data
@TableName("sys_unit")
public class SysUnit {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String unitName; // 单位名称
    private String leader;  // 负责人
    private LocalDateTime createTime;
}
2.3 连表查询结果VO
java 复制代码
package com.example.demo.vo;

import lombok.Data;
import java.time.LocalDateTime;

/**
 * 用户 + 单位 连表返回视图
 */
@Data
public class UserUnitVO {
    // 用户字段
    private Long id;
    private String username;
    private Long unitId;
    private String phone;
    private LocalDateTime createTime;

    // 单位字段(连表查询出来的)
    private String unitName; // 单位名称
    private String leader;   // 单位负责人
}
3. 查询参数DTO(UserQueryDTO.java)

封装查询条件,避免Controller用零散参数

java 复制代码
package com.example.demo.dto;

import lombok.Data;

/**
 * 用户查询参数
 */
@Data
public class UserQueryDTO {
    // 用户名(模糊查询)
    private String username;
    // 单位ID(精确查询)
    private Long unitId;
	private String phone;

	// 分页参数
    private Integer pageNum = 1;   // 默认第1页
    private Integer pageSize = 10; // 默认每页10条
}

五、自定义 Mapper + XML(核心)

1. Mapper 接口(UserMapper.java)

继承 MP 的 BaseMapper自定义业务方法

java 复制代码
package com.example.demo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.dto.UserQueryDTO;
import com.example.demo.entity.User;
import com.example.demo.vo.UserUnitVO;
import org.apache.ibatis.annotations.Param;

public interface UserMapper extends BaseMapper<User> {

    // 分页查询:单表
    IPage<User> selectUserList(Page<User> page, @Param("query") UserQueryDTO query);

    // 分页查询:连表
    IPage<UserUnitVO> selectUserUnitList(Page<UserUnitVO> page, @Param("query") UserQueryDTO query);
}
2. XML SQL 文件(UserMapper.xml)

手写自定义SQL ,放在 resources/mapper/xml/

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.example.demo.mapper.UserMapper">

    <!-- 单表查询 -->
    <select id="selectUserList" resultType="User">
        SELECT
            id, username, unit_id, phone, create_time
        FROM sys_user
        <where>
            <if test="query.username != null and query.username != ''">
                AND username LIKE CONCAT('%', #{query.username}, '%')
            </if>
            <if test="query.unitId != null">
                AND unit_id = #{query.unitId}
            </if>
            <if test="query.phone != null and query.phone != ''">
                AND phone LIKE CONCAT('%', #{query.phone}, '%')
            </if>
        </where>
    </select>

    <!-- 连表查询 -->
    <select id="selectUserUnitList" resultType="UserUnitVO">
        SELECT
            u.id,
            u.username,
            u.unit_id,
            u.phone,
            u.create_time,
            un.unit_name,
            un.leader
        FROM sys_user u
        LEFT JOIN sys_unit un 
        ON u.unit_id = un.id
        <where>
            <if test="query.username != null and query.username != ''">
                AND u.username LIKE CONCAT('%', #{query.username}, '%')
            </if>
            <if test="query.unitId != null">
                AND u.unit_id = #{query.unitId}
            </if>
        </where>
    </select>

</mapper>

六、Service 业务层

1. Service 接口(UserService.java)
java 复制代码
package com.example.demo.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo.dto.UserQueryDTO;
import com.example.demo.entity.User;
import com.example.demo.vo.UserUnitVO;

public interface UserService extends IService<User> {

    IPage<User> getUserList(UserQueryDTO query);

    IPage<UserUnitVO> getUserUnitList(UserQueryDTO query);
}
2. Service 实现类(UserServiceImpl.java)

调用自定义 Mapper 方法(核心步骤)

java 复制代码
package com.example.demo.service.impl;

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.dto.UserQueryDTO;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.UserService;
import com.example.demo.vo.UserUnitVO;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Override
    public IPage<User> getUserList(UserQueryDTO query) {
        // 构建分页对象
        Page<User> page = new Page<>(query.getPageNum(), query.getPageSize());
        return userMapper.selectUserList(page, query);
    }

    @Override
    public IPage<UserUnitVO> getUserUnitList(UserQueryDTO query) {
        Page<UserUnitVO> page = new Page<>(query.getPageNum(), query.getPageSize());
        return userMapper.selectUserUnitList(page, query);
    }
}

七、Controller 接口层

java 复制代码
package com.example.demo.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.demo.common.Result;
import com.example.demo.dto.UserQueryDTO;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import com.example.demo.vo.UserUnitVO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;

@RestController
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    // === 分页列表接口 ===
    @GetMapping("/list")
    public Result<IPage<User>> getUserList(UserQueryDTO query) {
        IPage<User> page = userService.getUserList(query);
        return Result.success(page);
    }

    // === 分页连表接口 ===
    @GetMapping("/unitList")
    public Result<IPage<UserUnitVO>> getUserUnitList(UserQueryDTO query) {
        IPage<UserUnitVO> page = userService.getUserUnitList(query);
        return Result.success(page);
    }
}

八、启动类

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

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// 扫描Mapper接口(核心!)
@MapperScan("com.example.demo.mapper")
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

九、测试接口

请求方式 :GET
请求地址http://localhost:8080/user/list?username=张三&unitId=10&pageNum=1&pageSize=10
请求参数

复制代码
username=张三(模糊匹配)
unitId=10(精确匹配)

返回结果

json 复制代码
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "records": [{}, {}], // 列表数据
    "total": 125,        // 总条数
    "size": 10,          // 每页条数
    "current": 1,        // 当前页
    "pages": 13          // 总页数
  }
}

总结

  1. 核心流程Controller接收参数Service调用自定义MapperMapper执行XML中的SQL
  2. 关键注解
    • @MapperScan:扫描Mapper接口
    • @Param:XML参数绑定
    • @TableName:实体绑定表名
  3. 实际开发规范
    • DTO 封装查询参数
    • 动态SQL 拼接条件
    • 统一返回体 封装响应
    • XML 单独存放,不与代码耦合
相关推荐
逸风尊者1 小时前
XGBoost模型工程使用
java·后端·算法
低客的黑调1 小时前
MyBatis-Plus-从 CRUD 到高级特性
java·servlet·tomcat
就像风一样抓不住2 小时前
Java 手机号校验工具类
java
凤山老林2 小时前
26-Java this 关键字
java·开发语言
焦糖玛奇朵婷2 小时前
解锁扭蛋机小程序的五大优势
java·大数据·服务器·前端·小程序
SamDeepThinking3 小时前
别让一个超时的第三方http接口拖垮所有接口
java·后端·架构
YaBingSec3 小时前
玄机靶场:供应链安全-供应链应急-Part2 通关笔记
java·笔记·安全
Gerardisite3 小时前
企微机器人开发指南
java·python·机器人·自动化·企业微信
OtIo TALL3 小时前
Java进阶(ElasticSearch的安装与使用)
java·elasticsearch·jenkins