Mybatis-plus-mp自定义模板

打开微信扫一扫关注小程序

背景

项目采用kotlin + Maven + SpringBoot + MySql,网上有好多生成JavaBean的代码,我之前使用恒宇少年 - 于起宇ApiBoot中的Mybatis Enhance Codegen生成的实体类,kotlin在调用实体类是会发生错误,如下图,网上查询很多资料,最后确认是因为kotlin在整合Lombok时,编译顺序不一致导致的,所以采用了MyBatis-Plus来解决这个问题。kotlin调用生成的实体类.jpg

安装MyBatis-Plus

详细配置文档请点击MyBatis-Plus进行查看,以下仅为解决上述错误的配置。 pom.xml配置

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

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

        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-reflect</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-kotlin</artifactId>
            <version>2.9.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>

        <!--MySQL-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>

        <!--MyBatis-Plus自动生成代码-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.2.0</version>
        </dependency>

        <!-- velocity 模版引擎 -->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>

        <!--FastJson-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.28</version>
        </dependency>

        <!--整合Shiro安全框架-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--集成jwt实现token认证-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.2.0</version>
        </dependency>

    </dependencies>

    <build>
        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <configuration>
                    <args>
                        <arg>-Xjsr305=strict</arg>
                    </args>
                    <compilerPlugins>
                        <plugin>spring</plugin>
                    </compilerPlugins>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>

        </plugins>
    </build>

</project>

解决方法

  • 通过全局配置
gc.isKotlin = true
  • 自定义代码生成模板

自定义代码模板

自定义Controller.kt模板

package ${package.Controller};

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 *  $!{table.comment} 前端控制器
 *========================
 * Created with IntelliJ IDEA
 * Author:Mr.Su
 * Blog: https://suzf.top/
 * Date:${date}
 * ========================
 */
##if(${restControllerStyle})
@RestController
##else
##@Controller
##end
@RequestMapping(value = "#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end
}
#end

自定义Entity.kt模板

package ${package.Entity};

#foreach($pkg in ${table.importPackages})
import ${pkg};
#end

/**
 *  $!{table.comment}
 *========================
 * Created with IntelliJ IDEA
 * Author:Mr.Su
 * Blog: https://suzf.top/
 * Date:${date}
 * ========================
 */
#if(${table.convert})
@TableName("${table.name}")
#end
#if(${swagger2})
@ApiModel(value="${entity}对象", description="$!{table.comment}")
#end
#if(${superEntityClass})
class ${entity} : ${superEntityClass}#if(${activeRecord})<${entity}>#end() {
#elseif(${activeRecord})
class ${entity} : Model<${entity}>() {
#else
class ${entity} : Serializable {
#end

## ----------  BEGIN 字段循环遍历  ----------
#foreach($field in ${table.fields})
#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
    #if(${swagger2})
    @ApiModelProperty(value = "${field.comment}")
    #else
    /**
     * ${field.comment}
     */
    #end
#end
#if(${field.keyFlag})
## 主键
#if(${field.keyIdentityFlag})
    @TableId(value = "${field.name}", type = IdType.AUTO)
#elseif(!$null.isNull(${idType}) && "$!idType" != "")
    @TableId(value = "${field.name}", type = IdType.${idType})
#elseif(${field.convert})
    @TableId("${field.name}")
#end
## 普通字段
#elseif(${field.fill})
## -----   存在字段填充设置   -----
#if(${field.convert})
    @TableField(value = "${field.name}", fill = FieldFill.${field.fill})
#else
    @TableField(fill = FieldFill.${field.fill})
#end
#elseif(${field.convert})
    @TableField("${field.name}")
#end
## 乐观锁注解
#if(${versionFieldName}==${field.name})
    @Version
#end
## 逻辑删除注解
#if(${logicDeleteFieldName}==${field.name})
    @TableLogic
#end
    #if(${field.propertyType} == "Integer")
    var ${field.propertyName}: Int? = null
    #else
    var ${field.propertyName}: ${field.propertyType}? = null
    #end
#end
## ----------  END 字段循环遍历  ----------


#if(${entityColumnConstant})
    companion object {
#foreach($field in ${table.fields})

        const val ${field.name.toUpperCase()} : String = "${field.name}"

#end
    }

#end
#if(${activeRecord})
    override fun pkVal(): Serializable? {
#if(${keyPropertyName})
        return ${keyPropertyName}
#else
        return null
#end
    }

#end
    override fun toString(): String {
        return "${entity}{" +
#foreach($field in ${table.fields})
#if($!{foreach.index}==0)
        "${field.propertyName}=" + ${field.propertyName} +
#else
        ", ${field.propertyName}=" + ${field.propertyName} +
#end
#end
        "}"
    }
}

自定义Mapper.kt模板

package ${package.Mapper};

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

/**
 *  $!{table.comment} Mapper 接口
 *========================
 * Created with IntelliJ IDEA
 * Author:Mr.Su
 * Blog: https://suzf.top/
 * Date:${date}
 * ========================
 */

interface ${table.mapperName} : ${superMapperClass}<${entity}>

#end

自定义Mapper.xml模板

<?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"/>

#end
#if(${baseResultMap})
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
#foreach($field in ${table.fields})
#if(${field.keyFlag})##生成主键排在第一位
        <id column="${field.name}" property="${field.propertyName}" />
#end
#end
#foreach($field in ${table.commonFields})##生成公共字段
    <result column="${field.name}" property="${field.propertyName}" />
#end
#foreach($field in ${table.fields})
#if(!${field.keyFlag})##生成普通字段
        <result column="${field.name}" property="${field.propertyName}" />
#end
#end
    </resultMap>

#end
#if(${baseColumnList})
    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
#foreach($field in ${table.commonFields})
        ${field.name},
#end
        ${table.fieldNames}
    </sql>

#end
</mapper>

自定义service.kt模板

package ${package.Service};

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

/**
 *  $!{table.comment} 服务类
 *========================
 * Created with IntelliJ IDEA
 * Author:Mr.Su
 * Blog: https://suzf.top/
 * Date:${date}
 * ========================
 */

interface ${table.serviceName} : ${superServiceClass}<${entity}>

#end

自定义serviceImpl.kt模板

package ${package.ServiceImpl};

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

/**
 *  $!{table.comment} 服务实现类
 *========================
 * Created with IntelliJ IDEA
 * Author:Mr.Su
 * Blog: https://suzf.top/
 * Date:${date}
 * ========================
 */
@Service
open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {

}

#end

所有需要自定义模板的文件都新建完成,目录如下: image.png

创建CodeGenerator.kt,用于执行,生成代码文件

fun main(args: Array<String>) {

    val mpg = AutoGenerator()
    val gc = GlobalConfig()
    val projectPath = System.getProperty("user.dir")
    println("代码生成的路径:${projectPath}/src/main/kotlin")
    gc.isFileOverride = true
    gc.outputDir = "$projectPath/src/main/kotlin"
    gc.author = "Mr.Su"
    gc.isOpen = false
    // 自定义文件命名,注意 %s 会自动填充表实体属性!
    gc.controllerName = "%sController"
    gc.serviceName = "%sService"
    gc.serviceImplName = "%sServiceImpl"
    gc.mapperName = "%sMapper"
    gc.xmlName = "%sMapper"
    gc.isKotlin = true
    gc.isBaseResultMap = true
    gc.isBaseColumnList = true
    mpg.globalConfig = gc

    //  使用自定义的模板文件
    val templateConfig = TemplateConfig()
    templateConfig.controller = "templates/controller.java"
    templateConfig.entityKt = "templates/entity.kt"
    templateConfig.mapper = "templates/mapper.java"
    templateConfig.xml = "templates/mapper.xml"
    templateConfig.service = "templates/service.java"
    templateConfig.serviceImpl = "templates/serviceImpl.java"
    mpg.template = templateConfig

    // 数据源配置
    val dsc = DataSourceConfig()
    dsc.url = "jdbc:mysql://localhost:3306/ykpushdata?useUnicode=true&useSSL=false&characterEncoding=utf8"
    // dsc.setSchemaName("public")
    dsc.driverName = "com.mysql.jdbc.Driver"
    dsc.username = "root"
    dsc.password = "root"
    mpg.dataSource = dsc

    // 策略配置
    var strategy = StrategyConfig();
    // strategy.setTablePrefix(new String[] { "sys_" })// 此处可以修改为您的表前缀
    strategy.naming = NamingStrategy.underline_to_camel// 表名生成策略
    strategy.setInclude("user","role")

    strategy.superServiceClass = null
    strategy.superServiceImplClass = null
    strategy.superMapperClass = null
    mpg.strategy = strategy

    // 包配置
    val pc = PackageConfig()
    pc.parent = "suzf.top.kotlinjava"
    pc.controller = "service.controller"
    pc.service = "service.service"
    pc.serviceImpl = "service.service.impl"
    pc.mapper = "common.mapper"
    pc.entity = "common.entity"
    pc.xml = "common.mapper.xml"
    mpg.packageInfo = pc

    // 执行生成
    mpg.execute()
}

运行main方法即可成功生成代码文件

# Java  Kotlin 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×