SpringBoot 3.x 整合 MyBatis-Plus(自动填充字段处理器、分页、多表查询、代码生成器)

tips1:解决 PaginationInnerInterceptor 爆红

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

<!-- mybatis-plus 分页插件,要和 mybatis-plus 版本一致 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-jsqlparser</artifactId>
    <version>3.5.10.1</version>
</dependency>

tips2:【已解决】lombok 注解不生效,编译报错

1、Maven

    <properties>
        <java.version>21</java.version>
        <mysql-connector-j.version>9.1.0</mysql-connector-j.version>
        <mybatis-plus.version>3.5.10.1</mybatis-plus.version>
        <mybatis-plus-jsqlparser.version>3.5.10.1</mybatis-plus-jsqlparser.version>
        <mybatis-plus-join.version>1.5.2</mybatis-plus-join.version>
        <mybatis-plus-generator.version>3.5.10.1</mybatis-plus-generator.version>
        <lombok.version>1.18.36</lombok.version>
    </properties>        


        <!-- mysql 驱动 -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>${mysql-connector-j.version}</version>
        </dependency>

        <!-- spring-boot3 , mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>

        <!-- mybatis-plus 分页插件 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-jsqlparser</artifactId>
            <version>${mybatis-plus-jsqlparser.version}</version> <!-- 确保版本和 MyBatis Plus 主包一致 -->
        </dependency>

        <!-- mybatis-plus 多表查询 -->
        <dependency>
            <groupId>com.github.yulichang</groupId>
            <artifactId>mybatis-plus-join-boot-starter</artifactId>
            <version>${mybatis-plus-join.version}</version>
        </dependency>

        <!-- mybatis-plus 代码生成器  -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>${mybatis-plus-generator.version}</version>
        </dependency>

        <!-- mybatis-plus 代码生成器 模板引擎  -->
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>

2、自动填充

2.1 配置自动填充处理器

package com.dragon.springboot3vue3.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.dragon.springboot3vue3.entity.User;
import com.dragon.springboot3vue3.utils.ThreadLocalUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;

/**
 * MybatisPlus 自动填充策略处理器
 */
@Component
public class MybatisPlusHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        // 获取登录的用户信息
        User user = ThreadLocalUtils.get();
        // 创建时间
        this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
        // 更新时间
        this.setFieldValByName("ts", LocalDateTime.now(), metaObject);
        // 创建者ID
        this.setFieldValByName("creatorId", user.getId(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        // 更新时间
        this.setFieldValByName("ts", LocalDateTime.now(), metaObject);
    }

}

2.2 实体类属性使用 @TableField 进行自动填充

package com.dragon.springboot3vue3.entity;

import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Email;
import lombok.Data;
import org.hibernate.validator.constraints.URL;
import java.io.Serializable;
import java.time.LocalDateTime;

@Data
@Schema(name = "User", description = "用户表")
public class User implements Serializable {
    private static final long serialVersionUID=1L;

    @Schema(description = "主键")
    @TableId(value = "id", type = IdType.ASSIGN_UUID)
    private String id;

    @Schema(description = "用户名")
    private String username;

    @Schema(description = "密码")
    @JsonIgnore
    private String password;

    @Schema(description = "姓名")
    private String name;

    @Schema(description = "邮箱")
    @Email
    private String email;

    @Schema(description = "头像地址")
    @URL
    private String avatarUrl;

    @Schema(description = "创建人ID")
    @TableField(fill = FieldFill.INSERT)
    private String creatorId;

    @Schema(description = "创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    @Schema(description = "更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime ts;

    @Schema(description = "逻辑删除字段 0.正常 1.删除")
    @TableLogic
    private Integer deleteFlag;
}

3、实现多表查询,返回分页数据

3.1 添加 MybatisPlus 分页插件

package com.dragon.springboot3vue3.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;

@Configuration
public class MybatisPlusConfig {
    /**
     * 添加 MybatisPlus 分页插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

3.2 mapper 继承 MPJBaseMapper

package com.dragon.springboot3vue3.mapper;

import com.dragon.springboot3vue3.entity.Article;
import com.github.yulichang.base.MPJBaseMapper;
import org.apache.ibatis.annotations.Mapper;

/**
 * <p>
 * 文章表 Mapper 接口
 * </p>
 *
 * @author dragon
 * @since 2024-04-24
 */
@Mapper
public interface ArticleMapper extends MPJBaseMapper<Article> {

}

3.3 多表查询,返回分页数据

package com.dragon.springboot3vue3.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dragon.springboot3vue3.controller.dto.entityDto.ArticleDto;
import com.dragon.springboot3vue3.controller.dto.pageDto.ArticlePageDto;
import com.dragon.springboot3vue3.entity.Article;
import com.dragon.springboot3vue3.entity.Category;
import com.dragon.springboot3vue3.mapper.ArticleMapper;
import com.dragon.springboot3vue3.service.IArticleService;
import com.dragon.springboot3vue3.utils.Result;
import com.dragon.springboot3vue3.utils.StringIdsDTO;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;


/**
 * <p>
 * 文章表 前端控制器
 * </p>
 *
 * @author dragon
 * @since 2024-04-24
 */
@Tag(name = "文章接口")
@RestController
@RequestMapping("/article")
public class ArticleController {
    @Autowired
    private IArticleService articleService;
    @Autowired
    private ArticleMapper articleMapper;

    @Operation(summary = "列表")
    @PostMapping("/list")
    public Result list(@RequestBody ArticlePageDto pageDto){
        // 创建分页对象
        Page<ArticleDto> page=new Page<>(pageDto.getCurrentPage(), pageDto.getPageSize());

        // 构造多表查询条件
        MPJLambdaWrapper<Article> qw=new MPJLambdaWrapper<Article>()
                .selectAll(Article.class)
                .select(Category::getCategoryName)
                .leftJoin(Category.class,Category::getId,Article::getCategoryId)
                .like(StringUtils.isNotBlank(pageDto.getTitle()),Article::getTitle, pageDto.getTitle())
                .eq(StringUtils.isNotBlank(pageDto.getCategoryId()),Article::getCategoryId, pageDto.getCategoryId())
                .eq(StringUtils.isNotBlank(pageDto.getStatus()),Article::getStatus, pageDto.getStatus());

        // 根据查询条件,将结果封装到分页对象
        Page<ArticleDto> response=articleMapper.selectJoinPage(page, ArticleDto.class,qw);

        return Result.success(response);
    }
}

4、代码生成器(根据数据库表生成代码)

package com.dragon.pay;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.model.ClassAnnotationAttributes;

public class CodeGenerator {
    public static void main(String[] args) {
        String url="jdbc:mysql://localhost:3306/pay?serverTimezone=UTC";
        String username="lll";
        String password="111";
        String tables="user";   // 多表,可用逗号分隔

        FastAutoGenerator.create(url, username, password)
                .globalConfig(builder -> {
                    builder.author("Dragon")    // 设置作者
                            .enableSpringdoc()  // 开启 swagger 模式
                            .disableOpenDir()   // 禁止打开输出目录,默认false
                            .outputDir("D:\\IdeaWorkspace\\pay\\src\\main\\java"); // 指定输出目录
                })
                .packageConfig(builder -> {
                     builder.parent("com.dragon.pay")     // 父包名
                             .entity("entity")            // 实体类包名
                             .controller("controller")    // controller 包名
                             .service("service")          // service 包名
                             .serviceImpl("service.impl") // service.impl 包名
                             .mapper("mapper");           // mapper 包名
                })
                .strategyConfig(builder -> {
                    builder.addInclude(tables)                // 设置需要生成的表名
                            .entityBuilder()                  // entity
                            .formatFileName("%s")             // 格式化实体名称,%s取消首字母I
                            .idType(IdType.ASSIGN_UUID)
                            .enableLombok(new ClassAnnotationAttributes("@Data","lombok.Data")) // @Data
                            .addTableFills(new Column("create_id", FieldFill.INSERT))       // 自动填充注解
                            .addTableFills(new Column("create_time", FieldFill.INSERT))     // 自动填充注解
                            .addTableFills(new Column("ts", FieldFill.INSERT_UPDATE))       // 自动填充注解
                            .logicDeleteColumnName("delete_flag")   // 逻辑删除注解
                            .enableFileOverride()                   // 覆盖已生成文件

                            .controllerBuilder()              // controller
                            .enableRestStyle()                // @RestController
                            .enableFileOverride()             // 覆盖已生成文件

                            .serviceBuilder()                   // service
                            .formatServiceFileName("%sService") // 格式化实体名称,%s取消首字母I
                            .enableFileOverride()               // 覆盖已生成文件

                            .formatServiceImplFileName("%sServiceImpl") // serviceImpl,格式化实体名称,%s取消首字母I
                            .enableFileOverride()                       // 覆盖已生成文件

                            .mapperBuilder()                  // mapper
                            .formatMapperFileName("%sMapper") // 格式化实体名称,%s取消首字母I
                            .enableMapperAnnotation()         // @Mapper
                            .enableFileOverride();            // 覆盖已生成文件;
                })
                .templateEngine(new FreemarkerTemplateEngine())     // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值