MybatisPlus插件

发布于 2021-12-16  6.86k 次阅读


MybatisPlus插件:

  1. 代码生成器
  2. 分页插件
  3. 执行分析插件SqlExplainInteerceptor
  4. 性能分析插件PerformanceInterceptor
  5. 自动填充
  6. 逻辑删除
  7. 通用枚举
  8. ……

一,MybatisPlus分页

MybatisPlus的分页比Mybatis简单许多

MybatisPlus不需要导入pagehelper依赖,它自己写了有分页组件跟pagehelper不太一样,功能也很强大

一,分页的简单使用

MybatisPlus和Mybatis的分页功能是一样的,但底层实现是不一样的,MybatisPlus的分页是它们自己开发的已经嵌入到了MybatisPlus,而Mybatis的分页是第三方开发的,需要进行依赖导入

步骤:

  • 配置分页
  • 使用分页

1,配置分页:

@Configuration
public class page_config  {

    @Bean//配置分页
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }}

2,使用分页:

① pojo类

@Data
@ToString
@TableName("mybatistest")
public class activerecord_pojo{
    @TableId(type = IdType.AUTO)
    int id;
    String name;
    int sex;
    int age;
}

② 映射接口

public interface mybatisplus_mapper extends BaseMapper<mybatisplus_pojo> {

    @Override
    <E extends IPage<mybatisplus_pojo>> E selectPage(E page, @Param("ew")Wrapper<mybatisplus_pojo> queryWrapper);
}

③ 测试

@Test
void selectpage() {
   //设置分页对象Page
   Page<mybatisplus_pojo> pojoPage = new Page<>(1,1);
   //设置条件查询
   QueryWrapper<mybatisplus_pojo> queryWrapper = new QueryWrapper<>();
   queryWrapper.like("name","da");
   //分页查询并获取分页查询对象
   Page<mybatisplus_pojo> pojoPage1 = mapper.selectPage(pojoPage, queryWrapper);

   System.out.println("查询的总页数:"+pojoPage1.getPages());
   System.out.println("查询的总条数:"+pojoPage1.getTotal());
   System.out.println("当前页数:"+pojoPage1.getCurrent());

   //通过分页查询对象获取当前页的数据
   List<mybatisplus_pojo> records = pojoPage1.getRecords();
   for(mybatisplus_pojo m :records){
      System.out.println(m);
   }
}

④ 结果

二,Page对象

Page对象是Mybatispuls为实现分页提供的对象

它的类图:

Page的构造:

  • Page(long current, long size, long total)
  • Page(long current, long size)
  • ……

Page的构造参数:

  • current:当前页
  • size:指定一页有多少条数据
  • total:指定总页数(这个无需指定)

Page的方法:

  • hasNext:判断是否有下一页
  • getRecords:将当前页数据转化为list数据并返回
  • setRecords:将list数据传入page对象
  • getTotal:获取总页数
  • setTotal:设置总页数
  • getSize:获取每一页的数据量
  • setSize:设置每一页的数据量
  • getCurrent:获取当前页
  • setCurrent:设置当前页
  • ……具体可以看它的源码,设置还要很多,我例举的只是常用的

二,MybatisPlus代码生成器

MybatPlus的代码生成器和Mybatis的逆向工程功能一样,都是负责把数据库表转化为Mapper,pojo等

MybatisPlus代码生成器和Mybatis Generator逆向工程对比:

  • MP代码生成器基于java代码来实现,Mybatis Generator基于XML实现
  • Mybatis Generator可生成:实体类,mapper接口,mapper映射文件
  • MP代码生成器:实体类,mapper接口,mapper映射文件,Service层,Controller层
  • MP代码生产器的功能比MBG的功能更加强大

表及字段的策略选择(只是选择):

  • 在MP中,建议数据库表名和表字段名采用驼峰命名方式,如果下划线命名方式,需要开启全局下划线配置,如果表名字段命名方式不一用@TableName和@TbaleField修改即可
  • 上述策略的原因是为了避免在产生对应实体类时性能耗损,这样字段不用做映射就能直接和实体类对应

在MP的官方文件提供两个版本的代码生成器,3.5.1版本之前的历史版本和3.5.1之后的新版本

一,MP生成器的使用(历史版本)

导入依赖:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.1</version>
</dependency>

生产器需要除了依赖还需要导入模板引擎:它提供了三种模板引擎

  • Velocity(默认)
  • FreeMaker
  • Beetl

① Velocity

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version>
</dependency>

② FreeMaker

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.31</version>
</dependency>

③ Beetl

<dependency>
    <groupId>com.ibeetl</groupId>
    <artifactId>beetl</artifactId>
    <version>3.9.0.RELEASE</version>
</dependency>

MP代码生产器的编写分为5个部分:

  1. 全局部分:GlobalConfig
  2. 数据源部分:DataSourceConfig
  3. 策略部分:StrategyConfig
  4. 包名策略部分:PackageConfig
  5. 整合部分:AutoGenerator

注:除了AutoGenerator这些类在com.baomidou.mybatisplus.generator.config包下,注意别导错

GlobalConfig的方法:

  • setActiveRecord():是否AR模式
  • setAuthor():设置作者
  • setOutputDir():生成工程的路径
  • setFileOverride():是否文件覆盖
  • setIdType():设置主键策略
  • setBaseResultMap():是否开启即可的ResultMap
  • setBaseColumnList():是否生成表的列集合
  • setEnableCache():是否开启缓存
  • ……
DataSourceConfig的方法:
  • setDbType():设置数据库的类型
  • setUsername():用户名
  • setPassword("123") : 设置数据库密码
  • setUrl():设置url
  • setDriverName():数据库驱动
  • ……
StrategyConfig的方法:
  • setCapitalMode():是否全局大写命名
  • setTablePrefix():生成表的前缀
  • setNaming():数据库表映射到实体类的命名策略
  • setInclude():需要生成的表名
  • ……
PackageConfig的方法:
  • setParent():设置父包路径
  • setEntity():实体类的包名
  • setMapper():设置mapper接口包名
  • setXml():这是接口的映射文件,包名和接口一样
  • setServiceImpl():service接口文件
  • setService():server文件
  • setController():controller文件包名
  • ……
AutoGenerator的方法:
  • setGlobalConfig():加入全局配置
  • a.setDataSource():加入数据源
  • a.setPackageInfo():加入包配置
  • a.setStrategy():加入策略配置
  • execute():执行
  • ……
例:
① 代码生成
@SpringBootTest
public class testgenerator {


    @Test
    void generator(){
        //全局部分
        GlobalConfig gc = new GlobalConfig();
        gc.setActiveRecord(true);//是否AR模式
        gc.setAuthor("WQL");//设置作者
        gc.setOutputDir("C:\\Users\\wql\\Desktop\\fq");//生成工程的路径


        //数据源部分
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDbType(DbType.MYSQL);//设置数据库的类型
        dataSourceConfig.setUsername("root");//用户名
        dataSourceConfig.setPassword("123");;//设置数据库密码
        dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/wql");//url
        dataSourceConfig.setDriverName("com.mysql.jdbc.Driver");//数据库驱动


        //策略部分
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setCapitalMode(true);//是否全局大写命名
        strategyConfig.setTablePrefix("wql_");//生成表的前缀
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体类的命名策略
        strategyConfig.setInclude("bm");//需要生成的表名


        //包名策略部分
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setParent("com.generator");//设置父包路径
        packageConfig.setEntity("pojo");//实体类的包名
        packageConfig.setMapper("mapper");//设置mapper接口包名
        packageConfig.setXml("mapper");//这是接口的映射文件,包名和接口一样
        packageConfig.setServiceImpl("service");//service接口文件
        packageConfig.setService("service");//server文件
        packageConfig.setController("controller");//controller文件包名

        //整合部分并运行
        AutoGenerator a = new AutoGenerator();
        a.setGlobalConfig(gc);//加入全局配置
        a.setDataSource(dataSourceConfig);//加入数据源
        a.setPackageInfo(packageConfig);//加入包配置
        a.setStrategy(strategyConfig);//加入策略配置


        a.execute();//执行
    }}

② 生成结果

二,MP生成器的使用(新版本3.5.1+

新版本对老版本的代码进行了重构,但功能基本没有变,新版本使用了大量的创建者模式提供Builder进行对象的构建

Maven依赖:

新版本和老版本API基本没有变,只是写法改变了,具体配置去官方文档看

文档地址:mp.baomidou.com/guide/generator-new.html#%E5%AE%89%E8%A3%85

例:

FastAutoGenerator.create("url", "username", "password")
        .globalConfig(builder -> {
                builder.author("baomidou") // 设置作者
            .enableSwagger() // 开启 swagger 模式
                        .fileOverride() // 覆盖已生成文件
                        .outputDir("D://"); // 指定输出目录
        })
        .packageConfig(builder -> {
                builder.parent("com.baomidou.mybatisplus.samples.generator") // 设置父包名
                        .moduleName("system") // 设置父包模块名
            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D://")); // 设置mapperXml生成路径
        })
        .strategyConfig(builder -> {
                builder.addInclude("t_simple") // 设置需要生成的表名
                        .addTablePrefix("t_", "c_"); // 设置过滤表前缀
        })
        .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
        .execute();}

三,MybatisPlus通用枚举

枚举对某些特定值的操作很方便,比如在表性别字段上,一般使用数字代替,在插入和更新时都需要填写,可以把这些常量封装导enum

步骤:

  • 新建枚举类,标注数据库存的值是那个属性
  • POJO类,使用通用枚举,返回值也要是enum
  • 配置枚举类包的位置
  • 使用枚举进行操作

通过枚举属性:数据库具体要存的是枚举的那个属性

1,创建枚举类并声明通用枚举属性

方式一: 使用 @EnumValue 注解枚举属性

例:

public enum GradeEnum {


    PRIMARY(1, "小学"),  SECONDORY(2, "中学"),  HIGH(3, "高中");


    GradeEnum(int code, String descp) {
        this.code = code;
        this.descp = descp;
    }


    @EnumValue//标记数据库存的值是code
    private final int code;
    //。。。
}

方式二: 枚举属性,实现 IEnum 接口

例:

public enum AgeEnum implements IEnum<Integer> {
    ONE(1, "一岁"),
    TWO(2, "二岁"),
    THREE(3, "三岁");


    private int value;
    private String desc;


    @Override
    public Integer getValue() {
        return this.value;
    }
}

2,配置枚举包位置

mybatis-plus:
  type-enums-package: 包位置信息

例:以表中sex字段为例,使用通过枚举进行查询和删除

① 新建enum类并标注通用枚举属性

@ToString
public enum myenum implements IEnum<Integer> {
    NAN(0,"男"),
    NV(1,"女");


    private int num;
    private String sex;


    myenum(int num, String sex) {
        this.num = num;
        this.sex = sex;
    }
    
    @Override
    public Integer getValue() {
        return this.num;
    }
}

② pojo类

@Data
@ToString
@TableName("mybatistest")
public class mybatisplus_pojo {
    @TableId(type = IdType.AUTO)
    int id;
    @TableField(fill = FieldFill.INSERT)
    String name;
    myenum sex;
    int age;
    int deleteid;
}

③ 配置枚举包的位置

mybatis-plus:
  type-enums-package: com.example.springboot_mybatisplus_dome.myenum

④ 实现插入

@SpringBootTest
class SpringbootMybatisplusDomeApplicationTests {

   @Autowired
   mybatisplus_mapper mapper;

   @Test
   void insert(){
      mybatisplus_pojo mybatisplusPojo = new mybatisplus_pojo();
      mybatisplusPojo.setAge(20);
      mybatisplusPojo.setName("lalala");
      //使用枚举进行设置
      mybatisplusPojo.setSex(myenum.NAN);
      int insert = mapper.insert(mybatisplusPojo);
      if(insert!=0){
         System.out.println("插入数据成功!:"+mybatisplusPojo.getId());
      }else {
         System.out.println("插入数据失败!");
      }
   }

⑤ 实现查询

@Test
void selectlist() {
   QueryWrapper<mybatisplus_pojo> queryWrapper = new QueryWrapper<>();
   queryWrapper.eq("sex",myenum.NAN);


   List<mybatisplus_pojo> mybatisplus_pojos = mapper.selectList(queryWrapper);
   for(mybatisplus_pojo m :mybatisplus_pojos){


      System.out.println(m);
   }
}

四,MybatisPlus逻辑查询

逻辑删除就是将数据标记为删除状态,而并非真正删除数据库中的数据,查询时需要携带状态条件,在开发中,实现某个功能时,不想真正删除物理数据可以这样操作

逻辑删除的基本概念:使用标记方式,需要删除时将数据标记为删除,不删除数据库中的物理数据

逻辑删除需要修改表结构,为表增加一个deleteid(名字任意)的字段

MP实现逻辑删除的步骤:

  1. 在表中添加一个逻辑删除的字段
  2. 在创建POJO实体类时,在逻辑删除字段添加一个@TableLogic
  3. 在配置文件中配置已删除数据和未删除数据对应的值(如:字段值0表示删除,字段值未1表示正常)

例:

① 在表中添加逻辑删除字段

② POJO类

@Data
@ToString
@TableName("mybatistest")
public class mybatisplus_pojo {
    @TableId(type = IdType.AUTO)
    int id;
    @TableField(fill = FieldFill.INSERT)
    String name;
    int sex;
    int age;
    @TableLogic//标记逻辑删除字段
    int deleteid;
}

③配置

mybatis-plus:
  global-config:
    db-config:
      logic-delete-value: 1 #已删除字段值为1
      logic-not-delete-value: 0 #正常,字段值为2

④ 删除测试

@SpringBootTest
class SpringbootMybatisplusDomeApplicationTests {

   @Autowired
   mybatisplus_mapper mapper;

   @Test
   void deleteid(){

      int i = mapper.deleteById(2);
      System.out.println(i);
   }}

⑤ 结果

五,MyBatisPlus自动填充功能

有些时候我们可能会有这样的需求,插入或者更新数据时,希望有些字段可以自动填充数据,比如密码,version等,在MP中提供了这样的功能,可以实现自动填充

实现步骤:

  • 使用@TableField注解进行标注
  • 实现MetaObjectHandler接口对标注字段进行填充

自动填充依赖于@TableField和它的Fill属性,假如需要字段填充,就把注解标准在那个属性字段上面

FieldFill:

  • DEFAULT:默认值,不进行填充
  • INSERT:插入操作填充
  • UPDATE:更新操作填充
  • INSERT_UPDATE:插入和更新填充

需要实现MetaObjectHandler接口:

  • insertFill(MetaObject metaObject):插入填充方法
  • updateFill(MetaObject metaObject):更新填充方法

例:

① POJO

@Data
@ToString
@TableName("mybatistest")
public class mybatisplus_pojo {
    @TableId(type = IdType.AUTO)
    int id;
    @TableField(fill = FieldFill.INSERT)
    String name;
    int sex;
    int age;
}

② MetaObjectHandler接口

@Component//需要将它放入容器中
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        //获取被标注字段属性的值
        Object name = getFieldValByName("name", metaObject);
        //判断是否为空
        if(name==null){
            //对字段进行填充
            setFieldValByName("name","GUN",metaObject);
        }
    }
    @Override
    public void updateFill(MetaObject metaObject) {

    }}

③ 测试(插入操作不加name属性)

@Test
void insert(){
   mybatisplus_pojo mybatisplusPojo = new mybatisplus_pojo();
   mybatisplusPojo.setAge(20);
   mybatisplusPojo.setSex(0);
   int insert = mapper.insert(mybatisplusPojo);
   if(insert!=0){
      System.out.println("插入数据成功!:"+mybatisplusPojo.getId());
   }else {
      System.out.println("插入数据失败!");
   }
}

④ 结果

六,SqlExplainInteerceptor执行分析插件

SqlExplainInteerceptor是MP中提供了对SQL执行的分析插件,它可以阻断全表更新,删除的操作

SqlExplainInteerceptor的作用:防止用户的不安全操作(例如全表的删除等)

注:该插件仅适合于开发环境,不适合于生成环境

配置SqlExplainInteerceptor执行解析器:

@Configuration
@MapperScan(basePackages = "com.example.springboot_mybatisplus_dome.dao.mapper")
public class page_config  {

    @Bean//配置执行分析插件
    public SqlExplainInterceptor sqlExplainInterceptor(){
        //创建SQL执行解析器
        SqlExplainInterceptor sqlExplainInterceptor = new SqlExplainInterceptor();
        List<ISqlParser> sqlParserList = new ArrayList<>();
        //攻击SQL,阻断解析器
        sqlParserList.add(new BlockAttackSqlParser());
        sqlExplainInterceptor.setSqlParserList(sqlParserList);
        return sqlExplainInterceptor;
    }
}

例:执行一个全表更新

① 全表更新

@Test
void updatewrapper(){
   int update = mapper.update(null,null);
   System.out.println(update);
}

② 结果

七,PerformanceInterceptor性能分析插件

PerformanceInterceptor性能分析插件,用于输出每条SQL语句及其执行的时间,可以设置最大执行时间,超过时间就会抛出异常

注:和执行分析插件一样也只适合于开发环境,不适合生产环境

配置:

@SpringBootApplication
@MapperScan("com.aiyi.springbootplus.dao")
public class SpringbootPlusApplication {
  /**
* SQL执行效率插件
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
    PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
    return new PerformanceInterceptor();
}
}

如果该性能分析插件是3.2.0 以上版本移除推荐使用第三方扩展 执行 SQL 分析打印 功能

@SpringBootApplication
@MapperScan("com.aiyi.springbootplus.dao")
public class SpringbootPlusApplication {
/**
* SQL执行效率插件
*/
@Bean
public PerformanceInterceptor performanceInterceptor() {
    PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
    // maxTime 指的是 sql 最大执行时长
    performanceInterceptor.setMaxTime(5000);
    //SQL是否格式化 默认false
    performanceInterceptor.setFormat(true);
    return new PerformanceInterceptor();
}
}

执行一段查询:

八,MybatisX快速开发插件

MybatisX是一款基于IDEA的快速开发的插件,为效率而生

安装步骤:进入IDEA --> Setting --> Plugins --> Marketolace --> 输入MybatisX搜索并安装

MybatisX可实现的功能:

  • java和xml文件的调用跳转
  • Mapper方法的自动生成

自动生成代码:可视化执行Mybatisplus代码生成器:

  • 选中需要自动生成实体类、XxxMapper.java、XxxService.java、XxxServiceImpl.java及XxxMapper.xml文件的表--->右击--->选择MybatisX-Generator


路漫漫其修远兮,吾将上下而求索