MyBatis-Plus介绍及基本使用

文章目录

概述

介绍

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

主页: 传送门

引入 MyBatis-Plus 之后请不要再次引入 MyBatis 以及 MyBatis-Spring,以避免因版本差异导致的问题。

特性:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer2005、SQLServer 等多种数据库
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 XML 热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 支持关键词自动转义:支持数据库关键词(order、key...)自动转义,还可自定义关键词
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
  • 内置 Sql 注入剥离器:支持 Sql 注入剥离,有效预防 Sql 注入攻击

MyBatis-Plus 常用配置

MyBatis-Plus 的配置可以通过 application.propertiesapplication.yml 文件进行。以下是一些常用的配置选项及其说明。

yml 复制代码
mybatis-plus:
  # 指定MyBatis-Plus映射文件的位置
  mapper-locations: classpath:mapper/*.xml
  # 指定MyBatis-Plus映射文件的位置。递归查找所有子目录中符合.xml格式的文件
  #mapper-locations: "classpath*:/mapper/**/*.xml"
  # 指定实体类的包路径,自动扫描并注册别名
  type-aliases-package: com.example.yourproject.entity
  # 全局配置。用于设置MyBatis-Plus的一些整体行为
  global-config:
    db-config:
      # 主键生成策略。默认auto。可选值有auto(自动增长)、none(无)、input(手动输入)、id_worker(雪花算法)、uuid等
      id-type: auto
      # 表前缀,用于生成 SQL 时自动去掉前缀
      table-prefix: t_
      # 配置逻辑删除字段(如果使用了逻辑删除功能)
      logic-delete-field: deleted
      # 逻辑删除字段的值,表示已删除
      logic-delete-value: 1
      # 逻辑删除字段的值,表示未删除
      logic-not-delete-value: 0
      # 字段策略,可选值有 not_null(非空插入)、not_empty(非空插入)、ignore(忽略)等
      field-strategy: not_empty
      # 是否开启大写模式,生成的 SQL 字段名将全部大写
      capital-mode: true
      # 是否刷新缓存,默认为 true
      refresh: true
  # 分页配置。用于启用分页功能
  pagination:
    # 每页大小。默认10
    page-size: 10
    # 是否统计总记录数。默认true
    total: true
    # 是否合理化分页,当分页参数不合理时,自动调整。默认false
    reasonable: true
    # 是否支持方法参数作为分页参数。默认false
    support-methods-arguments: true
    # 分页参数名,可以自定义
    params: null
  # 配置。用于
  configuration:
    # 开启下划线转驼峰命名规则。默认true
    map-underscore-to-camel-case: true
    # 设置MyBatis-Plus的日志输出。日志实现类,org...logging.stdout.StdOutImpl (控制台输出)或其他日志实现类
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 

注:

  • mybatis-plus.mapper-locations:指定MyBatis-Plus映射文件的位置。

    若不指定,MyBatis-Plus 会尝试从 resources/mapper/ 目录下加载 XML 文件(这是 Spring Boot 和 MyBatis 的默认行为)

  • type-aliases-package:指定实体类的包路径,自动扫描并注册别名。

    如果实体类名与数据库表名一致,或者已经通过@TableName 注解指定了正确的表名,则该配置可以缺省

    该配置缺省时,MyBatis-Plus会自动识别实体类并映射到相应的数据库表,但在 XML 中引用实体类时需要使用全限定名

分页插件配置类

java 复制代码
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 {

    /**
     * 分页插件
     * 注:3.5.9版本,MyBatis-Plus 对分页插件做了拆分,需要单独引用mybatis-plus-jsqlparser依赖以支持PaginationInnerInterceptor类
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}

注解配置

  • @MapperScan:用于扫描 Mapper 接口,并将这些接口注册为 Spring 容器中的 Bean

    • 注解位置:通常放在 Spring Boot 应用的主类上,或者放在配置类上

    • 支持通配符 :支持使用通配符 * 来匹配一级包路径,如果需要匹配多级包路径,可以使用 ** 来代替

    • 属性

      • value 或 basePackages:指定需要扫描的包路径。可以是一个或多个包路径,用逗号分隔。

      • markerInterface:指定一个标记接口,只有实现了该接口的 Mapper 接口才会被扫描。

        这个参数可以用于更细粒度地控制扫描范围。

      • sqlSessionFactoryRef:指定 SQL 会话工厂的引用名称。

      • 这个参数通常用于多数据源配置时,指定不同数据源对应的 SQL 会话工厂。

    • 注意

      • 包路径的正确性 :在使用 @MapperScan 注解时,需要确保指定的包路径是正确的,并且包含了所有需要扫描的 Mapper 接口。
      • 避免重复扫描 :如果项目中已经通过其他方式(如 @Mapper 注解)将 Mapper 接口注册为 Bean,那么在使用 @MapperScan 注解时,需要避免重复扫描这些接口,否则可能会导致 Bean 冲突或性能问题。
      • 多数据源配置 :在配置多数据源时,需要注意 sqlSessionFactoryRef 参数的使用,以确保不同数据源对应的 Mapper 接口能够正确注册和使用。
  • @TableName:指定实体类对应的数据库表名

    • 说明:如果实体类的名称与数据库表名在命名上保持一致(即遵循驼峰转下划线的命名规则),则此注解不是必需的。但如果命名不一致,则需要使用此注解来明确指定表名。

    • 示例:

      java 复制代码
      @TableName("user")
      public class User {
          // 实体类属性
      }
  • @TableId:指定实体类中的主键字段

    • 说明 :如果实体类中有一个名为 id 的字段,并且希望它作为主键,则此注解不是必需的,因为 MyBatis-Plus 默认会将名为id的字段作为主键。但如果主键字段的名称不是 id,或者需要指定主键的生成策略(如自增、UUID等),则需要使用此注解。

    • 属性

      • value:字段名。
      • type:主键类型。可选值有 IdType.AUTO(自增)、IdType.NONE(无主键)、IdType.ASSIGN_ID(全局唯一ID)、IdType.ASSIGN_UUID(全局唯一UUID)等。
    • 示例:

      java 复制代码
      @TableId(value = "id", type = IdType.AUTO)
      private Long id;
  • @TableField:指定实体类中的普通字段与数据库表字段之间的映射关系

    • 说明 :如果实体类的字段名与数据库表的字段名在命名上保持一致(即遵循驼峰转下划线的命名规则),则此注解不是必需的。但如果字段名不一致,或者字段名与数据库的关键字冲突,或者需要处理成员变量以 is 开头且是布尔值的情况,则需要使用此注解。

    • 属性

      • value:字段名。

      • exist:字段是否存在,默认为 true

        如果实体类中有一些字段不需要映射到数据库表中,则可以设置为 false

      • fill:字段填充策略,可选值有 FieldFill.INSERT(插入时填充)、FieldFill.UPDATE(更新时填充)等。

    • 示例:

      java 复制代码
      @TableField(value = "name", fill = FieldFill.INSERT)
      private String name;
  • @TableLogic:指定逻辑删除字段

    • 属性

      • value:字段名。
      • delval:删除标记值。
      • undelval:未删除标记值。
    • 示例:

      java 复制代码
      @TableLogic(value = "0", delval = "1")
      private Integer deleted;
    • 是否必需:如果需要使用逻辑删除功能,则必须使用此注解。

  • @Version:指定乐观锁字段

    • 示例:

      Java 复制代码
      @Version
      private Integer version;
    • 是否必需:如果需要使用乐观锁功能,则必须使用此注解。

    @KeySequence:指定 Oracle 数据库的序列

    • 属性

      • value:序列名。
    • 示例:

      Java 复制代码
      @TableId(type = IdType.SEQUENCE, value = "user_seq")
      private Long id;
    • 是否必需:如果使用 Oracle 数据库的序列生成主键,则必须使用此注解。

    @Transient:指定不持久化的字段

    • 示例:

      Java 复制代码
      @Transient
      private String tempField;
    • 是否必需:如果实体类中有一些临时字段不需要持久化到数据库,则可以使用此注解。

快速入门

maven 依赖

xml 复制代码
<!-- MyBatis-plus启动器 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.9</version>
    <exclusions>
        <exclusion>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!--引入较新的mybatis-spring,支持springboot3-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>3.0.3</version>
</dependency>
<!--3.5.9版本,MyBatis-Plus 对分页插件做了拆分,需要单独引用依赖。jdk8引入mybatis-plus-jsqlparser-4.9 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-jsqlparser</artifactId>
    <version>3.5.9</version>
</dependency>

<!-- MyBatis-plus-generator 代码生成器 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.9</version>
</dependency>
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version>
</dependency>

编写配置文件

application.yml

yaml 复制代码
spring:
  application:
    name: plus-test
  datasource:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql:///mytest?characterEncoding=UTF-8
      username: root
      password: 123456
      type: com.alibaba.druid.pool.DruidDataSource

# myBatis-plus
mybatis-plus:
  # 指定MyBatis-Plus映射文件的位置
  mapper-locations: classpath*:mapper/*.xml
  # 指定实体类的包路径,自动扫描并注册别名
  type-aliases-package: com.example.entity
  configuration:
    # 设置MyBatis-Plus的日志输出。日志实现类,org...logging.stdout.StdOutImpl (控制台输出)或其他日志实现类
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

编写启动类

java 复制代码
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.**.mapper")
public class SpringBootRunner {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootRunner.class,args);
    }
}

编写 MybatisPlus 配置类

java 复制代码
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 {

    /**
     * 分页插件
     * 注:3.5.9版本,MyBatis-Plus 对分页插件做了拆分,需要单独引用mybatis-plus-jsqlparser依赖以支持PaginationInnerInterceptor类
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }
}

代码生成器:MybatisPlusGenerator

maven依赖

xml 复制代码
<!-- MyBatis-plus-generator 代码生成器 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>${mybatis-plus.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version>
</dependency>

代码生成器核心类

示例是将代码生成器集成到 Spring 环境中,部分配置参数放到了配置文件中。

  • 核心类

    java 复制代码
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.generator.FastAutoGenerator;
    import com.baomidou.mybatisplus.generator.config.OutputFile;
    import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
    import jakarta.annotation.PostConstruct;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
    import org.springframework.stereotype.Component;
    
    import java.util.Arrays;
    import java.util.Collections;
    
    /**
     * MyBatis-Plus代码生成器
     */
    @Component
    public class MybatisPlusGeneratorRunner {
        @Autowired
        private DataSourceProperties dbProp;
        @Autowired
        private MybatisPlusGeneratorProperties generatorProp;
    
        @PostConstruct
        public void run() {
            execute();
        }
    
        private void execute() {
            FastAutoGenerator
                    // 数据库配置
                    .create(dbProp.getUrl(), dbProp.getUsername(), dbProp.getPassword())
                    // 全局配置
                    .globalConfig((builder) -> {
                        // 设置注释信息-作者
                        builder.author(generatorProp.getAuthor());
                        // 设置swagger注解
                        //builder.enableSwagger();
                        // 设置代码生成的路径
                        builder.outputDir(generatorProp.getOutputDirRoot() + "/src/main/java");
                        // 完成后不打开文件夹
                        builder.disableOpenDir();
                        // 不生成service接口,但是依然会生成serviceImpl
                        //builder.disableServiceInterface();
                    })
                    // 包配置
                    .packageConfig((builder) -> {
                        // 设置父包路径
                        builder.parent(generatorProp.getPackagePath());
                        //设置xml文件路径
                        builder.pathInfo(Collections.singletonMap(OutputFile.xml,
                                generatorProp.getOutputDirRoot() + "/src/main/resources/mapper"));
                        // 设置实体类包名
                        builder.entity(generatorProp.getPackageEntity());
                        // 设置Mapper接口包名
                        //builder.mapper("mapper");
                        // 设置Service接口包名
                        //builder.service("service");
                        // 设置Service实现类包名
                        //builder.serviceImpl("service.impl");
                    })
                    // 策略配置
                    .strategyConfig((builder) -> {
                        // 指定表
                        builder.addInclude("all".equals(generatorProp.getDbTables()) ?
                                Collections.emptyList() : Arrays.asList(generatorProp.getDbTables().split(",")));
                        // controller的策略配置
                        builder.controllerBuilder()
                                // 启用rest风格
                                .enableRestStyle()
                                // 开启驼峰转连字符
                                .enableHyphenStyle()
                                // 禁用生成
                                .disable()
                                // 覆盖已有文件
                                //.enableFileOverride()
                                .build();
                        // service的策略配置
                        builder.serviceBuilder()
                                // 格式化service接口文件名称
                                .formatServiceFileName("%sService")
                                // 格式化service实现类文件名称
                                .formatServiceImplFileName("%sServiceImp")
                                // 禁用生成
                                .disable()
                                // 覆盖已有文件
                                //.enableFileOverride()
                                .build();
                        // entity的策略配置
                        builder.entityBuilder()
                                // 启用Lombok插件
                                .enableLombok()
                                // 启用表字段注解
                                .enableTableFieldAnnotation()
                                // 版本字段名称
                                .versionColumnName(generatorProp.getVersionColumnName())
                                // 逻辑删除字段名称
                                .logicDeleteColumnName(generatorProp.getLogicDeleteColumnName())
                                // 设置字段名的命名策略为下划线转驼峰命名
                                .columnNaming(NamingStrategy.underline_to_camel)
                                // 主键策略递增
                                .idType(IdType.ASSIGN_UUID)
                                // 格式化实体类名称
                                .formatFileName("%sEntity")
                                // 覆盖已有文件
                                //.enableFileOverride()
                                .build();
                        // mapper的策略配置
                        builder.mapperBuilder()
                                .enableBaseColumnList()
                                .enableBaseResultMap();
                    })
                    .execute();
        }
    }
  • 配置类

    java 复制代码
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.stereotype.Component;
    
    @Data
    @Component
    @RefreshScope
    @ConfigurationProperties(prefix = "mybatis-plus.generator")
    public class MybatisPlusGeneratorProperties {
        // 作者
        private String author = "blackcrow";
    
        // 代码生成的模块路径,例如:D:\IdeaProjects\open_multielement\user
        private String outputDirRoot;
        // 父包路径,例如:com.example.user
        private String packagePath;
        // 实体类包名,例如:entity
        private String packageEntity = "entity";
        // 表名,多个英文逗号分隔,所有输入 all
        private String dbTables;
    
        // 版本字段名称
        private String versionColumnName = "version";
        // 逻辑删除字段名称
        private String logicDeleteColumnName = "is_delete";
    }
相关推荐
u01005596015 小时前
MySQL 中的左连接查询(LEFT JOIN)是一种 SQL 连接操作
java·数据库·mybatis
武子康19 小时前
Java-16 深入浅出 MyBatis - SqlSession Executor StatementHandler 源码分析
java·开发语言·mysql·mybatis·springboot
你疯了抱抱我20 小时前
【自用】管材流转项目后端重部署流程 SpringBoot MyBatis PLUS
spring boot·后端·mybatis
zxguan1 天前
Mybatis 学习 之 XML 手册
xml·学习·mybatis
云初@1 天前
MyBatis动态SQL处理增删改查
数据库·sql·mybatis
深情废杨杨2 天前
后端-mybatis的一对多
java·spring boot·mybatis
爱上语文2 天前
数据库多表设计
java·开发语言·数据库·后端·mybatis
计算机学姐2 天前
基于SpringBoot+Vue的美妆购物网站
java·vue.js·spring boot·后端·mysql·spring·mybatis
计算机学姐2 天前
基于SpringBoot的汽车销售网站
java·spring boot·后端·mysql·汽车·intellij-idea·mybatis