使用代码生成器快速开发spring boot项目

一、 使用mybatis-plus的代码生成器

1、简介

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。详细说明查看官方文档。

下面我将介绍使用自定义freemarker模板来快速生成各个模块的代码。此代码生成器的代码在github上面,详细说明可以查看源代码。

2、代码结构介绍

代码结构

3、修改数据库的连接配置

修改数据库的连接配置

4、运行MybatisPlusGenerate.java生成代码

运行MybatisPlusGenerate.java生成代码

5、添加mybatis-plus的分页插件

mybatis-plus的分页插件

二、模板文件与代码生成文件介绍

src\main\resources\templates文件夹下面创建如下配置文件

1、mapper.xml.ftl




    <#if enableCache>

        

    
    <#if baseResultMap>

        
            <#list table.fields as field>
                <#if field.keyFlag>
                <#--生成主键排在第一位-->
                    
                
            
            <#list table.commonFields as field>
            <#--生成公共字段 -->
                
            
            <#list table.fields as field>
                <#if !field.keyFlag>
                <#--生成普通字段 -->
                    
                
            
        
    
    <#if baseColumnList>

        
            <#list table.commonFields as field>
                ${field.name},
            
            ${table.fieldNames}
        
    

2、mapper.java.ftl

package ${package.Mapper};

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

/**
* 

* ${table.comment!} Mapper 接口 *

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

3、entity.java.ftl

package ${package.Entity};

<#list table.importPackages as pkg>
    import ${pkg};

<#if swagger2>
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;

<#if entityLombokModel>
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    import lombok.experimental.Accessors;


/**
* 

* ${table.comment!} 实体映射表 *

* * @author ${author} * @since ${date} */ <#if entityLombokModel> @Data <#if superEntityClass??> @EqualsAndHashCode(callSuper = true) <#else> @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) <#if table.convert> @TableName("${table.name}") <#if swagger2> @ApiModel(value="${entity}对象", description="${table.comment!}") <#if superEntityClass??> public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}> { <#elseif activeRecord> public class ${entity} extends Model<${entity}> { <#else> public class ${entity} implements Serializable { <#if entitySerialVersionUID> private static final long serialVersionUID = 1L; <#-- ---------- BEGIN 字段循环遍历 ----------> <#list table.fields as field> <#if field.keyFlag> <#assign keyPropertyName="${field.propertyName}"/> <#if field.comment!?length gt 0> <#if swagger2> @ApiModelProperty(value = "${field.comment}") <#else> /** * ${field.comment} */ <#if field.keyFlag> <#-- 主键 --> <#if field.keyIdentityFlag> @TableId(value = "${field.name}", type = IdType.ASSIGN_ID) <#elseif idType??> @TableId(value = "${field.name}", type = IdType.${idType}) <#elseif field.convert> @TableId("${field.name}") <#-- 普通字段 --> <#elseif field.fill??> <#-- ----- 存在字段填充设置 -----> <#if field.convert> @TableField(value = "${field.name}", fill = FieldFill.${field.fill}) <#else> @TableField(fill = FieldFill.${field.fill}) <#elseif field.convert> @TableField("${field.name}") <#-- 乐观锁注解 --> <#if (versionFieldName!"") == field.name> @Version <#-- 逻辑删除注解 --> <#if (logicDeleteFieldName!"") == field.name> @TableLogic private ${field.propertyType} ${field.propertyName}; <#------------ END 字段循环遍历 ----------> <#if !entityLombokModel> <#list table.fields as field> <#if field.propertyType == "boolean"> <#assign getprefix="is"/> <#else> <#assign getprefix="get"/> public ${field.propertyType} ${getprefix}${field.capitalName}() { return ${field.propertyName}; } <#if entityBuilderModel> public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { <#else> public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { this.${field.propertyName} = ${field.propertyName}; <#if entityBuilderModel> return this; } <#if entityColumnConstant> <#list table.fields as field> public static final String ${field.name?upper_case} = "${field.name}"; <#if activeRecord> @Override protected Serializable pkVal() { <#if keyPropertyName??> return this.${keyPropertyName}; <#else> return null; } <#if !entityLombokModel> @Override public String toString() { return "${entity}{" + <#list table.fields as field> <#if field_index==0> "${field.propertyName}=" + ${field.propertyName} + <#else> ", ${field.propertyName}=" + ${field.propertyName} + "}"; } }

4、service.java.ftl

package ${package.Service};

import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import com.baomidou.mybatisplus.core.metadata.IPage;
/**
* 

* ${table.comment!} 服务类 *

* * @author ${author} * @since ${date} */ <#if kotlin> interface ${table.serviceName} : ${superServiceClass}<${entity}> <#else> public interface ${table.serviceName} extends ${superServiceClass}<${entity}> { /** * 新增 * @param ${entity?uncap_first} {@link ${entity}} * @return {@code boolean} */ boolean create(${entity} ${entity?uncap_first}); /** * 删除 * @param id {@code Long} * @return {@code boolean} */ boolean remove(Long id); /** * 编辑 * @param ${entity?uncap_first} {@link ${entity}} * @return {@code boolean} */ boolean update(${entity} ${entity?uncap_first}); /** * 获取 * @param id {@code Long} * @return {@link ${entity}} */ ${entity} get(Long id); /** * 分页 * @param current {@code int} 页码 * @param size {@code int} 笔数 * @param ${entity?uncap_first} {@link ${entity}} * @return {@code IPage<${entity}>} */ IPage<${entity}> page(int current, int size, ${entity} ${entity?uncap_first}); }

5、serviceImpl.java.ftl

package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
* 

* ${table.comment!} 服务实现类 *

* * @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} { @Override public boolean create(${entity} ${entity?uncap_first}) { return super.save(${entity?uncap_first}); } @Override public boolean remove(Long id) { return super.removeById(id); } @Override public boolean update(${entity} ${entity?uncap_first}) { return super.updateById(${entity?uncap_first}); } @Override public ${entity} get(Long id) { return super.getById(id); } @Override public IPage<${entity}> page(int current, int size, ${entity} ${entity?uncap_first}) { Page<${entity}> page = new Page<>(current, size); LambdaQueryWrapper<${entity}> wrapper = Wrappers.lambdaQuery(${entity?uncap_first}); // TODO 查询 // TODO 排序 return super.page(page, wrapper); } }

6、controller.java.ftl

package ${package.Controller};

import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};
import org.springframework.web.bind.annotation.RequestMapping;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.validation.BindingResult;
import java.util.Objects;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.web.bind.annotation.*;
<#if restControllerStyle>
    import org.springframework.web.bind.annotation.RestController;
<#else>
    import org.springframework.stereotype.Controller;

<#if superControllerClassPackage??>
    import ${superControllerClassPackage};


/**
* 

* ${table.comment!} 前端控制器 *

* * @author ${author} * @since ${date} */ <#if restControllerStyle> @RestController <#else> @Controller @RequestMapping("<#if package.ModuleName??>${package.ModuleName}/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}") <#if kotlin> class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}() <#else> <#if superControllerClass??> public class ${table.controllerName} extends ${superControllerClass} { <#else> public class ${table.controllerName} { @Resource private I${entity}Service ${entity?uncap_first}Service; /** * 新增 * * @param ${entity?uncap_first} {@link ${entity}} * @return {@link ResponseResult} */ @PostMapping("create") public ResponseResult create(@Valid @RequestBody ${entity} ${entity?uncap_first}, BindingResult bindingResult) { // 表单验证 if (bindingResult.hasErrors()) { return ResponseResult.failure(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage()); } // 业务逻辑 boolean created = ${entity?uncap_first}Service.create(${entity?uncap_first}); if (created) { return ResponseResult.success("创建成功"); } return null; } /** * 删除 * * @param ${entity?uncap_first}Id {@code Long} * @return {@link ResponseResult} */ @DeleteMapping("remove/{${entity?uncap_first}Id}") public ResponseResult remove(@PathVariable Long ${entity?uncap_first}Id) { // 业务逻辑 boolean deleted = ${entity?uncap_first}Service.remove(${entity?uncap_first}Id); if (deleted) { return ResponseResult.success("删除成功"); } return null; } /** * 修改 * * @param ${entity?uncap_first} {@link ${entity}} * @return {@link ResponseResult} */ @PutMapping("update") public ResponseResult update(@Valid @RequestBody ${entity} ${entity?uncap_first}, BindingResult bindingResult) { // 表单验证 if (bindingResult.hasErrors()) { return ResponseResult.failure(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage()); } // 业务逻辑 boolean updated = ${entity?uncap_first}Service.update(${entity?uncap_first}); if (updated) { return ResponseResult.success("编辑成功"); } return null; } /** * 获取 * * @param ${entity?uncap_first}Id {@code Long} * @return {@link ResponseResult} */ @GetMapping("get/{${entity?uncap_first}Id}") public ResponseResult get(@PathVariable Long ${entity?uncap_first}Id) { ${entity} ${entity?uncap_first} = ${entity?uncap_first}Service.get(${entity?uncap_first}Id); return ResponseResult.success(${entity?uncap_first}); } /** * 分页 * * @param current {@code int} 页码 * @param size {@code int} 笔数 * @return {@link ResponseResult} */ @GetMapping("page") public ResponseResult page( @RequestParam int current, @RequestParam int size) { ${entity} ${entity?uncap_first} = new ${entity}(); // TODO 查询条件,需要在参数中增加 @RequestParam(required = false) IPage<${entity}> page = ${entity?uncap_first}Service.page(current, size, ${entity?uncap_first}); return ResponseResult.success(page); } }

7、MybatisPlusGenerate.java

package com.demo.generator;

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.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

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

/**
 * @Author edison
 * @Date 2020/06/03 16:23
 * @Description 代码生成器
 **/
public class MybatisPlusGenerate {
    /**
     * 作者
     */
    private static final String AUTHOR = "edison";

    /**
     * JDBC 驱动程序
     */
    private static final String JDBC_DRIVER_NAME = "com.mysql.cj.jdbc.Driver";

    /**
     * JDBC 连接地址
     */
    private static final String JDBC_URL = "jdbc:mysql://localhost:3306/test";

    /**
     * 数据库账号
     */
    private static final String JDBC_USERNAME = "root";

    /**
     * 数据库密码
     */
    private static final String JDBC_PASSWORD = "root";

    /**
     * 要生成的表,用 `,` 分割
     */
    private static final String TABLES = "xy_link";

    /**
     * 工作目录
     */
    private static final String USER_DIR = System.getProperty("user.dir");

    /**
     * 包配置 - 父级目录
     */
    private static final String PACKAGE_PARENT = "com.demo";

    /**
     * 包配置 - 模块目录
     * 注意:如果表前缀与模块命相同,生成时会删除前缀,比如:core_admin 最终构建为 Admin, AdminController ...
     */
    private static final String PACKAGE_MODULE_NAME = "";

    /**
     * 包配置 - 实体类目录,一般领域驱动设计开发的实体称为domain,所以这里命名为domain,也可以使用entity或者自定义
     */
    private static final String PACKAGE_ENTITY = "entity";

    /**
     * 包配置 - 数据访问接口目录
     */
    private static final String PACKAGE_MAPPER = "dao";

    /**
     * 包配置 - 业务处理接口目录
     */
    private static final String PACKAGE_SERVICE = "service";

    /**
     * 包配置 - 业务处理实现目录
     */
    private static final String PACKAGE_SERVICE_IMPL = "service.impl";

    /**
     * 包配置 - 控制器目录
     */
    private static final String PACKAGE_CONTROLLER = "controller";


    /**
     * 全局配置
     *
     * @return {@link GlobalConfig}
     */
    private static GlobalConfig globalConfig() {
        GlobalConfig config = new GlobalConfig();
        config.setOutputDir(USER_DIR + "/src/main/java");
        // 开发人员
        config.setAuthor(AUTHOR);
        // 是否打开输出目录
        config.setOpen(false);
        // XML ResultMap: mapper.xml生成查询映射结果
        config.setBaseResultMap(true);
        // XML ColumnList: mapper.xml生成查询结果列
        config.setBaseColumnList(true);
        // 开启 swagger2 模式,需要添加swagger依赖
        config.setSwagger2(false);

        return config;
    }

    /**
     * 数据源配置
     *
     * @return {@link DataSourceConfig}
     */
    private static DataSourceConfig dataSourceConfig() {
        DataSourceConfig config = new DataSourceConfig();
        config.setUrl(JDBC_URL);
        config.setDriverName(JDBC_DRIVER_NAME);
        config.setUsername(JDBC_USERNAME);
        config.setPassword(JDBC_PASSWORD);
        return config;
    }

    /**
     * 包配置
     *
     * @return {@link PackageConfig}
     */
    private static PackageConfig packageConfig() {
        PackageConfig config = new PackageConfig();
        // 你哪个父目录下创建包
        config.setParent(PACKAGE_PARENT);
        // 设置模块的名字,比如 core,生成效果为 com.demo.core
        config.setModuleName(PACKAGE_MODULE_NAME);
        // 实体类创建在哪个包
        config.setEntity(PACKAGE_ENTITY);
        config.setMapper(PACKAGE_MAPPER);
        config.setService(PACKAGE_SERVICE);
        config.setServiceImpl(PACKAGE_SERVICE_IMPL);
        config.setController(PACKAGE_CONTROLLER);
        return config;
    }

    /**
     * 代码生成模板配置 - Freemarker
     *
     * @return {@link TemplateConfig}
     */
    private static TemplateConfig templateConfig() {
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setEntity("templates/entity.java");
        templateConfig.setMapper("templates/mapper.java");
        templateConfig.setService("templates/service.java");
        templateConfig.setServiceImpl("templates/serviceImpl.java");
        templateConfig.setController("templates/controller.java");
        templateConfig.setXml(null);
        return templateConfig;
    }

    /**
     * 代码生成策略配置
     *
     * @return {@link StrategyConfig}
     */
    private static StrategyConfig strategyConfig() {
        // 策略配置,数据库表配置
        StrategyConfig config = new StrategyConfig();
        // 数据库表映射到实体的命名策略,下划线连转驼峰
        config.setNaming(NamingStrategy.underline_to_camel);
        // 数据库表字段映射到实体类的命名策略,下划线连转驼峰
        config.setColumnNaming(NamingStrategy.underline_to_camel);
        // 实体是否为 lombok 模型
        config.setEntityLombokModel(true);
        config.setInclude(TABLES.split(","));
        // 驼峰转连字符串
        config.setControllerMappingHyphenStyle(true);
        // REST 风格
        config.setRestControllerStyle(true);
        // 表前缀
        config.setTablePrefix(packageConfig().getModuleName() + "_");
        // 实体是否生成 serialVersionUID
        config.setEntitySerialVersionUID(true);
        // 是否生成实体时,生成字段注解
        config.setEntityTableFieldAnnotationEnable(true);
        return config;
    }

    /**
     * 自定义配置
     */
    private static InjectionConfig injectionConfig() {
        InjectionConfig config = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 自定义输出 mapper.xml 到 resources 目录下
        String mapperPath = "/templates/mapper.xml.ftl";
        List focList = new ArrayList<>();

        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(mapperPath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
                return USER_DIR + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper"
                        + StringPool.DOT_XML;
            }
        });

        config.setFileOutConfigList(focList);
        return config;
    }

    public static void main(String[] args) {
        AutoGenerator generator = new AutoGenerator();
        generator.setGlobalConfig(globalConfig());
        generator.setDataSource(dataSourceConfig());
        generator.setPackageInfo(packageConfig());
        generator.setTemplate(templateConfig());
        generator.setTemplateEngine(new FreemarkerTemplateEngine());
        generator.setCfg(injectionConfig());
        generator.setStrategy(strategyConfig());

        generator.execute();
    }

}

8、pom.xml



    4.0.0

    
        org.springframework.boot
        spring-boot-starter-parent
        2.3.0.RELEASE
    

    org.example
    code-generator
    1.0-SNAPSHOT
    jar
    代码生成器

    
        
            edison
            edison
            [email protected]
        
    
    
        3.3.1
        6.1.5.Final
    
    
        
        
            org.springframework.boot
            spring-boot-starter-jdbc
            
                
                    org.apache.tomcat
                    tomcat-jdbc
                
            
        
        
            com.zaxxer
            HikariCP
        
        
            mysql
            mysql-connector-java
        

        
        
            com.baomidou
            mybatis-plus-boot-starter
            ${mybatis-plus.version}
        
        
            com.baomidou
            mybatis-plus-generator
            ${mybatis-plus.version}
        

        
            org.freemarker
            freemarker
        

        
        
            org.projectlombok
            lombok
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.hibernate.validator
            hibernate-validator
            ${hibernate-validator.version}
        
    

    
        generator-code-demo
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
            
            
                org.apache.maven.plugins
                maven-surefire-plugin
                ${maven-surefire-plugin.version}
                
                    
                    true
                    
                        **/*Tests.java
                    
                    
                        **/Abstract*.java
                    
                    
                        file:/dev/./urandom
                        true
                    
                
            
        
    

你可能感兴趣的:(使用代码生成器快速开发spring boot项目)