Spring-boot Mybatis-plus practical application

Article directory

  • Preface
  • 1. springBoot integrates mybatis-plus
    • 1.1 maven introduces dependencies:
    • 1.2 Configure data source::
  • 2. Use:
    • 2.1 mysql prints the executed sql settings:
    • 2.2 Paging query:
    • 2.3 Conditional constructor:
      • 2.3.1 QueryWrapper query:
      • 2.3.2 UpdateWrapper update:
      • 2.3.3 LambdaQueryWrapper query:
      • 2.3. LambdaUpdateWrapper update:
  • 3. Use of plug-ins:
    • 3.1 Custom ID generation:
    • 3.2 Logical deletion:
    • 3.3 Autofill:
    • 3.4 Execute sql printing:
      • 3.4.1 Dependencies:
      • 3.4.2 Driver modification:
      • 3.4.3 Define py.properties configuration:
      • 3.4.4 Optional idea SQL beautification plug-in:
    • 3.5 Database security protection:
    • 3.6 Database optimistic locking:
    • 3.7 Code Generator:
      • 3.7.1 jar in springboot web project:
      • 3.7.2 Define business class generation:
      • 3.7.3 Run business class generation:
  • Summarize:
  • refer to:

Foreword

After Mybatis-plus is introduced in the Spring-boot project, how should the data source be configured and how to quickly implement CRUD through the Mybatis-plus interface.

1. springBoot integrates mybatis-plus

1.1 maven introduces dependencies:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>

1.2 Configure data source::

@Configuration
public class MyConfig {<!-- -->


    @Bean
    public DataSource dataSource() {<!-- -->
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl("jdbc:mysql://localhost:3406/mybatis?useUnicode=true & amp;characterEncoding=UTF-8 & amp;allowMultiQueries=true & amp;useAffectedRows=true & amp;useSSL=false & amp; zeroDateTimeBehavior=convertToNull & amp;serverTimezone=GMT+8");
        dataSource.setUsername("root");
        dataSource.setPassword("ddsoft");
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {<!-- -->
        return new JdbcTemplate(dataSource);
    }


    @Bean
    public DataSourceTransactionManager transactionManager(DataSource dataSource) {<!-- -->
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean
    public JdbcTemplate jdbcTemplate() {<!-- -->
        return new JdbcTemplate(dataSource());
    }
    @Bean
    public DataSourceTransactionManager transactionManager() {<!-- -->
        return new DataSourceTransactionManager(dataSource());
    }

}

2. Use:

2.1 mysql prints the executed sql settings:

# mysql log
logging.level.root=info
logging.level.com.example.springdabaihua=debug

tip: Dao layer uses Mapper’s crud, which usually starts with the name of sql’s crud; when service uses Tongcha, we will not directly reference the Mapper layer, but will use the service layer: service Tongchang has business names starting with listXxx, getXxx; these APIs are not here To expand, you can learn about it through the CRUD interface on the official website;

2.2 Paging query:

Define paging plug-in to intercept SQL:

/**
 * Add paging plugin
 */
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {<!-- -->
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//If you configure multiple plug-ins, remember to add pagination last
    //interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); If there are multiple data sources, you do not need to match the specific type. Otherwise, it is recommended to match the specific DbType.
    return interceptor;
})

Pagination at the business layer:

@Test
public void testPage1() {<!-- -->
    IPage<TbUser> ipage = new Page<TbUser>(1, 2);
    IPage<TbUser> page = userService.page(ipage);
    System.out.println(page.getRecords());
    System.out.println(page.getPages());
    System.out.println(page.getTotal());
}

Pagination of mapper layer:

@Test
public void testPage2() {<!-- -->
    IPage<TbUser> ipage = new Page<TbUser>(1, 2);
    IPage<TbUser> page = userMapper.getPage(ipage);;
    System.out.println(page.getRecords());
    System.out.println(page.getPages());
    System.out.println(page.getTotal());
}

public interface TbUserMapper extends BaseMapper<TbUser> {<!-- -->

    IPage<TbUser> getPage(IPage<?>page );
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springdabaihua.mapper.TbUserMapper">


    <select id="getPage" resultType="com.example.springdabaihua.entity.TbUser">
        select * from tb_user
    </select>
</mapper>

2.3 Conditional constructor:

2.3.1 QueryWrapper query:

@Test
public void testWraaper1(){<!-- -->
    QueryWrapper<TbUser> wrapper = new QueryWrapper<>();
// select can limit column names
    wrapper.select("id","name").like("name","Zhang");
    List<TbUser> list = userService.list(wrapper);
    list.stream().forEach(e->{<!-- -->
        System.out.println(e);
    });
}

2.3.2 UpdateWrapper update:

@Test
public void testWraaper2() {<!-- -->
    UpdateWrapper<TbUser> wrapper = new UpdateWrapper<>();
    wrapper.like("name", "1");
    wrapper.set("name", "Zhao Liu");
    userService.update(wrapper);

}

2.3.3 LambdaQueryWrapper query:

Added use of Lambda expressions so you don’t have to receive incoming column names

@Test
public void testWraaper3() {<!-- -->
    LambdaQueryWrapper<TbUser> wrapper = new LambdaQueryWrapper<>();
    wrapper.select(TbUser::getId,TbUser::getName).like(TbUser::getName, "张");
    List<TbUser> list = userService.list(wrapper);
    list.stream().forEach(e -> {<!-- -->
        System.out.println(e);
    });
}

2.3. LambdaUpdateWrapper update:

Added use of Lambda expressions so you don’t have to receive incoming column names

@Test
public void testWraaper4() {<!-- -->
    LambdaUpdateWrapper<TbUser> wrapper = new LambdaUpdateWrapper<>();
    wrapper.like(TbUser::getName, "Zhao");
    wrapper.set(TbUser::getName,"Xiao Li Flying Knife");
    userService.update(wrapper);

}

3. Use of plug-ins:

3.1 Custom ID generation:

Define id generation: (For the setting of distributed globally unique id, you can refer to other articles in my blog and search for the keyword “distributed globally unique id” to view)

@Component
public class CustomIdGenerator implements IdentifierGenerator {<!-- -->
    @Override
    public Long nextId(Object entity) {<!-- -->
      //You can use the full class name of the currently passed in class as bizKey, or extract parameters to generate bizKey for distributed Id call generation.
      String bizKey = entity.getClass().getName();
        //Call distributed ID generation based on bizKey
        long id = ....;
      //Return the generated id value.
        return id;
    }
}

Use a custom id defined in the entity class:

 @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Integer id;

3.2 Logical deletion:

Add logically deleted fields to mysql table

tip: Supports all data types (Integer, Boolean, LocalDateTime are recommended). If the database field uses datetime, the logical undeleted value and the deleted value can be configured as the string null, and the other value can be configured as Function to get the value such as now();

Single table fields can be set:

 @TableLogic(value = "1",delval = "0")
 private Integer isDelete;

Global configuration is also possible:

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: flag # Entity field name for global logical deletion (since 3.3.0, you can ignore step 2 after configuration)
      logic-delete-value: 1 # Logical deleted value (default is 1)
      logic-not-delete-value: 0 # Logical not deleted value (default is 0)

tip: Only effective for automatically injected sql (the api results provided by mybatis-plus are not supported if you write your own xml):

  • Insertion: No restrictions
  • Search: Add a where condition to filter out deleted data. If you use the where condition generated by wrapper.entity, this field will also be automatically added.
  • Update: Add a where condition to prevent updating to deleted data. If you use the where condition generated by wrapper.entity, this field will also be automatically added.
  • Delete: Convert to Update

3.3 Autocomplete:

Fill creation, update person and time: annotation fill field @TableField(… fill = FieldFill.INSERT) The generator strategy part can also be configured
Custom padding:

@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {<!-- -->

    @Override
    public void insertFill(MetaObject metaObject) {<!-- -->
        log.info("start insert fill ....");
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // Starting version 3.3.0 (recommended)
        // or
        this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // Starting version 3.3.3 (recommended)
        // or
        this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // It can also be used (this method has a bug in 3.3.0)
    }

    @Override
    public void updateFill(MetaObject metaObject) {<!-- -->
        log.info("start update fill ....");
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // Starting version 3.3.0 (recommended)
        // or
        this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // Starting version 3.3.3 (recommended)
        // or
        this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // It can also be used (this method has a bug in 3.3.0)
    }
}

Filling time:

public enum FieldFill {<!-- -->
    /**
     * Not processed by default
     */
    DEFAULT,
    /**
     * Insert filler fields
     */
    INSERT,
    /**
     * Update fill fields
     */
    UPDATE,
    /**
     * Insert and update populated fields
     */
    INSERT_UPDATE
}

3.4 Execute sql printing:

3.4.1 Dependencies:

 <dependency>
    <groupId>p6spy</groupId>
     <artifactId>p6spy</artifactId>
     <version>3.9.1</version>
 </dependency>

3.4.2 Driver modification:

datasource:
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:h2:mem:test

tip: driver-class-name and url are added to p6spy

3.4.3 Define py.properties configuration:

#3.2.1 or above used
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1 The following is used or not configured.
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# Custom log printing
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#Log output to console
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# Use the log system to record sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# Set up p6spy driver agent
deregisterdrivers=true
# Cancel JDBC URL prefix
useprefix=true
# Configure the log exception. The result sets that can be removed include error, info, batch, debug, statement, commit, rollback, result, and resultsset.
excludecategories=info,debug,result,commit,resultset
# Date format
dateformat=yyyy-MM-dd HH:mm:ss
# There can be multiple actual drivers
#driverlist=org.h2.Driver
# Whether to enable slow SQL logging
outagedetection=true
# Slow SQL logging standard 2 seconds
outagedetectioninterval=2

Effect:

3.4.4 Optional idea SQL beautification plug-in:


After beautification, the printed SQL will be formatted and displayed instead of only displayed on one line;

Attention!

  • driver-class-name is the driver class provided by p6spy
  • The url prefix is jdbc:p6spy followed by a colon as the corresponding database connection address.
  • Print out sql as null, add commit in excludecategories
  • Batch operation does not print sql, remove batch in excludecategories
  • For batch operation printing duplicate problems, please use MybatisPlusLogFactory (new in 3.2.1)
  • This plug-in has performance losses and is not recommended for use in production environments.

3.5 Database security protection:

Encrypt sensitive data, such as mysql connection, user name, password, etc.:

public static void main(String[] args) {<!-- -->
    // Generate a 16-bit random AES key
    String randomKey = AES.generateRandomKey();
    System.out.println("randomKey = " + randomKey);
    // Random key encryption
    String result = AES.encrypt("root", randomKey);
    System.out.println(result);
}

The obtained randomKey is the encryption key, and sensitive data can be encrypted by changing the secret key;
Effect:

Complete the decryption of the customized ciphertext content when the project is started:
Define the attribute value annotation to be decrypted: DecryptedValue

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface DecryptedValue {<!-- -->
    String value() default "";
}

Add the DecryptedValue annotation to the field to be encrypted:

@Value("${spring.datasource.username}")
@DecryptedValue("spring.datasource.username")
private String userName;

@Value("${spring.datasource.password}")
@DecryptedValue("spring.datasource.password")
private String passWord;

Define decryption class: DataSourceDecryptionProcessor

import com.baomidou.mybatisplus.core.toolkit.AES;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;

@Component
public class DataSourceDecryptionProcessor implements BeanPostProcessor {<!-- -->
    @Value("${spring.datasource.key:xxxx}")
    private String dataSourceKey;

    private final Environment environment;

    public DataSourceDecryptionProcessor(Environment environment) {<!-- -->
        this.environment = environment;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {<!-- -->
        Class<?> clazz = bean.getClass();
        do {<!-- -->
            for (Field field : clazz.getDeclaredFields()) {<!-- -->
                DecryptedValue decryptedValueAnnotation = AnnotationUtils.findAnnotation(field, DecryptedValue.class);
                if (decryptedValueAnnotation != null) {<!-- -->
                    String propertyValue = environment.getProperty(decryptedValueAnnotation.value());
                    if (!StringUtils.isEmpty(propertyValue)) {<!-- -->
                        field.setAccessible(true);
                        try {<!-- -->
                        //Decrypt the encrypted value
                            String value = AES.decrypt(propertyValue, dataSourceKey);
                            field.set(bean, value);
                        } catch (IllegalAccessException e) {<!-- -->
                            e.printStackTrace();
                        }
                    }
                }
            }
            clazz = clazz.getSuperclass();
        } while (clazz != null);
        return bean;
    }
}

3.6 Database Optimistic Locking:

Add plugin:

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {<!-- -->
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return interceptor;
}

Add the @Version annotation to the fields of the entity class:

@Version
private Integer version;

Add version int type field to the table;

Test 1:

@Test
public void testLock() throws InterruptedException {<!-- -->
    CountDownLatch countDownLatch =new CountDownLatch(2);
    for (int i = 0; i < 2; i + + ) {<!-- -->
        int finalI = i;
        new Thread(()->{<!-- -->
            TbUser byId = userService.getById(860069891);
            byId.setName("lisi" + finalI);
            try {<!-- -->
                Thread.sleep(2000);
            } catch (InterruptedException e) {<!-- -->
                countDownLatch.countDown();
                throw new RuntimeException(e);

            }
            userService.updateById(byId);
            countDownLatch.countDown();
            
        },"thread" + i).start();
    }

    countDownLatch.await();
    

}


Test 2:

@Test
public void testLock1() throws InterruptedException {<!-- -->
    TbUser byId1 = userService.getById(860069891);
    TbUser byId2 = userService.getById(860069891);
    byId1.setName("Zhang Fei1");
    System.out.println("userService.updateById(byId1) = " + userService.updateById(byId1));
    byId2.setName("Zhao Yun1");
    System.out.println("userService.updateById(byId2) = " + userService.updateById(byId2));


}

3.7 Code Generator:

Used to quickly generate entities, services, mappers and controllers to facilitate business development;

3.7.1 jar in springboot web project:

 <dependencies>
<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.18</version>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.1.1</version>
    </dependency>
    <!--Code Generator-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.28</version>
    </dependency>
    <!--Code Generator-->
</dependencies>

3.7.2 Define business class generation:

package com.example.mybatiscodegenerage;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.springframework.util.StringUtils;

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

public class GenerateCode {<!-- -->
    /**
     * <p>
     * Read the console content
     *</p>
     */
    public static String scanner(String tip) {<!-- -->
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("Please enter" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {<!-- -->
            String ipt = scanner.next();
            if (StringUtils.hasText(ipt)) {<!-- -->
                return ipt;
            }
        }
        throw new MybatisPlusException("Please enter the correct one" + tip + "!");
    }

    public static void main(String[] args) {<!-- -->
        // Code generator
        AutoGenerator mpg = new AutoGenerator();

        //Global configuration
        GlobalConfig gc = new GlobalConfig();
        // Get the current project path
        String projectPath = System.getProperty("user.dir");
        //output directory
        gc.setOutputDir(projectPath + "/spring-batch/src/main/java");
        //Set author
        gc.setAuthor("jobob");
        // Do you need to open the folder after the code is generated?
        gc.setOpen(false);
        // Whether to generate Swagger2 annotations
        // gc.setSwagger2(true); Entity attribute Swagger2 annotation
        // Whether to generate a BaseResultMap mapping all fields in xml
        //gc.setBaseResultMap(true);
        //The same file generates overwrite
        gc.setFileOverride(true);
        // Time format for generating code
        gc.setDateType(DateType.ONLY_DATE);
        // https://baomidou.com/pages/061573/#datetype
        // Use the name of the table to directly generate entities, %s table name does not add the Entity suffix
       // gc.setEntityName("%s");
        // Mapper interface name %sMapper table name + Mapper
       // gc.setMapperName("%sMapper");
        // Mapper.xml generates file name, table name + Mapper.xml
        // gc.setXmlName("%sMapper");
        //Service interface name table name + Service
        // gc.setServiceName("%sService")
        //Service interface implementation class name table name + ImplService
        // gc.setServiceImplName("%sImplService");
        //Set to global configuration
        mpg.setGlobalConfig(gc);

        //Data source configuration
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3406/mybatis?useUnicode=true & amp;characterEncoding=UTF-8 & amp;allowMultiQueries=true & amp;useAffectedRows=true & amp;useSSL=false & amp; zeroDateTimeBehavior=convertToNull & amp;serverTimezone=GMT+8");
        // dsc.setSchemaName("public");
// dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("ddsoft");
        mpg.setDataSource(dsc);

        // package configuration
        PackageConfig pc = new PackageConfig();
        // For example, com.xxx.xxx.user, com.xxx.xxx is the package name, user is the module name
        //Set module name
        pc.setModuleName(scanner("module name"));
        //Set package name
        pc.setParent("com.baomidou.ant");
        mpg.setPackageInfo(pc);

        // Custom configuration Custom properties
        InjectionConfig cfg = new InjectionConfig() {<!-- -->
            @Override
            public void initMap() {<!-- -->
                // to do nothing
            }
        };

        // If the template engine is freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // If the template engine is velocity
        // String templatePath = "/templates/mapper.xml.vm";

        // Custom output configuration
        List<FileOutConfig> focList = new ArrayList<>();
        // Custom configuration will be output first mapper.xml file location settings
        focList.add(new FileOutConfig(templatePath) {<!-- -->
            @Override
            public String outputFile(TableInfo tableInfo) {<!-- -->
                // Customize the output file name. If your Entity sets the prefix and suffix, please note that the name of the xml will change accordingly! !
                return projectPath + "/spring-batch/src/main/resources/mapper/" + pc.getModuleName()
                         + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        /*
        cfg.setFileCreate(new IFileCreate() {
            @Override
            public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
                // Determine whether a custom folder needs to be created
                checkDir("Directory created by calling the default method, use " for custom directories);
                if (fileType == FileType.MAPPER) {
                    // The mapper file has been generated and is judged to exist. If you do not want to regenerate it, return false.
                    return !new File(filePath).exists();
                }
                //Allow template file generation
                return true;
            }
        });
        */
        //Set custom configuration
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        //Configure template
        TemplateConfig templateConfig = new TemplateConfig();

        //Configure custom output template
        //Specify the custom template path, be careful not to bring .ftl/.vm, it will be automatically recognized based on the template engine used.
        // templateConfig.setEntity("templates/entity2.java");
        // templateConfig.setService();
        // templateConfig.setController();
        // Invalidate the existing xml configuration generated at the code level
        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        //Strategy configuration, database table configuration
        StrategyConfig strategy = new StrategyConfig();
        //Naming strategy for database tables mapped to entities, underline to camel case
        strategy.setNaming(NamingStrategy.underline_to_camel);
        //Naming strategy for mapping database table fields to entity classes
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //Customize the inherited entity class. Adding this one will inherit the entity when generating the entity class.
        //strategy.setSuperEntityClass("com.wy.testCodeGenerator.entity");
        //Whether the entity is a lombok model
        strategy.setEntityLombokModel(true);
        //Generate @RestController controller
        strategy.setRestControllerStyle(true);
        //Public parent class Controller whether it has a parent class
        // strategy.setSuperControllerClass("Your own parent class controller, no need to set it if you don’t have one!");
        //Public fields written in the parent class
        // strategy.setSuperEntityColumns("id");
        // If you want to generate according to the prefix setTablePrefix("pms_")
// strategy.setTablePrefix("pms_");
        strategy.setInclude(scanner("Table name, multiple English commas separated").split(","));
        // Camel case transfer string mapper path setting in RestController. If set, the path to the table name will be generated, such as pmp_user
        strategy.setControllerMappingHyphenStyle(true);
        //Table prefix such as pms_xxx The generated class does not include pms
// strategy.setTablePrefix( "pms");
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }
}

3.7.3 Run business class generation:

Summary:

This article organizes the commonly used CRUD APIs and commonly used plug-ins of Spring-boot Mybatis-plus.

Reference:

Mybatis-plus official website;