【Mybatis】Mybatis-Plus 高级

1、关于插件

1.1、插件机制

        MyBatis 允许你在已映射语句执⾏过程中的某⼀点进⾏拦截调⽤。默认情况下,MyBatis 允许使⽤插件来拦截的⽅法调⽤包括:

  • Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  • ParameterHandler (getParameterObject, setParameters)
  • ResultSetHandler (handleResultSets, handleOutputParameters)
  • StatementHandler (prepare, parameterize, batch, update, query)

        我们看到了可以拦截Executor接⼝的部分⽅法,⽐如update,query,commit,rollback等⽅法,还有其他接⼝的⼀些⽅法等。总体概括为:

  1. 拦截执⾏器的⽅法
  2. 拦截参数的处理
  3. 拦截结果集的处理
  4. 拦截Sql语法构建的处理

拦截器示例:

package com.blnp.net.plugin;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;

import java.util.Properties;

/**
 * <p></p>
 *
 * @author lyb 2045165565@qq.com
 * @version 1.0
 * @since 2024/8/27 14:17
 */
@Intercepts(
        @Signature(
                type = Executor.class,
                method = "update",
                args = {MappedStatement.class,Object.class}
        )
)
public class MyInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        /**
         *  拦截方法,具体业务逻辑编写的位置
         **/
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        //创建target对象的代理对象,目的是将当前拦截器加入到该对象中
        return Plugin.wrap(target,this);
    }

    @Override
    public void setProperties(Properties properties) {
        //属性设置
    }
}

注入到Spring容器中:

/**
* ⾃定义拦截器
*/
@Bean
public MyInterceptor myInterceptor(){
	return new MyInterceptor();
}

或者通过xml配置,mybatis-config.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
	PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<plugins>
		<plugin interceptor="com.blnp.net.plugin.MyInterceptor"></plugin>
	</plugins>
</configuration>

1.2、性能分析插件

1.2.1、旧版本分析方法

        老版本的性能分析插件是使用以下方式来进行分析的,但是该插件比较影响性能。并且官方在3.2.0版本以上已经移除了,但这里还是记录下具体的使用方法:

步骤一:在MP配置类中配置该插件,并且只适用于DEV环境

import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisPlusConfig {

   /*
    *性能分析插件
    */
   @Bean
   @Profile({"dev"}) // 指定环境为dev生效
   public PerformanceInterceptor performanceInterceptor(){
       PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        // 设置sql语句的最大执行时间
       performanceInterceptor.setMaxTime(100);
       // 设置sql是否格式化显示
       performanceInterceptor.setFormat(true);

       return performanceInterceptor;
   }
}

 步骤二:设置环境为dev,可以在yml如下配置,或者直接测试类中也是可以设置的,如图。

spring:
  profiles:
    active: dev

1.2.2、推荐方式

步骤一:引入p6spy的maven依赖

<!--SQL 分析打印-->
<dependency>
    <groupId>p6spy</groupId>
    <artifactId>p6spy</artifactId>
    <version>3.8.2</version>
</dependency>

步骤二:更改yml连接数据库配置,主要修改driver-class-name、url中jdbc后需要加上p6spy

spring:
  datasource:
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:mysql://127.0.0.1:3360/test?userSSL=false
    username: root
    password: 123456
  profiles:
    active: dev

步骤三:新增spy.properties文件,内容如下,可以根据需求相对应的修改文件。

module.log=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
 
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
 
#日志输出到控制台,解开注释就行了
# appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
 
# 指定输出文件位置
logfile=sql.log
 
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
 
# 设置 p6spy driver 代理
deregisterdrivers=true
 
# 取消JDBC URL前缀
useprefix=true
 
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,batch,resultset
 
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
 
# 实际驱动可多个
#driverlist=org.h2.Driver
 
# 是否开启慢SQL记录
outagedetection=true
 
# 慢SQL记录标准 2 秒
outagedetectioninterval=2

步骤四:输出文件格式内容如下

 Consume Time:63 ms 2024-08-27 17:15:22
 Execute SQL:SELECT id,name,age,email FROM user WHERE (age <= '23')

拓展:关于 p6spy

.        P6Spy是一个开源的Java应用程序,它可以拦截和记录JDBC(Java数据库连接)调用,以便开发人员可以更方便地进行数据库调试和性能优化。P6Spy可以通过提供数据库调试信息和SQL执行时间等方面的信息来帮助开发人员诊断慢查询和其他数据库问题。主要包括以下几个方面:

  1. 监视和记录JDBC调用:P6Spy可以拦截JDBC驱动程序发送到数据库的SQL语句,并记录它们以供后期分析。
  2. 统计查询性能:P6Spy可以记录SQL执行时间、连接打开和关闭时间以及事务提交和回滚时间等有关性能的信息。
  3. 分析慢查询:P6Spy可以帮助开发人员查找和调试缓慢的SQL查询,以便优化查询性能。
  4. 预测系统行为:使用P6Spy,开发人员可以获得有关系统负载和数据库性能的信息,以便优化系统配置和资源使用。

相关配置:

# 指定应用的日志拦截模块,默认为com.p6spy.engine.spy.P6SpyFactory 
#modulelist=com.p6spy.engine.spy.P6SpyFactory,com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory

# 真实JDBC driver , 多个以 逗号 分割 默认为空
#driverlist=

# 是否自动刷新 默认 flase
#autoflush=false

# 配置SimpleDateFormat日期格式 默认为空
#dateformat=

# 打印堆栈跟踪信息 默认flase
#stacktrace=false

# 如果 stacktrace=true,则可以指定具体的类名来进行过滤。
#stacktraceclass=

# 监测属性配置文件是否进行重新加载
#reloadproperties=false

# 属性配置文件重新加载的时间间隔,单位:秒 默认60s
#reloadpropertiesinterval=60

# 指定 Log 的 appender,取值:
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
#appender=com.p6spy.engine.spy.appender.StdoutLogger
#appender=com.p6spy.engine.spy.appender.FileLogger

# 指定 Log 的文件名 默认 spy.log
#logfile=spy.log

# 指定是否每次是增加 Log,设置为 false 则每次都会先进行清空 默认true
#append=true

# 指定日志输出样式  默认为com.p6spy.engine.spy.appender.SingleLineFormat , 单行输出 不格式化语句
#logMessageFormat=com.p6spy.engine.spy.appender.SingleLineFormat
# 也可以采用  com.p6spy.engine.spy.appender.CustomLineFormat 来自定义输出样式, 默认值是%(currentTime)|%(executionTime)|%(category)|connection%(connectionId)|%(sqlSingleLine)
# 可用的变量为:
#   %(connectionId)            connection id
#   %(currentTime)             当前时间
#   %(executionTime)           执行耗时
#   %(category)                执行分组
#   %(effectiveSql)            提交的SQL 换行
#   %(effectiveSqlSingleLine)  提交的SQL 不换行显示
#   %(sql)                     执行的真实SQL语句,已替换占位
#   %(sqlSingleLine)           执行的真实SQL语句,已替换占位 不换行显示
#customLogMessageFormat=%(currentTime)|%(executionTime)|%(category)|connection%(connectionId)|%(sqlSingleLine)

# date类型字段记录日志时使用的日期格式 默认dd-MMM-yy
#databaseDialectDateFormat=dd-MMM-yy

# boolean类型字段记录日志时使用的日期格式 默认boolean 可选值numeric
#databaseDialectBooleanFormat=boolean

# 是否通过jmx暴露属性 默认true
#jmx=true

# 如果jmx设置为true 指定通过jmx暴露属性时的前缀 默认为空
# com.p6spy(.<jmxPrefix>)?:name=<optionsClassName>
#jmxPrefix=

# 是否显示纳秒 默认false
#useNanoTime=false

# 实际数据源 JNDI
#realdatasource=/RealMySqlDS
# 实际数据源 datasource class
#realdatasourceclass=com.mysql.jdbc.jdbc2.optional.MysqlDataSource

# 实际数据源所携带的配置参数 以 k=v 方式指定 以 分号 分割
#realdatasourceproperties=port;3306,serverName;myhost,databaseName;jbossdb,foo;bar

# jndi数据源配置 
# 设置 JNDI 数据源的 NamingContextFactory。 
#jndicontextfactory=org.jnp.interfaces.NamingContextFactory
# 设置 JNDI 数据源的提供者的 URL。 
#jndicontextproviderurl=localhost:1099
# 设置 JNDI 数据源的一些定制信息,以分号分隔。 
#jndicontextcustom=java.naming.factory.url.pkgs;org.jboss.naming:org.jnp.interfaces

# 是否开启日志过滤 默认false, 这项配置是否生效前提是配置了 include/exclude/sqlexpression
#filter=false

# 过滤 Log 时所包含的表名列表,以逗号分隔 默认为空
#include=
# 过滤 Log 时所排除的表名列表,以逗号分隔 默认为空
#exclude=

# 过滤 Log 时的 SQL 正则表达式名称  默认为空
#sqlexpression=

#显示指定过滤 Log 时排队的分类列表,取值: error, info, batch, debug, statement,
#commit, rollback, result and resultset are valid values
# (默认 info,debug,result,resultset,batch)
#excludecategories=info,debug,result,resultset,batch

# 是否过滤二进制字段
# (default is false)
#excludebinary=false

# P6Log 模块执行时间设置,整数值 (以毫秒为单位),只有当超过这个时间才进行记录 Log。 默认为0
#executionThreshold=

# P6Outage 模块是否记录较长时间运行的语句 默认false
# outagedetection=true|false
# P6Outage 模块执行时间设置,整数值 (以秒为单位)),只有当超过这个时间才进行记录 Log。 默认30s
# outagedetectioninterval=integer time (seconds)

1.3、乐观锁插件

1.3.1、适用场景

        目的是当要更新⼀条记录的时候,希望这条记录没有被别⼈更新。乐观锁实现⽅式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执⾏更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

1.3.2、插件配置

SpringBoot:

@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
    return new OptimisticLockerInterceptor();
}

SpringMVC:

<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>

1.3.3、注解实体字段

第⼀步,为表添加version字段,并且设置初始值为1:

ALTER TABLE `tb_user`
ADD COLUMN `version` int(10) NULL AFTER `email`;
UPDATE `tb_user` SET `version`='1';

第⼆步,为User实体对象添加version字段,并且添加@Version注解:

@Version
private Integer version;

1.3.4、验证测试

@Test
public void testUpdate() {
    User user = new User();
    user.setAge(30);
    user.setId(2 L);
    user.setVersion(1); //获取到version为1
    int result = this.userMapper.updateById(user);
    System.out.println("result = " + result);
}
[DEBUG] Original SQL: UPDATE tb_user SET age=?,
version=? WHERE id=? AND version=?
[main] [com.baomidou.mybatisplus.extension.parsers.BlockAttackSqlParser]-
[DEBUG] parser sql: UPDATE tb_user SET age = ?, version = ? WHERE id = ? AND
version = ?
[main] [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Fetching
JDBC Connection from DataSource
[main] [org.mybatis.spring.transaction.SpringManagedTransaction]-[DEBUG] JDBC
Connection [HikariProxyConnection@540206885 wrapping
com.mysql.jdbc.JDBC4Connection@27e0f2f5] will not be managed by Spring
[main] [com.blnp.net.mp.mapper.UserMapper.updateById]-[DEBUG] ==> Preparing:
UPDATE tb_user SET age=?, version=? WHERE id=? AND version=?
[main] [com.blnp.net.mp.mapper.UserMapper.updateById]-[DEBUG] ==> Parameters:
30(Integer), 2(Integer), 2(Long), 1(Integer)
[main] [com.blnp.net.mp.mapper.UserMapper.updateById]-[DEBUG] <== Updates: 1
[main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@30135202]
result = 1

1.3.5、特别说明

  • ⽀持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity 中
  • 仅⽀持 updateById(id) 与 update(entity, wrapper) ⽅法
  • 在 update(entity, wrapper) ⽅法下, wrapper 不能复⽤!!!

2、SQL 注入器

2.1、编写MyBaseMapper

package com.blnp.net.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import java.util.List;

/**
 * <p></p>
 *
 * @author lyb 2045165565@qq.com
 * @version 1.0
 * @since 2024/8/28 9:06
 */
public interface MyBaseMapper<T> extends BaseMapper<T> {

    /**
     * 用途: 自定义查询所有接口
     * @author liaoyibin
     * @since 9:11 2024/8/28
     * @params []
     * @param
     * @return java.util.List<T>
    **/
    List<T> findAll();
}

        实际使用时,对应的mapper继承该自定义mapper即可:

2.2、编写MySqlInjector

        如果直接继承AbstractSqlInjector的话,原有的BaseMapper中的⽅法将失效,所以我们选择继承DefaultSqlInjector进⾏扩展。

package com.blnp.net.sqlInjector;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 自定义SQL注入方法
 * <p>
 *     1、直接继承AbstractSqlInjector的话,原有的BaseMapper中的方法将失效
 * </p>
 *
 * @author lyb 2045165565@qq.com
 * @version 1.0
 * @since 2024/8/28 9:17
 */
@Component
public class MySqlInjector extends DefaultSqlInjector {

    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
        //注入自定义SQL方法实现
        methodList.add(new FindAll());
        return methodList;
    }
}

2.3、编写FindAll

package com.blnp.net.sqlInjector;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;

/**
 * <p></p>
 *
 * @author lyb 2045165565@qq.com
 * @version 1.0
 * @since 2024/8/28 9:25
 */
public class FindAll extends AbstractMethod {

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        String sqlMethod = "findAll";
        String sql = "select * from " + tableInfo.getTableName();
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        return this.addSelectMappedStatementForTable(mapperClass, sqlMethod, sqlSource, tableInfo);
    }
}

2.4、注册到Spring容器

@Bean
public ISqlInjector mySqlInjector() {
    return new MySqlInjector();
}

2.5、测试验证

package com.blnp.net.mp;

import com.blnp.net.mp.generator.project.entity.TbProject;
import com.blnp.net.mp.generator.project.mapper.TbProjectMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
class GeneratorCodeApplicationTests {

    @Resource
    TbProjectMapper projectMapper;

    /**
     * 用途:乐观锁测试实现
     * @author liaoyibin
     * @since 14:48 2024/8/28
     * @params []
     * @param
     * @return void
    **/
    @Test
    public void contextLoads() {
        TbProject project = projectMapper.selectById(1);
        project.setCreater("李四");
        int i = projectMapper.updateById(project);
        System.out.println("i = " + i);

        /**
         *  特别说明:
         *      这里尤其要注意,关于Mybatis-Plus的乐观锁插件,仅支持 updateById(id) 与 update(entity, wrapper) 方法;
         *   此外,如果是单独 new 对象实体的方式进行更新是不会触发乐观锁的。
         *
         *   UserEntity entity = new UserEntity();
         *   entity.setId(1);
         *   mapper.updateById(entity);
         *   //该方式是无效且不触发乐观锁!!
         **/
    }

    /**
     * 用途:SQL注入器测试查询
     * @author liaoyibin
     * @since 14:47 2024/8/28
     * @params []
     * @param
     * @return void
    **/
    @Test
    public void testCusQuery() {
        List<TbProject> tbProjects = projectMapper.findAll();
        for (TbProject tbProject : tbProjects) {
            System.out.println("tbProject = " + tbProject);
        }
    }
}

3、自动填充功能

3.1、添加@TableField注解

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

package com.baomidou.mybatisplus.annotation;

/**
 * 字段填充策略枚举类
 *
 * <p>
 * 判断注入的 insert 和 update 的 sql 脚本是否在对应情况下忽略掉字段的 if 标签生成
 * <if test="...">......</if>
 * 判断优先级比 {@link FieldStrategy} 高
 * </p>
 *
 * @author hubin
 * @since 2017-06-27
 */
public enum FieldFill {
    /**
     * 默认不处理
     */
    DEFAULT,
    /**
     * 插入时填充字段
     */
    INSERT,
    /**
     * 更新时填充字段
     */
    UPDATE,
    /**
     * 插入和更新时填充字段
     */
    INSERT_UPDATE
}

3.2、编写MyMetaObjectHandler

package com.blnp.net.mp.generator.handle;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Optional;

/**
 * <p>自动填充插件实现</p>
 *
 * @author lyb 2045165565@qq.com
 * @version 1.0
 * @since 2024/8/28 14:54
 */
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        Object creater = getFieldValByName("creater", metaObject);
        if (!Optional.ofNullable(creater).isPresent()) {
            //新增SQL时,为空则自动填充
            setFieldValByName("creater","王二麻子",metaObject);
        }
        Object createTime = getFieldValByName("createTime", metaObject);
        if (!Optional.ofNullable(createTime).isPresent()) {
            //新增SQL时,为空则自动填充
            long currentTimeMillis = System.currentTimeMillis();
            setFieldValByName("createTime",currentTimeMillis,metaObject);
        }
        Object comment = getFieldValByName("comment", metaObject);
        if (!Optional.ofNullable(comment).isPresent()) {
            //新增SQL时,为空则自动填充
            String commentMsg = String.format("记录于 %s 时刻,完成【新增】操作!", DateUtil.now());
            setFieldValByName("comment",commentMsg,metaObject);
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        Object comment = getFieldValByName("comment", metaObject);
        if (!Optional.ofNullable(comment).isPresent()) {
            //新增SQL时,为空则自动填充
            String commentMsg = String.format("记录于 %s 时刻,完成【更新】操作!", DateUtil.now());
            setFieldValByName("comment",commentMsg,metaObject);
        }
    }
}

 3.3、验证测试

@Test
public void testAutoFill() {
    TbProject project = new TbProject();
    project.setName("喷淋系统");
    int insert = projectMapper.insert(project);
    System.out.println("project = " + project);
}

4、逻辑删除

4.1、修改表结构

        为数据表增加deleted字段,⽤于表示数据是否被删除,1代表删除,0代表未删除。同时,也修改User实体,增加deleted属性并且添加@TableLogic注解:

ALTER TABLE `tb_user`
ADD COLUMN `deleted` int(1) NULL DEFAULT 0 COMMENT '1代表删除,0代表未删除'
AFTER `version`;
@TableLogic
private Integer deleted;

4.2、配置

application.properties:

# 逻辑已删除值(默认为 1)
mybatis-plus.global-config.db-config.logic-delete-value=1
# 逻辑未删除值(默认为 0)
mybatis-plus.global-config.db-config.logic-not-delete-value=0

 4.3、测试验证

@Test
public void testLogicDelete() {
    int deleteById = projectMapper.deleteById(2);
    System.out.println("deleteById = " + deleteById);
}

5、代码生成器

5.1、创建Maven工程

        并配置以下版本依赖:

<properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--mybatis-plus的springboot⽀持-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--简化代码的具包-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

5.2、创建生成类

package com.blnp.net.mp.generator;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

/**
 * <p>mysql代码生成器示例</p>
 *
 * @author lyb 2045165565@qq.com
 * @version 1.0
 * @since 2024/8/28 11:07
 */
public class MysqlGenerator {

    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("blnp");
        gc.setOpen(false);
        mpg.setGlobalConfig(gc);
        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://127.0.0.1:3307/my_test?useUnicode=true&useSSL=false&characterEncoding=utf8");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("admin@123");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(scanner("模块名"));
        pc.setParent("com.blnp.net.mp.generator");
        mpg.setPackageInfo(pc);

        //自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                //自定义输入文件名称
                return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" +
                        StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
        mpg.setTemplate(new TemplateConfig().setXml(null));

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //strategy.setSuperEntityClass("com.baomidou.mybatisplus.samples.generator.common.BaseEntity");
        strategy.setEntityLombokModel(true);
        //strategy.setSuperControllerClass("com.baomidou.mybatisplus.samples.generator.common.BaseController");
        strategy.setInclude(scanner("表名"));
        strategy.setSuperEntityColumns("id");
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        // 选择 freemarker 引擎需要指定如下加,注意 pom 依赖必须有!
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }
}

5.3、生成测试

5.4、示例源代码

示例源代码下载:

generator-code.7z官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘

6、完整源代码

mybatis-plus示例包.7z官方版下载丨最新版下载丨绿色版下载丨APP下载-123云盘

  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值