SpringBoot整合Mybatis Plus(超详细)一篇就够了~~

简介:

官网文档地址

Mybatis-Plus特性:

  • 无侵入:Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做增强不做改变,引入 Mybatis-Plus 不会对您现有的 Mybatis 构架产生任何影响,而且 MP 支持所有 Mybatis 原生的特性
  • 依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 预防Sql注入:内置 Sql 注入剥离器,有效预防Sql注入攻击
  • 通用CRUD操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题
  • 支持热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
  • 支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
  • 支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S. 比 Mybatis 官方的 Generator 更加强大!)
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 支持关键词自动转义:支持数据库关键词(order、key…)自动转义,还可自定义关键词
  • 内置分页插件:基于 Mybatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作
实现过程:
  1. maven依赖
<properties>
    <java.version>1.8</java.version>
    <lombok.version>1.16.18</lombok.version>
    <fastjson.version>1.2.39</fastjson.version>
    <mysql.connector.version>8.0.16</mysql.connector.version>
    <mybatis-plus-version>3.1.0</mybatis-plus-version>
    <druid-version>1.0.29</druid-version>
</properties>


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <scope>provided</scope>
    <version>${lombok.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
<!--Json-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>${fastjson.version}</version>
</dependency>
<!--使用Mysql数据库-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql.connector.version}</version>
</dependency>

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

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>${mybatis-plus-version}</version>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>${druid-version}</version>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>${velocity-version}</version>
</dependency>
<!--swagger2 集成-->
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>${swagger2-version}</version>
</dependency>
  1. application.yml配置
server:
  port: 8081
  tomcat:
    uri-encoding: UTF-8
    max-http-post-size: -1
spring:
  application:
    name: blog
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/blog?useUnicode=yes&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2b8
    driverClassName: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
    # 配置druid数据库连接池---------------------------------------
    initialSize: 5        # 初始化大小,最小,最大
    minIdle: 5
    maxActive: 20
    maxWait: 60000        # 配置获取连接等待超时的时间
    timeBetweenEvictionRunsMillis: 60000  # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    minEvictableIdleTimeMillis: 300000    # 配置一个连接在池中最小生存的时间,单位是毫秒
    validationQuery: SELECT 'x'           # 校验SQL,Oracle配置 spring.datasource.validationQuery=SELECT 1 FROM DUAL,如果不配validationQuery项,则下面三项配置无用
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true   # 打开PSCache,并且指定每个连接上PSCache的大小
    maxPoolPreparedStatementPerConnectionSize: 20
    filters: stat,wall,log4j       # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000  # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    useGlobalDataSourceStat: true  # 合并多个DruidDataSource的监控数据

# 配置mybatis-plus的xml和bean的目录
mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:  #逻辑删除配置
    db-config:
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
    refresh-mapper: true # 刷新mapper 调试神器

  1. 接下来我们来进行mybatis-plus的配置
package com.blog.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.util.Date;

/**
 * @author LiWT
 * @Date 2020-12-04
 */
@EnableTransactionManagement
@Configuration
@MapperScan("com.blog.mapper")
public class MybatisPlusConfig implements MetaObjectHandler {

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("isDeleted", false, metaObject);
        this.setFieldValByName("createId", "1", metaObject);
        this.setFieldValByName("createName", "创建人姓名", metaObject);
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateId", "2", metaObject);
        this.setFieldValByName("updateName", "更新人姓名", metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateId", "2", metaObject);
        this.setFieldValByName("updateName", "更新人姓名", metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }

    @Bean
    public ISqlInjector sqlInjector() {
        return new LogicSqlInjector();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }

    /**
     * 配置监控服务器
     *
     * @return 返回监控注册的servlet对象
     */
    @Bean
    public ServletRegistrationBean<StatViewServlet> statViewServlet() {
        ServletRegistrationBean<StatViewServlet> servletRegistrationBean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
        // 添加IP白名单
//        servletRegistrationBean.addInitParameter("allow", "127.0.0.1");
        // 添加IP黑名单,当白名单和黑名单重复时,黑名单优先级更高
//        servletRegistrationBean.addInitParameter("deny", "127.0.0.1");
        // 添加控制台管理用户
        servletRegistrationBean.addInitParameter("loginUsername", "blog_admin");
        servletRegistrationBean.addInitParameter("loginPassword", "43kqZ$WG");
        // 是否能够重置数据
        servletRegistrationBean.addInitParameter("resetEnable", "false");
        return servletRegistrationBean;
    }
}
  • paginationInterceptor()用于配置MybatisPlus分页插件
  • insertFill()方法用于自动填充数据,创建人/修改人ID、姓名这些数据可以从JWT中获取用户真实数据填入
  • updateFill()方法用于更新数据时自动填充修改人ID、姓名数据
  • statViewServlet()配置sql监控服务器,可以监控sql执行情况及查询情况,但是生产环境建议不要开启;其中的loginUsername与loginPassword用于登录监控服务器
  1. 启动类上需要使用@MapperScan(“com.blog.mapper.*”)配置扫描Mapper的路径

  2. 最后贴上MybatisPlus最好用的结构生成器,从Entity -> Mapper -> Mapper.xml -> Service -> ServiceImpl -> Controller层结构全部自动生成,究极好用

package com.blog.utils;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

/**
 * mybatis-plus自动生成代码工具类
 *
 * @author LiWT
 * @date 2020-12-04
 */
public class Generator {

    @Data
    static class ConfigureParams {
        private String auth;
        private String packageName;
        private String path;
        private String url;
        private String username;
        private String password;
        private String driverName;
        private String[] tablePrefix;
        private String logicDeleteFieldName;
        private String[] include;
        private String controllerPackage;
        private String entityPackage;
        private String mapperPackage;
        private String xmlPackage;
        private String[] autoFillInsertAndUpdate;
        private String[] autoFillInsert;

        public ConfigureParams(String auth, String packageName, String path, String url, String username, String password, String driverName, String[] tablePrefix, String logicDeleteFieldName, String[] include, String controllerPackage, String entityPackage, String mapperPackage, String xmlPackage, String[] autoFillInsertAndUpdate, String[] autoFillInsert) {
            this.auth = auth;
            this.packageName = packageName;
            this.path = path;
            this.url = url;
            this.username = username;
            this.password = password;
            this.driverName = driverName;
            this.tablePrefix = tablePrefix;
            this.logicDeleteFieldName = logicDeleteFieldName;
            this.include = include;
            this.controllerPackage = controllerPackage;
            this.entityPackage = entityPackage;
            this.mapperPackage = mapperPackage;
            this.xmlPackage = xmlPackage;
            this.autoFillInsertAndUpdate = autoFillInsertAndUpdate;
            this.autoFillInsert = autoFillInsert;
        }
    }

    /**
     * 生成代码直接运行该main方法即可,注意需修改一些配置信息
     * auth://创建人
     * packageName://包前缀
     * path://项目路径
     * url://数据库连接地址xxx.xxx.x.xxx:端口/数据库名称
     * username://数据库连接用户名
     * password://数据库连接密码
     * driverName://数据库驱动
     * tablePrefix://生成的实体类去掉前缀,可以配置多个
     * logicDeleteFieldName://逻辑删除属性名称
     * include://要生成代码的表名,多个表名用英文逗号分割  ".*." 生成全部
     * controllerPackage://controller包名
     * entityPackage://实体类包名
     * mapperPackage://mapper包名
     * xmlPackage://xml包名
     * autoFillInsertAndUpdate://表中新增或修改时需自动填充的字段
     * autoFillInsert://表中新增时需自动填充的字段
     */
    public static void main(String[] args) {

        String auth = "LiWT";
        String packageName = "com.blog";
        String path = "D:\\Projects\\blog\\src\\main\\java";
        String url = "127.0.0.1:3306/blog";
        String username = "root";
        String password = "root";
        String driverName = "com.mysql.cj.jdbc.Driver";
        String[] tablePrefix = new String[]{"sys_", "usc_"};
        String logicDeleteFieldName = "is_deleted";
        String[] include = new String[]{".*."};
        String controllerPackage = "controller";
        String entityPackage = "entity";
        String mapperPackage = "mapper";
        String xmlPackage = "classpath:mapper";
        String[] autoFillInsertAndUpdate = new String[]{"update_id", "update_name", "update_time"};
        String[] autoFillInsert = new String[]{"create_id", "create_name", "create_time"};
        ConfigureParams configureParams = new ConfigureParams(auth, packageName, path, url, username, password, driverName,
                tablePrefix, logicDeleteFieldName, include, controllerPackage, entityPackage, mapperPackage, xmlPackage, autoFillInsertAndUpdate, autoFillInsert);

        //加载配置信息并执行
        generate(configureParams);
    }

    private static void generate(ConfigureParams configureParams) {
        //******************************全局配置******************************//
        GlobalConfig config = new GlobalConfig();
        //设置是否支持AR模式
        config.setActiveRecord(true)
                //设置生成代码的作者
                .setAuthor(configureParams.getAuth())
                //设置输出代码的位置
                .setOutputDir(configureParams.getPath())
                // XML 二级缓存
                .setEnableCache(false)
                // XML ResultMap
                .setBaseResultMap(true)
                // XML columList
                .setBaseColumnList(true)
                //.setKotlin(true) 是否生成 kotlin 代码
                // 是否使用Swagger2
                .setSwagger2(true)
                // 设置是否覆盖原来的代码
                .setFileOverride(false);

        //******************************数据源配置******************************//
        //数据库连接url
        String dbUrl = "jdbc:mysql://" + configureParams.getUrl() + "?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC";
        //数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        //数据库类型 枚举
        dataSourceConfig.setDbType(DbType.MYSQL)
                //设置url
                .setUrl(dbUrl)
                //设置用户名
                .setUsername(configureParams.getUsername())
                //设置密码
                .setPassword(configureParams.getPassword())
                //设置数据库驱动
                .setDriverName(configureParams.getDriverName())
                // 自定义数据库表字段类型转换【可选】
                .setTypeConvert(new MySqlTypeConvert() {
                    @Override
                    public DbColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
                        System.out.println("转换类型:" + fieldType);
                        //将数据库中datetime转换成date
                        if (fieldType.toLowerCase().contains("datetime")) {
                            return DbColumnType.DATE;
                        }
                        return (DbColumnType) super.processTypeConvert(globalConfig, fieldType);
                    }
                });

        //******************************策略配置******************************//
        // 自定义需要填充的字段 数据库中的字段
        List<TableFill> tableFillList = new ArrayList<>();
        for (String autoFillName : configureParams.getAutoFillInsertAndUpdate()) {
            tableFillList.add(new TableFill(autoFillName, FieldFill.INSERT_UPDATE));
        }
        for (String autoFillName : configureParams.getAutoFillInsert()) {
            tableFillList.add(new TableFill(autoFillName, FieldFill.INSERT));
        }

        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig
                //全局大写命名是否开启
                .setCapitalMode(true)
                //【实体】是否为lombok模型
                .setEntityLombokModel(true)
                //表名生成策略  下划线转驼峰
                .setNaming(NamingStrategy.underline_to_camel)
                //生成的去掉前缀,可以配置多个
                .setTablePrefix(configureParams.getTablePrefix())
                //自动填充设置
                .setTableFillList(tableFillList)
                //逻辑删除属性名称
                .setLogicDeleteFieldName(configureParams.getLogicDeleteFieldName())
                .setRestControllerStyle(true)
                //要生成代码的表名
                .setInclude(configureParams.getInclude());
        //集成注入设置 注入全局设置
        new AutoGenerator().setGlobalConfig(config)
                //注入数据源配置
                .setDataSource(dataSourceConfig)
                //注入策略配置
                .setStrategy(strategyConfig)
                //设置包名信息
                .setPackageInfo(
                        new PackageConfig()
                                //提取公共父级包名
                                .setParent(configureParams.getPackageName())
                                //设置controller信息
                                .setController(configureParams.getControllerPackage())
                                //设置实体类信息
                                .setEntity(configureParams.getEntityPackage())
                                //设置mapper信息
                                .setMapper(configureParams.getMapperPackage())
                                .setXml(configureParams.getXmlPackage())
                )
                //设置自定义模板
                .setTemplate(
                        new TemplateConfig()
                                //.setXml(null)//指定自定义模板路径, 位置:/resources/templates/entity2.java.ftl(或者是.vm)
                                //注意不要带上.ftl(或者是.vm), 会根据使用的模板引擎自动识别
                                // 自定义模板配置,模板可以参考源码 /mybatis-plus/src/main/resources/template 使用 copy
                                // 至您项目 src/main/resources/template 目录下,模板名称也可自定义如下配置:
                                // .setController("...");
                                // .setEntity("...");
                                // .setMapper("...");
                                // .setXml("...");
                                // .setService("...");
                                .setServiceImpl("templates/serviceImpl.java")
                )
                //开始执行代码生成
                .execute();
    }
}

该Generator需要配置几个关键信息,然后直接执行main方法即可快速生成代码

  • packageName://包前缀(com.xxx.xxx)
  • path://项目路径(该路径需要copy到java层,如果使用IDEA编辑器的话直接选中java文件夹右键 -> Copy Path -> Absolute Path 即可)
  • url://数据库连接地址xxx.xxx.x.xxx:端口/数据库名称 (该项配置数据库连接地址 IP:Port/数据库名称)
  • username://数据库连接用户名
  • password://数据库连接密码
  • driverName://数据库驱动 (写死com.mysql.cj.jdbc.Driver即可,无需修改)
  • tablePrefix://生成的实体类去掉前缀,可以配置多个(该项为数据库表名前缀,生成代码时会根据该项配置自动去掉前缀)
  • logicDeleteFieldName://逻辑删除属性名称(该项为数据库表逻辑删除字段名,在调用mybatis-plus删除接口时会根据application.yml中的逻辑删除配置自动填充值)
  • include://要生成代码的表名,多个表名用英文逗号分割 (".*." 生成全部)
  • controllerPackage://controller包名(controller层要生成代码的包名,与上方packageName合起来即为生成controller代码的路径)
  • entityPackage://实体类包名(entity层要生成代码的包名,与上方packageName合起来即为生成entity代码的路径)
  • mapperPackage://mapper包名(mapper层要生成代码的包名,与上方packageName合起来即为生成mapper代码的路径)
  • xmlPackage://xml包名(resources下存放xml文件的包名)
  1. 创建mysql数据库及表
CREATE TABLE `usc_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `account` varchar(60) NOT NULL COMMENT '账号',
  `name` varchar(60) DEFAULT NULL COMMENT '名字',
  `nick_name` varchar(255) DEFAULT NULL COMMENT '昵称',
  `password` varchar(60) NOT NULL COMMENT '密码',
  `password_date` datetime DEFAULT NULL COMMENT '密码设置日期',
  `address` varchar(512) DEFAULT NULL COMMENT '地址',
  `birthday` datetime DEFAULT NULL COMMENT '生日',
  `sex` varchar(60) DEFAULT NULL COMMENT '性别',
  `mobile` varchar(60) DEFAULT NULL COMMENT '手机',
  `email` varchar(60) DEFAULT NULL COMMENT '邮箱',
  `comment` varchar(512) DEFAULT NULL COMMENT '用户备注',
  `picture` varchar(255) DEFAULT NULL COMMENT '图片',
  `org_id` bigint(20) DEFAULT '1' COMMENT '所属组织机构ID',
  `join_date` datetime DEFAULT NULL COMMENT '入职时间',
  `create_id` bigint(20) DEFAULT NULL COMMENT '创建人id',
  `update_id` bigint(20) DEFAULT '0' COMMENT '修改人id',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `create_name` varchar(60) DEFAULT NULL COMMENT '创建人姓名',
  `update_name` varchar(60) DEFAULT NULL COMMENT '最后修改人姓名',
  `is_deleted` tinyint(1) DEFAULT '0' COMMENT '是否删除(0:未删除,1:已删除)',
  `status` int(2) DEFAULT NULL COMMENT '状态',
  `fail_num` int(11) DEFAULT '0' COMMENT '登录失败次数',
  `idcard_number` varchar(40) DEFAULT NULL COMMENT '用户身份证号',
  PRIMARY KEY (`id`),
  UNIQUE KEY `UNI_ACCOUNT` (`account`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='用户中心-用户信息表';
  1. 执行上边生成代码,然后我们在Service中写一个方法实验一下
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

可以看到MybatisPlus自带的方法我们就都可以使用了,它还自带了QueryWrapper、LambdaQueryWrapper等条件查询器,使单表的查询更加方便了,具体使用请参考条件构造器的使用教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值