MybatisPlusGenerator自定义模板生成文件

MybatisPlusGenerator自定义模板生成文件

本文章按照MybatisPlusGenerator规范,并自定义模版生成对应的Controller,IService,ServiceImpl,Entity,Mapper,Mapper.xml

依赖包引入

		<!--数据库驱动 可以根据需要自行调整-->
        <dependency>
            <groupId>com.oracle.database.jdbc</groupId>
            <artifactId>ojdbc8</artifactId>
            <version>12.2.0.1</version>
        </dependency>

        <!--Mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!--mybatis-plus逆向工程-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!--freemarker-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!--Velocity引擎模板-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>
        <!--Lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

实现类源码

package com.example.mybatisdemo;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.fill.Property;

import java.util.Collections;
import java.util.Scanner;

/**
 * @author : Doug Liang
 * @date : 2024/8/23 14:11
 * @version: 1.0
 * @description:
 */
public class MybatisPlusGeneratorNew {


    protected static String URL = "jdbc:oracle:thin:@192.168.137.12:1521:yscrmora";
    protected static String USERNAME = "yscrmora";
    protected static String PASSWORD = "oracle";

    protected static DataSourceConfig DATA_SOURCE_CONFIG = new DataSourceConfig.Builder(URL, USERNAME,
            PASSWORD).build();


    public static void main(String[] args) {


        System.out.println("请输入表名 , 多个英文逗号分隔");
        String[] tableNames = new Scanner(System.in).next().split(",");

        for (String tableName : tableNames) {

            AutoGenerator generator = new AutoGenerator(DATA_SOURCE_CONFIG);

            // 全局配置
            GlobalConfig globalConfig = new GlobalConfig.Builder()
                    .fileOverride() // 如果文件存在,是否覆盖
                    .outputDir(System.getProperty("user.dir") + "/src/main/java") // 生成文件的输出目录
                    // .enableSwagger() // 是否开启Swagger2
                    .commentDate("yyyy-MM-dd") // 注释中的日期格式
                    .dateType(DateType.TIME_PACK) // 时间类型,默认使用java.util.Date
                    .author("DougLiang")
                    .build();

            generator.global(globalConfig);


            // 包配置(PackageConfig)
            PackageConfig packageConfig = new PackageConfig.Builder()
                    .parent("com.tlit.mybatis")
                    .entity("entity")
                    .service("service")
                    .serviceImpl("service.Impl")
                    .controller("controller")
                    .mapper("mapper")
                    .xml("mapper.xml")
                    .pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") + "\\src\\main\\resources\\mapper"))
                    .build();

            generator.packageInfo(packageConfig);

            // 模板配置(TemplateConfig)
            TemplateConfig templateConfig = new TemplateConfig.Builder()
                    .disable(TemplateType.ENTITY) // 禁用实体类的默认模板
                    .entity("/templates/entity.java") // 自定义实体类模板文件路径
                    .service("/templates/service.java") // 自定义服务接口模板文件路径
                    .serviceImpl("/templates/serviceImpl.java") // 自定义服务实现类模板文件路径
                    .mapper("/templates/mapper.java") // 自定义Mapper接口模板文件路径
                    .mapperXml("/templates/mapper.xml") // 自定义XML映射文件模板文件路径
                    .controller("/templates/controller.java") // 自定义控制器类模板文件路径
                    .build();

            generator.template(templateConfig);

            // 策略配置
            StrategyConfig strategyConfig = new StrategyConfig.Builder()
                    .enableCapitalMode() // 开启大写命名
                    .enableSkipView() // 是否跳过视图
                    .disableSqlFilter() // 禁用 SQL 过滤器
                    .addInclude(tableName) // 需要包含的表名,使用正则表达式
                    .build();


            // 实体配置
            strategyConfig.entityBuilder()
//                    .disableSerialVersionUID() // 禁用 serialVersionUID
                    .enableChainModel() // 开启链式模型
                    .enableLombok() // 开启Lombok
                    .enableRemoveIsPrefix() // 移除字段名中的is前缀
                    .enableTableFieldAnnotation() // 开启字段注解
                    .enableActiveRecord() // 开启ActiveRecord模式
                    .versionColumnName("version") // 乐观锁字段名
                    .versionPropertyName("version") // 乐观锁属性名
                    .logicDeleteColumnName("deleted") // 逻辑删除字段名
                    .logicDeletePropertyName("deleted") // 逻辑删除属性名
//                    .naming(NamingStrategy.underline_to_camel) // 命名策略:不改变原始表名
//                    .columnNaming(NamingStrategy.underline_to_camel) // 字段命名策略:下划线转驼峰
                    .addTableFills(new Column("create_time", FieldFill.INSERT)) // 添加表填充字段
                    .addTableFills(new Property("update_time", FieldFill.INSERT_UPDATE)) // 添加表填充属性
//                    .idType(IdType.AUTO) // 主键类型:自增
//                    .formatFileName(formatTableName) // 文件名格式化
                    .build();

            // 根据名字取选择是否要格式化表名 我这里表名是XW_*
            String formatTableName = toCamelCase(tableName.substring(3));

            // 控制器配置
            strategyConfig.controllerBuilder()
                    .enableRestStyle() // 开启RestController风格
                    .formatFileName(formatTableName + "Controller") // 控制器文件名格式化
                    .build();

            // 服务配置
            strategyConfig.serviceBuilder()
                    .formatServiceFileName("I" + formatTableName + "Service") // 服务接口文件名格式化
                    .formatServiceImplFileName(formatTableName + "ServiceImpl") // 服务实现类文件名格式化
                    .superServiceImplClass("I" + formatTableName + "Service") // 设置父类为空,即不继承任何父类
                    .build();

            tableName = toCamelCase(tableName);
            // Mapper配置
            strategyConfig.mapperBuilder()
                    .superClass(BaseMapper.class) // Mapper接口的父类
                    .enableMapperAnnotation() // 开启Mapper注解
                    .enableBaseResultMap() // 开启基本结果映射
                    .enableBaseColumnList() // 开启基本列映射
                    .formatMapperFileName(tableName + "Mapper") // Mapper接口文件名格式化
                    .formatXmlFileName(tableName + "Mapper"); // XML映射文件名格式化

            generator.strategy(strategyConfig);

            generator.execute();
        }

    }
    public static String toCamelCase(String s) {
        StringBuilder camelCaseStr = new StringBuilder();
        String[] parts = s.split("_");
        for (String part : parts) {
            camelCaseStr.append(toProperCase(part));
        }
        return camelCaseStr.toString();
    }

    public static String toProperCase(String s) {
        return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase();
    }

}

模版文件

根据上面的源码我们定义的模版文件实在resource/templates/ 文件夹下,此时只会读取我们定义的文件模版,模板文件格式我这里使用的是vm格式的,默认会根据VelocityTemplateEngine读取,无需自己再添加后缀的格式,所以在上面的源码中定义读取的模版文件里,并没有将文件以.vm结尾。对应读取的源码也给大家看一下,无需大家再写。

    public @NotNull String templateFilePath(@NotNull String filePath) {
        String dotVm = ".vm";
        return filePath.endsWith(".vm") ? filePath : filePath + ".vm";
    }

下面是我根据项目需要做的一些自定义模板,供大家参考使用

文件名:entity.java.vm

package ${package.Entity};

#foreach($pkg in ${table.importPackages})
import ${pkg};
#end
#if(${entityLombokModel})
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
#if(${chainModel})
import lombok.experimental.Accessors;
#end
#end

/**
 * <p>
 * $!{table.comment} ${entity}实体类
 * </p>
 * @author ${author}
 * @since ${date}
 */
#if(${entityLombokModel})
@SuppressWarnings("all")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
#end
#if(${table.convert})
@TableName("${table.name}")
#end
#if(${swagger2})
@ApiModel(value="${entity}对象", description="$!{table.comment}")
#end
#if(${superEntityClass})
public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end implements Serializable {
#elseif(${activeRecord})
public class ${entity} extends Model<${entity}> implements Serializable {
#else
public class ${entity} implements Serializable {
#end

#if(${entitySerialVersionUID})
    private static final long serialVersionUID = 1L;
#end
## ----------  BEGIN 字段循环遍历  ----------
#foreach($field in ${table.fields})

#if(${field.keyFlag})
#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")
    /**
     * ${field.comment}
     */
#end
#if(${field.keyFlag})
## 主键
#if(${field.keyIdentityFlag})
    @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
  #elseif(!$null.isNull(${idType}) && "$!idType" != "")
    @TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
  #elseif(${field.convert})
    @TableId("${field.annotationColumnName}")
#end
## 普通字段
#elseif(${field.fill})
## -----   存在字段填充设置   -----
  #if(${field.convert})
    @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
  #else
    @TableField(fill = FieldFill.${field.fill})
  #end

#elseif(${field.convert})
    @TableField("${field.annotationColumnName}")
#end
## 乐观锁注解
#if(${versionFieldName}==${field.name})
    @Version
#end
## 逻辑删除注解
#if(${logicDeleteFieldName}==${field.name})
    @TableLogic
#end
    private ${field.propertyType} ${field.propertyName};
#end
## ----------  END 字段循环遍历  ----------

#if(!${entityLombokModel})
#foreach($field in ${table.fields})
  #if(${field.propertyType.equals("boolean")})
    #set($getprefix="is")
  #else
    #set($getprefix="get")
  #end
    public ${field.propertyType} ${getprefix}${field.capitalName}() {
        return ${field.propertyName};
    }
  #if(${chainModel})
    public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
  #else
    public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
  #end
        this.${field.propertyName} = ${field.propertyName};
  #if(${chainModel})
        return this;
  #end
    }
#end
## --foreach end---
#end
## --end of #if(!${entityLombokModel})--
#if(${entityColumnConstant})
  #foreach($field in ${table.fields})
    public static final String ${field.name.toUpperCase()} = "${field.name}";
  #end
#end
#if(!${entityLombokModel})
    @Override
    public String toString() {
        return "${entity}{" +
  #foreach($field in ${table.fields})
    #if($!{foreach.index}==0)
        "${field.propertyName}=" + ${field.propertyName} +
    #else
        ", ${field.propertyName}=" + ${field.propertyName} +
    #end
  #end
        "}";
    }
#end
    /**
     * 当前页码
     */
    @TableField(exist = false)
    private long pageNo;

    /**
     * 每页大小
     */
    @TableField(exist = false)
    private long pageSize;
}

文件名:controller.java.vm

package ${package.Controller};

import ${package.Service}.${table.serviceName};
import ${package.Entity}.${entity};
import com.tlcb.pf.web.util.PageView;
import com.tlit.platform.core.ViewResult;
import com.tlit.platform.constdef.ConstDef;
import org.apache.ibatis.session.RowBounds;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;

/**
 * <p>
 * $!{table.comment} 前端控制器
 * </p>
 * @author ${author}
 * @date ${date}
 * @since   1.0.0
 */
@SuppressWarnings("all")
@Controller
@RequestMapping("/app/view/${table.entityPath}")
public class ${table.controllerName} {

    private static final Logger logger = LoggerFactory.getLogger(${table.controllerName}.class);

    @Autowired
    private ${table.serviceName} ${table.entityPath}Service;

    @RequestMapping("/insert")
    @ResponseBody
    @Transactional
    public ViewResult insert(@RequestBody ${entity} ${table.entityPath}, HttpServletRequest request) {
        ViewResult result = new ViewResult();
        ${table.entityPath}Service.insert(${table.entityPath});
        result.setResult(ConstDef.ViewResult.SUCCESS);
        return result;
    }

    @RequestMapping("/delete")
    @ResponseBody
    @Transactional
    public ViewResult delete(@RequestParam("id") String id, HttpServletRequest request) {
        ViewResult result = new ViewResult();
        // TODO: 请填入业务逻辑
        ${table.entityPath}Service.delete(id);
        result.setResult(ConstDef.ViewResult.SUCCESS);
        return result;
    }

    @RequestMapping("/update")
    @ResponseBody
    @Transactional
    public ViewResult update(@RequestBody ${entity} ${table.entityPath}, HttpServletRequest request) {
        ViewResult result = new ViewResult();
        xwCustomerService.update(${table.entityPath});
        result.setResult(ConstDef.ViewResult.SUCCESS);
        return result;
    }

    @GetMapping("/list")
    public PageView list(${entity} ${table.entityPath}, HttpServletRequest request,
                                                      @RequestParam(defaultValue = "1") String pageNow,
                                                      @RequestParam(defaultValue = "10") String pageSize) {

        int pageNowInt = Integer.parseInt(pageNow);
        int pageSizeInt = Integer.parseInt(pageSize);
        // 创建查询对象
        int offset = (pageNowInt - 1) * pageSizeInt;
        int limit = pageNowInt * pageSizeInt;

        RowBounds rowBounds = new RowBounds(offset, limit);
        List<${entity}> data = ${table.entityPath}Service.selectByRowBounds(${table.entityPath},rowBounds);
        Long count = ${table.entityPath}Service.count(${table.entityPath});
        PageView pageView = new PageView(pageNowInt);
        pageView.setRecords(data);
        pageView.setRowCountByPageSize(count, pageSizeInt);
        return pageView;
    }

}

文件名:service.java.vm

package ${package.Service};

import ${package.Entity}.${entity};
import org.apache.ibatis.session.RowBounds;
import java.util.List;

/**
 * <p>
 * $!{table.comment} 服务类
 * </p>
 * @author ${author}
 * @since ${date}
 */
public interface ${table.serviceName} {

    /**
     * 向$!{table.comment}添加一条数据
     * @param ${table.entityPath} 参数
     * @return 影响行数
     */
    int insert(${entity} ${table.entityPath});

    /**
     * 删除$!{table.comment}中一条数据
     * @param id 参数
     * @return 影响行数
     */
    int delete(String id);

    /**
     * 修改$!{table.comment}中一条数据信息
     * @param ${table.entityPath} 参数
     * @return 影响行数
     */
    int update(${entity} ${table.entityPath});

    /**
    *
    * @param ${table.entityPath} 参数
    * @param rowBounds 分页条数对象
    * @return
    */
    List<${entity}> selectByRowBounds(${entity} ${table.entityPath}, RowBounds rowBounds);

     /**
     * @param ${table.entityPath} 参数
     * @return 条数
     */
     Long count(${entity} ${table.entityPath});

}

文件名:serviceImpl.java.vm

package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.session.RowBounds;
import java.util.List;

/**
 * <p>
 * $!{table.comment} 服务实现类
 * </p>
 * @author ${author}
 * @since ${date}
 */
@Service
public class ${table.serviceImplName} implements ${table.serviceName} {

    private static final Logger logger = LoggerFactory.getLogger(${table.serviceImplName}.class);

    @Autowired
    private ${table.mapperName} ${table.entityPath}Mapper;

    @Override
    public int insert(${entity} ${table.entityPath}) {
        return ${table.entityPath}Mapper.insert(${table.entityPath});
    }

    @Override
    public int delete(String id) {

        // 按主键删除
        return ${table.entityPath}Mapper.deleteById(id);
    }

    @Override
    public int update(${entity} ${table.entityPath}) {
        LambdaUpdateWrapper<${entity}> wrapper = new LambdaUpdateWrapper<>();
        // TODO: 条件请自己处理
        return ${table.entityPath}Mapper.update(${table.entityPath}, wrapper);
    }

    @Override
    public List<${entity}> selectByRowBounds(${entity} ${table.entityPath},RowBounds rowBounds){
        // TODO: 条件请自己处理
        return ${table.entityPath}Mapper.selectByCase(rowBounds.getOffset(), rowBounds.getLimit());
    }

    @Override
    public Long count(${entity} ${table.entityPath}){
        return ${table.entityPath}Mapper.count(${table.entityPath});
    }



}

文件名:mapper.java.vm

package ${package.Mapper};

import ${package.Entity}.${entity};
import ${superMapperClassPackage};
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;

/**
 * <p>
 * $!{table.comment} Mapper 接口
 * </p>
 * @author ${author}
 * @since ${date}
 */
@SuppressWarnings("all")
@Mapper
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {

    List<${entity}> selectByCase(@Param("start")int start, @Param("limit")int limit);

    Long count(${entity} ${table.entityPath});

}

文件名:mapper.xml.vm

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

    <select id="count" resultType="long">
        SELECT COUNT (*) FROM ${table.name}
        <include refid="selectPageClause"/>
    </select>

    <select id="selectByCase" resultMap="BaseResultMap">
        select * from (select t.*,rownum r from (
        SELECT * FROM ${table.name}
        <include refid="selectPageClause"/>
        ) t
        where rownum<![CDATA[<]]>=#{limit}) where r<![CDATA[>]]>#{start}
    </select>

    <sql id="selectPageClause">
        <where>
            -- TODO:查询条件请自己添加
        </where>
    </sql>

</mapper>

因为项目需要,生成的mapper.xml中自带了分页逻辑

综上,自定义模板生成完成。实际上还可以用别的模版去做,但是个人觉得使用VelocityTemplateEngine读取时,模版更好处理一点。但是切记不要在模版中直接使用格式化。

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DougLiang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值