zoukankan      html  css  js  c++  java
  • SpringBoot

    前言

    AutoGeneratorMyBatis-Plus的代码生成器,通过AutoGenerator可以快速生成EntityMapperMapper XMLServiceController等各个模块的代码,这里介绍下SpringBoot中集成MyBatis-Plus代码生成器CodeGenerator的方式,模板引擎使用Freemarker


    环境

    SpringBoot2.53 + Mybatis-Plus3.3.0


    具体实现

    代码生成器

    • pom.xml
    <!-- MyBatis-Plus从3.0.3之后移除了代码生成器与模板引擎的默认依赖,需要手动添加相关依赖 -->
    <!-- generator -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.3.0</version>
    </dependency>
    
    <!-- freemarker -->
    <dependency>
        <groupId>org.freemarker</groupId>
        <artifactId>freemarker</artifactId>
        <version>2.3.28</version>
    </dependency>
    
    • CodeGenerator.java
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
    import com.baomidou.mybatisplus.core.toolkit.StringUtils;
    import com.baomidou.mybatisplus.generator.AutoGenerator;
    import com.baomidou.mybatisplus.generator.config.*;
    import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
    import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Scanner;
    
    /**
     * 代码生成器
     */
    public class CodeGenerator {
    
        public static void main(String[] args) {
            // 代码生成器
            AutoGenerator mpg = new AutoGenerator();
    
            // 全局配置
            GlobalConfig globalConfig = new GlobalConfig();
            globalConfig
                    .setAuthor("generator@xxx")
                    .setOpen(false)
                    .setFileOverride(false)
                    .setIdType(IdType.AUTO)
                    .setBaseResultMap(true)
                    .setEntityName("%s")
                    .setServiceName("%sService");
            mpg.setGlobalConfig(globalConfig);
    
            // 数据源配置
            DataSourceConfig dataSourceConfig = new DataSourceConfig();
            dataSourceConfig
                    .setUrl("jdbc:mysql://localhost:3306/cms?allowPublicKeyRetrieval=true&useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai")
                    .setDriverName("com.mysql.cj.jdbc.Driver")
                    .setUsername("root")
                    .setPassword("sunday");
            mpg.setDataSource(dataSourceConfig);
    
            // 包名配置
            PackageConfig packageConfig = new PackageConfig();
            packageConfig
                    .setParent("com.coisini.mybatisplus")
                    .setPathInfo(getPathInfo())
                    .setEntity("entity")
                    .setController("controller")
                    .setXml("xml");
            mpg.setPackageInfo(packageConfig);
    
            // 模板配置
            TemplateConfig templateConfig = new TemplateConfig();
            templateConfig
                    .setEntity("/templates/entity.java")
                    .setXml("/templates/mapper.xml")
                    .setController("/templates/controller.java");
            mpg.setTemplate(templateConfig);
    
            // 策略配置
            StrategyConfig strategyConfig = new StrategyConfig();
            strategyConfig
                    .setNaming(NamingStrategy.underline_to_camel)
                    .setSuperEntityClass("com.coisini.mybatisplus.entity.BaseEntity")
                    .setEntitySerialVersionUID(false)
                    .setEntityLombokModel(true)
                    .setRestControllerStyle(true)
                    .setSuperEntityColumns("id", "create_time")
                    .setInclude(scanner("表名,多个英文逗号分割").split(","))
                    .setControllerMappingHyphenStyle(true);
            mpg.setStrategy(strategyConfig);
            mpg.setTemplateEngine(new FreemarkerTemplateEngine());
            mpg.execute();
        }
    
        /**
         * 读取控制台内容
         */
        private static String scanner(String tip) {
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入" + tip + ":");
            if (scanner.hasNext()) {
                String ipt = scanner.next();
                if (StringUtils.isNotBlank(ipt)) {
                    return ipt;
                }
            }
            throw new MybatisPlusException("请输入正确的" + tip + "!");
        }
    
        private static Map<String, String> getPathInfo() {
            Map<String, String> pathInfo = new HashMap<>();
            pathInfo.put(ConstVal.ENTITY_PATH, System.getProperty("user.dir") + "/src/main/java/com/coisini/mybatisplus/entity");
            pathInfo.put(ConstVal.MAPPER_PATH, System.getProperty("user.dir") + "/src/main/java/com/coisini/mybatisplus/mapper");
            pathInfo.put(ConstVal.SERVICE_PATH, System.getProperty("user.dir") + "/src/main/java/com/coisini/mybatisplus/service");
            pathInfo.put(ConstVal.SERVICE_IMPL_PATH, System.getProperty("user.dir") + "/src/main/java/com/coisini/mybatisplus/service/impl");
            pathInfo.put(ConstVal.CONTROLLER_PATH, System.getProperty("user.dir") + "/src/main/java/com/coisini/mybatisplus/controller");
            pathInfo.put(ConstVal.XML_PATH, System.getProperty("user.dir") + "/src/main/resources/mapper");
            return pathInfo;
        }
    }
    

    自定义代码模板

    • 自定义代码模板ControllerEntitymapper-xml,目录如下所示:

    在这里插入图片描述

    • 控制器模板controller.java.ftl
    package ${package.Controller};
    
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.PutMapping;
    import org.springframework.web.bind.annotation.DeleteMapping;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestParam;
    import ${package.Entity}.${entity};
    
    <#if restControllerStyle>
    import org.springframework.web.bind.annotation.RestController;
    <#else>
    import org.springframework.stereotype.Controller;
    </#if>
    <#if superControllerClassPackage??>
    import ${superControllerClassPackage};
    </#if>
    
    /**
    <#if table.comment != "">
     * ${table.comment!}控制器
     *
    </#if>
    * @author ${author}
    * @since ${date}
    */
    <#if restControllerStyle>
    @RestController
    <#else>
    @Controller
    </#if>
    @RequestMapping("/${package.Controller?split(".")?last}<#if package.ModuleName??>/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen?replace("-do", "")}<#else>${table.entityPath?replace("DO", "")}</#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>
    
        @PostMapping("")
        public void create() {
    
        }
    
        @PutMapping("/{id}")
        public void update(@PathVariable Long id) {
    
        }
    
        @DeleteMapping("/{id}")
        public void delete(@PathVariable Long id) {
    
        }
    
        @GetMapping("/{id}")
        public ${entity} get(@PathVariable(value = "id") Long id) {
            return null;
        }
    
    }
    </#if>
    
    • 实体模板entity.java.ftl
    package ${package.Entity};
    
    <#list table.importPackages as pkg>
    <#--子类变量包含id才导入相应的包-->
    <#if (pkg =="com.baomidou.mybatisplus.annotation.IdType" || pkg =="com.baomidou.mybatisplus.annotation.TableId")>
        <#list table.fields as field>
            <#if field.keyFlag>
    import ${pkg};
            </#if>
        </#list>
    <#else>
    import ${pkg};
    </#if>
    </#list>
    <#if swagger2>
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    </#if>
    <#if entityLombokModel>
    import lombok.Data;
    import lombok.EqualsAndHashCode;
    import lombok.experimental.Accessors;
    </#if>
    
    /**
    <#if table.comment != "">
     * ${table.comment!}
     *
    </#if>
     * @author ${author}
     * @since ${date}
     */
    <#if entityLombokModel>
    @Data
        <#if superEntityClass??>
    @EqualsAndHashCode(callSuper = true)
        <#else>
    @EqualsAndHashCode(callSuper = false)
        </#if>
    @Accessors(chain = true)
    </#if>
    <#if table.convert>
    @TableName("${table.name}")
    </#if>
    <#if swagger2>
    @ApiModel(value="${entity}对象", description="${table.comment!}")
    </#if>
    <#if superEntityClass??>
    public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
    <#elseif activeRecord>
    public class ${entity} extends Model<${entity}> {
    <#else>
    public class ${entity} implements Serializable {
    </#if>
    
    <#if entitySerialVersionUID>
        private static final long serialVersionUID = 1L;
    </#if>
    <#-- ----------  BEGIN 字段循环遍历  ---------->
    <#list table.fields as field>
        <#if field.keyFlag>
            <#assign keyPropertyName="${field.propertyName}"/>
        </#if>
    
        <#if field.comment!?length gt 0>
            <#if swagger2>
        @ApiModelProperty(value = "${field.comment}")
            <#else>
        /**
         * ${field.comment}
         */
            </#if>
        </#if>
        <#if field.keyFlag>
            <#-- 主键 -->
            <#if field.keyIdentityFlag>
        @TableId(value = "${field.name}", type = IdType.AUTO)
            <#elseif idType??>
        @TableId(value = "${field.name}", type = IdType.${idType})
            <#elseif field.convert>
        @TableId("${field.name}")
            </#if>
            <#-- 普通字段 -->
        <#elseif field.fill??>
        <#-- -----   存在字段填充设置   ----->
            <#if field.convert>
        @TableField(value = "${field.name}", fill = FieldFill.${field.fill})
            <#else>
        @TableField(fill = FieldFill.${field.fill})
            </#if>
        <#elseif field.convert>
        @TableField("${field.name}")
        </#if>
        <#-- 乐观锁注解 -->
        <#if (versionFieldName!"") == field.name>
        @Version
        </#if>
        <#-- 逻辑删除注解 -->
        <#if (logicDeleteFieldName!"") == field.name>
        @TableLogic
        </#if>
        private ${field.propertyType} ${field.propertyName};
    </#list>
    <#------------  END 字段循环遍历  ---------->
    
    <#if !entityLombokModel>
        <#list table.fields as field>
            <#if field.propertyType == "boolean">
                <#assign getprefix="is"/>
            <#else>
                <#assign getprefix="get"/>
            </#if>
        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}) {
        </#if>
            this.${field.propertyName} = ${field.propertyName};
            <#if entityBuilderModel>
            return this;
            </#if>
        }
        </#list>
    </#if>
    
    <#if entityColumnConstant>
        <#list table.fields as field>
        public static final String ${field.name?upper_case} = "${field.name}";
    
        </#list>
    </#if>
    <#if activeRecord>
        @Override
        protected Serializable pkVal() {
        <#if keyPropertyName??>
            return this.${keyPropertyName};
        <#else>
            return null;
        </#if>
        }
    
    </#if>
    <#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} +
            </#if>
        </#list>
            "}";
        }
    </#if>
    }
    
    • xml模板mapper.xml.ftl
    <?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="${package.Mapper}.${table.mapperName}">
    
    <#if enableCache>
        <!-- 开启二级缓存 -->
        <cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
    
    </#if>
    <#if baseResultMap>
        <!-- 通用查询映射结果 -->
        <resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
    <#list table.fields as field>
    <#if field.keyFlag><#--生成主键排在第一位-->
            <id column="${field.name}" property="${field.propertyName}" />
    </#if>
    </#list>
    <#list table.commonFields as field><#--生成公共字段 -->
        <#if field.keyFlag>
            <id column="${field.name}" property="${field.propertyName}" />
        <#else>
            <result column="${field.name}" property="${field.propertyName}" />
        </#if>
    </#list>
    <#list table.fields as field>
    <#if !field.keyFlag><#--生成普通字段 -->
            <result column="${field.name}" property="${field.propertyName}" />
    </#if>
    </#list>
        </resultMap>
    
    </#if>
    <#if baseColumnList>
        <!-- 通用查询结果列 -->
        <sql id="Base_Column_List">
    <#list table.commonFields as field>
            ${field.name},
    </#list>
            ${table.fieldNames}
        </sql>
    
    </#if>
    </mapper>
    

    测试

    • 新建表
    CREATE TABLE `test` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `title` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
      `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
    
    • 运行CodeGeneratormain方法

    在这里插入图片描述

    • 生成目录文件如下所示:

    在这里插入图片描述


    - End -
    梦想是咸鱼
    关注一下吧
    以上为本篇文章的主要内容,希望大家多提意见,如果喜欢记得点个推荐哦
    作者:Maggieq8324
    本文版权归作者和博客园共有,欢迎转载,转载时保留原作者和文章地址即可。
  • 相关阅读:
    BAT脚本编写要点(1)_特殊字符
    开源爬虫软件汇总
    使用Gradle发布项目到JCenter仓库
    解决Android中,禁止ScrollView内的控件改变之后自动滚动
    理解RESTful架构
    一种为 Apk 动态写入信息的方案
    Proguard配置注解
    使用statsvn统计svn中的代码量
    android如何释放图片缓存
    Git命令参考手册(文本版)
  • 原文地址:https://www.cnblogs.com/maggieq8324/p/15239981.html
Copyright © 2011-2022 走看看