Spring Boot uses Mybatis-plus and its code generator

Spring Boot uses Mybatis-plus and its code generator

The first part of this article explains the use of Mybatis-plus. Click the link below to go to the official website.

But be warned. It is only used for rapid development, because the first point of SQL optimization is that the select in the SQL statement should not directly write *, that is, search all, but should write every field to be used.

The second part is to write the code generator in Mybatis-plus. First of all, the code generated by the code can actually be directly used as an example in the Mybatis-plus official website. But to change the generated code into what you want, you still need to do it yourself. Modify the template code so this article will show the template I am using now.

Article Directory:

  1. Mybatis-Plus use
  2. Code generator

Mybatis-Plus use

Dependencies that need to be added in pom.xml

//Mybatis-Plus package
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.3.1.tmp</version>
    </dependency>
    // Package of code constructors
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.3.1.tmp</version>
    </dependency>
    //The page template used is freemarker
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.30</version>
    </dependency>
    // For the lombok package, it is recommended to download the plug-in. If you do not download the plug-in code, the code will be red, but it can run.
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    // Use pagehelper for paging. Mybatis-plus has paging API. Whether to use it or not is up to you.
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper-spring-boot-starter</artifactId>
        <version>1.2.10</version>
    </dependency>
    // If you plan to use swagger, add the following two annotations
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>

The following is the project structure and code. Exception, config, and until are not involved in this tutorial

*Application.java *

@EnableCaching
//Scan mapper folder
@MapperScan("com.generator.mapper")
@SpringBootApplication
public class GeneratorApplication {

    public static void main(String[] args) {
        SpringApplication.run(GeneratorApplication.class, args);
    }

}

Entity class entity

@Data
// If this is true, its parent class must be considered when equaling. Because this class has no parent class, it is false.
// I suggest everyone to learn about the following in this place, which is related to the equals() method and involves .equals() of parent classes and subclasses.
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
//The following annotation is from swagger
@ApiModel(value="UserInfo object", description="")
public class UserInfo implements Serializable {

    private static final long serialVersionUID = 1L;
    //The following is the annotation of Mybatis-Plus, primary key declaration, automatic growth
    @TableId(value = "user_id", type = IdType.AUTO)
    private Integer userId;

    private String pwd;

    private String userName;

    private String userRealName;

    private String telephone;
    // swagger annotation
    @ApiModelProperty(value = "User occupation")
    private String userPro;


}

Under the service package

// You need to inherit IService<Entity> here to obtain the methods in Mybatis-plus.
// In fact, you don’t need to write the following here, because Mybatis-plus has corresponding select methods internally. Please read the official documents for related information.
// But I still recommend using a method designed by yourself, which is more callable.
public interface IUserInfoService extends IService<UserInfo> {

    /**
     * Find userInfo
     * @param userInfo
     * @param pageStart
     * @param pageSize
     * @return
     */
    List<UserInfo> findUserInfo(UserInfo userInfo, Integer pageStart, Integer pageSize);

    /**
     * Add userInfo
     * @param userInfo
     * @return
     */
    int insertUserInfo(UserInfo userInfo);

    /**
     * Modify userInfo
     * @param userInfo
     * @return
     */
    int updateUserInfo(UserInfo userInfo);

    /**
     * Delete userInfo
     * @param id
     * @return
     */
    int deleteUserInfo(int id);

}

Under the impl folder in the service package

// The declaration is a Service service class, inherit ServiceImpl<Entity> and use the methods in Mybatis-plus
// Implement the interface declared in IUserInfoService
@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements IUserInfoService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Override
    public List<UserInfo> findUserInfo(UserInfo userInfo, Integer pageStart, Integer pageSize) {
        /*
        This is to call the eq method in QueryWrapper to build a sql statement yourself.
        QueryWrapper<UserInfo> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("userName",userInfo.getUserName());
        */
        // Use the QueryWrapper conditional constructor. Here, the object is stored directly. There are other ways to use it. In it, the api commands such as eq are directly called according to the situation.
        QueryWrapper<UserInfo> queryWrapper=new QueryWrapper<>(userInfo);
        // Use pagehelper to paginate
        PageHelper.startPage(pageStart,pageSize);
        //Call the selectList method in ServiceImpl
        return userInfoMapper.selectList(queryWrapper);
    }

    @Override
    public int insertUserInfo(UserInfo userInfo) {
        return userInfoMapper.insert(userInfo);
    }

    @Override
    public int updateUserInfo(UserInfo userInfo) {
        return userInfoMapper.updateById(userInfo);
    }

    @Override
    public int deleteUserInfo(int id) {
        return userInfoMapper.deleteById(id);
    }


}

Under the mapper folder

//The declaration is an interface, inheriting BaseMapper<Entity>
@Repository
public interface UserInfoMapper extends BaseMapper<UserInfo> {
    //Add custom mapper here
}

mapper folder under resources

<?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.generator.mapper.UserInfoMapper">

</mapper>

Under the controller folder

// swagger annotation
@Api(tags = "UserInfoController", description = "User Management")
@RestController
@RequestMapping("/user-info")
public class UserInfoController {

    //Here I declare a variable using the interface, which can be declared directly using service
    @Autowired
    private IUserInfoService userInfoService;

    // swagger annotation
    @ApiOperation("Query User")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public RespBody findUserInfo(UserInfo userInfo,
                                 @RequestParam(value = "pageStart",defaultValue = "1")Integer pageStart,
                                 @RequestParam(value = "pageSize", defaultValue = "10")Integer pageSize){
        List<UserInfo> userInfoList = userInfoService.findUserInfo(userInfo, pageStart, pageSize);
        //Return class of pagehelper
        PageInfo<UserInfo> pageInfo = new PageInfo<>(userInfoList);
        return RespBody.ok(pageInfo);
    }

    @ApiOperation("Add user")
    @RequestMapping(value = "/insert", method = RequestMethod.POST)
    public RespBody insertUserInfo(UserInfo userInfo) {
        int result = userInfoService.insertUserInfo(userInfo);
        if (result == 1) {
            return RespBody.ok();
        }
        return RespBody.error();
    }

    @ApiOperation("Modify user")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public RespBody updateUserInfo(UserInfo userInfo) {
        int result = userInfoService.updateUserInfo(userInfo);
        if (result == 1) {
            return RespBody.ok();
        }
        return RespBody.error();
    }

    @ApiOperation("Delete user")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public RespBody updateUserInfo(@RequestParam("id")int id) {
        int result = userInfoService.deleteUserInfo(id);
        if (result == 1) {
            return RespBody.ok();
        }
        return RespBody.error();
    }

}

At this point, the above is the corresponding code generated using my design template

My Mybatis-plus code generator

Code

// Some modifications have been made, but overall it is the same as the code on the official website
public class CodeGenerator {

    /**
     * <p>
     * Read the console content
     *</p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        //Enter module name
        help.append("Please enter" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(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();
        String projectPath = System.getProperty("user.dir");
        //Output path
        gc.setOutputDir(projectPath + "/src/main/java");
        // author
        gc.setAuthor("dell");
        gc.setOpen(false);
        // Whether to use entity attribute Swagger2 annotation
        gc.setSwagger2(true);
        mpg.setGlobalConfig(gc);

        // mysql data source configuration
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/mall?serverTimezone=GMT+8 & amp;characterEncoding=UTF-8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("*****");
        mpg.setDataSource(dsc);

        // package configuration
        PackageConfig pc = new PackageConfig();
        // pc.setModuleName(scanner("module name")); There is a step to enter the module name in the example, but I omitted it.
        //Set the prefix name
        pc.setParent("com.generator");
        mpg.setPackageInfo(pc);

        String myName = scanner("Data name: example (userInfo)");
        String myTitle = scanner("Module name: example (user)");
        // Custom configuration
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // It can be seen as setting up several global variables, which are used to generate better descriptions for your own templates. How to use them in templates ${cfg.myName}
                Map<String, Object> map = new HashMap<>();
                map.put("myName", myName);
                map.put("myTitle", myTitle);
                this.setMap(map);
            }
        };

        // If the template engine is freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // Custom output configuration
        List<FileOutConfig> focList = new ArrayList<>();
        // Custom configuration will be output first
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                //Here is mapper.xml in resources
                return projectPath + "/src/main/resources/mapper/"
                         + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });

        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        //Configure template
        TemplateConfig templateConfig = new TemplateConfig();
        // Configure a custom output template. If you don't write the following code, you will use the default template output.
        // Find the mybatis-plus-generator package in the template location and open the templates. There will also be a picture below.
        templateConfig.setService("templates/service2.java");
        templateConfig.setController("templates/controller2.java");
        templateConfig.setServiceImpl("templates/serviceImpl2.java");
        templateConfig.setMapper("templates/mapper2.java");

        // If there is also code to set the path in the generated xml, I did not set it.
        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        //Strategy configuration, settings such as Luo Feng
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);

        //Select whether there is a parent entity
        String ipt = scanner("Please enter whether to select the parent class entity, 1 means no, otherwise please enter the parent class");
        if (!("1".equals(ipt))) {
            //Set the parent entity
            strategy.setSuperEntityClass(ipt);
        }

        // Whether to use Lombok method
        strategy.setEntityLombokModel(true);
        // Whether to use RestController
        strategy.setRestControllerStyle(true);
        //Public 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");

        // Enter the relevant name
        strategy.setInclude(scanner("Table name, multiple English commas separated").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

}

Default template location

Run the example

Put the template code last

Put the template into templates under resources controller2.java.ftl

package ${package.Controller};
// Please change this place yourself and change it to your own path.
import com.generator.entity.RespBody;

import com.generator.entity.${entity};
import com.generator.service.${table.serviceName};

import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage>
import ${superControllerClassPackage};
</#if>

/**
 * <p>
    * ${table.comment!} front-end controller
    *</p>
 *
 * @author ${author}
 * @since ${date}
 */
@Api(tags = "${table.controllerName}", description = "${cfg.myTitle}Management")
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@RequestMapping("<#if package.ModuleName>/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle>${controllerMappingHyphen}<#else>${table.entityPath}</ #if>")
<#if kotlin>
class ${table.controllerName}<#if superControllerClass> : ${superControllerClass}()</#if>
<#else>
    <#if superControllerClass>
public class ${table.controllerName} extends ${superControllerClass} {
    <#else>
public class ${table.controllerName} {
    </#if>

    @Autowired
    private ${table.serviceName} ${cfg.myName}Service;

    @ApiOperation("Query ${cfg.myTitle}")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public RespBody find${entity}(${entity} ${cfg.myName},
                                 @RequestParam(value = "pageStart",defaultValue = "1")Integer pageStart,
                                 @RequestParam(value = "pageSize", defaultValue = "10")Integer pageSize){
        List<${entity}> ${cfg.myName}List = ${cfg.myName}Service.find${entity}(${cfg.myName}, pageStart, pageSize);
        PageInfo<${entity}> pageInfo = new PageInfo<>(${cfg.myName}List);
        return RespBody.ok(pageInfo);
    }

    @ApiOperation("Add ${cfg.myTitle}")
    @RequestMapping(value = "/insert", method = RequestMethod.POST)
    public RespBody insert${entity}(${entity} ${cfg.myName}) {
        int result = ${cfg.myName}Service.insert${entity}(${cfg.myName});
        if (result == 1) {
            return RespBody.ok();
        }
        return RespBody.error();
    }

    @ApiOperation("Modify ${cfg.myTitle}")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public RespBody update${entity}(${entity} ${cfg.myName}) {
        int result = ${cfg.myName}Service.update${entity}(${cfg.myName});
        if (result == 1) {
            return RespBody.ok();
        }
        return RespBody.error();
    }

    @ApiOperation("Delete ${cfg.myTitle}")
    @RequestMapping(value = "/delete", method = RequestMethod.DELETE)
    public RespBody update${entity}(@RequestParam("id")int id) {
        int result = ${cfg.myName}Service.delete${entity}(id);
        if (result == 1) {
            return RespBody.ok();
        }
        return RespBody.error();
    }

}
</#if>

service2.java.ftl

package ${package.Service};

import ${package.Entity}.${entity};
import ${superServiceClassPackage};

import java.util.List;

/**
 * <p>
    * ${table.comment!} service class
    *</p>
 *
 * @author ${author}
 * @since ${date}
 */
<#if kotlin>
interface ${table.serviceName} : ${superServiceClass}<${entity}>
<#else>
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {

    /**
     * Find ${cfg.myName}
     * @param ${cfg.myName}
     * @param pageStart
     * @param pageSize
     * @return
     */
    List<${entity}> find${entity}(${entity} ${cfg.myName}, Integer pageStart, Integer pageSize);

    /**
     * Add ${cfg.myName}
     * @param ${cfg.myName}
     * @return
     */
    int insert${entity}(${entity} ${cfg.myName});

    /**
     * Modify ${cfg.myName}
     * @param ${cfg.myName}
     * @return
     */
    int update${entity}(${entity} ${cfg.myName});

    /**
     * Delete ${cfg.myName}
     * @param id
     * @return
     */
    int delete${entity}(int id);

}
</#if>

serviceImpl2.java.ftl

package ${package.ServiceImpl};

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;

/**
 * <p>
    * ${table.comment!} service implementation class
    *</p>
 *
 * @author ${author}
 * @since ${date}
 */
@Service
<#if kotlin>
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {

}
<#else>
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {

    @Autowired
    private ${table.mapperName} ${cfg.myName}Mapper;

    @Override
    public List<${entity}> find${entity}(${entity} ${cfg.myName}, Integer pageStart, Integer pageSize) {
        //Expand here according to specific conditions
        QueryWrapper<${entity}> queryWrapper=new QueryWrapper<>(${cfg.myName});
        PageHelper.startPage(pageStart,pageSize);
        return ${cfg.myName}Mapper.selectList(queryWrapper);
    }

    @Override
    public int insert${entity}(${entity} ${cfg.myName}) {
        return ${cfg.myName}Mapper.insert(${cfg.myName});
    }

    @Override
    public int update${entity}(${entity} ${cfg.myName}) {
        return ${cfg.myName}Mapper.updateById(${cfg.myName});
    }

    @Override
    public int delete${entity}(int id) {
        return ${cfg.myName}Mapper.deleteById(id);
    }

}
</#if>

mapper2.java.ftl

package ${package.Mapper};

import ${package.Entity}.${entity};
import ${superMapperClassPackage};
import org.springframework.stereotype.Repository;

/**
 * <p>
    * ${table.comment!} Mapper interface
    *</p>
 *
 * @author ${author}
 * @since ${date}
 */
<#if kotlin>
interface ${table.mapperName} : ${superMapperClass}<${entity}>
<#else>
@Repository
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {

}
</#if>

Going a step further, you still need to read the official document Mybatis-plus to use the relevant APIs.

This article is published by OpenWrite, a blog posting platform!