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.properties 或 application.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 中引用实体类时需要使用全限定名 
分页插件配置类
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:指定实体类对应的数据库表名 - 
说明:如果实体类的名称与数据库表名在命名上保持一致(即遵循驼峰转下划线的命名规则),则此注解不是必需的。但如果命名不一致,则需要使用此注解来明确指定表名。 
- 
示例: @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)等。
 
- 
示例: @TableId(value = "id", type = IdType.AUTO) private Long id;
 
- 
- 
@TableField:指定实体类中的普通字段与数据库表字段之间的映射关系 - 
说明:如果实体类的字段名与数据库表的字段名在命名上保持一致(即遵循驼峰转下划线的命名规则),则此注解不是必需的。但如果字段名不一致,或者字段名与数据库的关键字冲突,或者需要处理成员变量以 is开头且是布尔值的情况,则需要使用此注解。
- 
属性: - 
value:字段名。
- 
exist:字段是否存在,默认为true。如果实体类中有一些字段不需要映射到数据库表中,则可以设置为 false
- 
fill:字段填充策略,可选值有FieldFill.INSERT(插入时填充)、FieldFill.UPDATE(更新时填充)等。
 
- 
- 
示例: @TableField(value = "name", fill = FieldFill.INSERT) private String name;
 
- 
- 
@TableLogic:指定逻辑删除字段 - 
属性: - value:字段名。
- delval:删除标记值。
- undelval:未删除标记值。
 
- 
示例: @TableLogic(value = "0", delval = "1") private Integer deleted;
- 
是否必需:如果需要使用逻辑删除功能,则必须使用此注解。 
 
- 
- 
@Version:指定乐观锁字段 - 
示例: @Version private Integer version;
- 
是否必需:如果需要使用乐观锁功能,则必须使用此注解。 
 @KeySequence:指定 Oracle 数据库的序列 - 
属性: - value:序列名。
 
- 
示例: @TableId(type = IdType.SEQUENCE, value = "user_seq") private Long id;
- 
是否必需:如果使用 Oracle 数据库的序列生成主键,则必须使用此注解。 
 @Transient:指定不持久化的字段 - 
示例: @Transient private String tempField;
- 
是否必需:如果实体类中有一些临时字段不需要持久化到数据库,则可以使用此注解。 
 
- 
快速入门
maven 依赖
<!-- 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
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
编写启动类
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 配置类
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依赖
<!-- 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 环境中,部分配置参数放到了配置文件中。
- 
核心类 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(); } }
- 
配置类 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"; }
- 点赞
- 收藏
- 关注作者
 
             
           
评论(0)