MyBatisPlus3--freemarker自定义模板

MyBatisPlus3–freemarker自定义模板

导包

 	<!--MyBatisPlus依赖模块-->
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.3.2</version>
    </dependency>
    <!--MyBatisPlus代码生成器-->
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-generator</artifactId>
      <version>3.3.2</version>
    </dependency>
    <!-- freemarker模板-->
    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.29</version>
    </dependency>

找到导入的包选中templates包,复制所有的ftl结尾的文件。粘贴到resources下。

MyBatisPlus3--freemarker自定义模板_第1张图片
MyBatisPlus3--freemarker自定义模板_第2张图片
1.打开controller.java.ftl设置自定义布局。

package ${package.Controller};

import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};
import com.自己的工具包.RetJson;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

<#if restControllerStyle>
<#else>
 import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage??>
 import ${superControllerClassPackage};
</#if>


import javax.validation.Valid;
import java.util.List;

/**
* 

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

* * @author ${author} * @since ${date} */
@Api(tags = "${table.comment}") <#if restControllerStyle> @RestController <#else> @Controller </#if> @RequestMapping("<#if package.ModuleName??>/${package.ModuleName}/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}") <#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} ${table.serviceName?uncap_first}; @ApiOperation(value = "${table.comment}分页列表", response = ${entity}.class) @ApiImplicitParams({ @ApiImplicitParam(name = "page", value = "页面", dataType = "Long"), @ApiImplicitParam(name = "size", value = "页面数据量", dataType = "Long"), @ApiImplicitParam(name = "sort", value = "排序方式排序[true:正序; false:倒序]", dataType = "Boolean"), @ApiImplicitParam(name = "sortName", value = "排序字段,参照返回字段", dataType = "String")}) @PostMapping(value = "/page") public Object list(@Valid @RequestBody ${entity} param) { Object data = ${table.serviceName?uncap_first}.page(param); return RetJson.ok(data); } @ApiOperation(value = "${table.comment}详情", response = ${entity}.class) @GetMapping(value = "/info/{id}") public Object info(@PathVariable Long id) { Object data = ${table.serviceName?uncap_first}.info(id); return RetJson.ok(data); } @ApiOperation(value = "${table.comment}新增") @PostMapping(value = "/add") public Object add(@Valid @RequestBody ${entity} param) { ${table.serviceName?uncap_first}.add(param); return RetJson.ok(); } @ApiOperation(value = "${table.comment}修改") @PostMapping(value = "/modify") public Object modify(@Valid @RequestBody ${entity} param) { ${table.serviceName?uncap_first}.modify(param); return RetJson.ok(); } @ApiOperation(value = "${table.comment}删除(单个条目)") @GetMapping(value = "/remove/{id}") public Object remove(@PathVariable Long id) { ${table.serviceName?uncap_first}.remove(id); return RetJson.ok(); } @ApiOperation(value = "${table.comment}删除(多个条目)") @PostMapping(value = "/removes") public Object removes(@Valid @RequestBody List<Long> ids) { ${table.serviceName?uncap_first}.removes(ids); return RetJson.ok(); } } </#if>

2.下面依次类推 service.java.ftl

package ${package.Service};

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

import java.util.List;

/**
* 

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

* * @author ${author} * @since ${date} */
<#if kotlin> interface ${table.serviceName} : ${superServiceClass}<${entity}> <#else> public interface ${table.serviceName} extends ${superServiceClass}<${entity}> { /** * ${table.comment!}分页列表 * @param param 根据需要进行传值 * @return */ IPage<${entity}> page(${entity} param); /** * ${table.comment!}详情 * @param id * @return */ ${entity} info(Long id); /** * ${table.comment!}新增 * @param param 根据需要进行传值 * @return */ void add(${entity} param); /** * ${table.comment!}修改 * @param param 根据需要进行传值 * @return */ void modify(${entity} param); /** * ${table.comment!}删除(单个条目) * @param id * @return */ void remove(Long id); /** * 删除(多个条目) * @param ids * @return */ void removes(List<Long> ids); } </#if>
  1. serviceImpl.java.ftl
package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.自己的工具包.RetJson;
import com.自己的工具包.RetCode;
import com.自己的工具包.PageUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

/**
* 

* ${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} { @Autowired private PageUtils pageUtils; /** * ${table.comment!}分页列表 * @param param 根据需要进行传值 * @return */ @Override public IPage<${entity}> page(${entity} param) { QueryWrapper<${entity}> queryWrapper = new QueryWrapper<>(); queryWrapper.lambda() <#list table.fields as field> // ${field.comment} <#if !entityLombokModel> <#if field.propertyType == "Boolean"> <#assign getprefix="is"/> <#else> <#assign getprefix="get"/> </#if> <#if field.propertyType == "String"> .eq(!StringUtils.isEmpty(param.${getprefix}${field.capitalName}()), ${entity}::${getprefix}${field.capitalName}, param.${getprefix}${field.capitalName}()) <#else> .eq(param.${getprefix}${field.capitalName}() != null, ${entity}::${getprefix}${field.capitalName}, param.${getprefix}${field.capitalName}()) </#if> <#else> <#if field.propertyType == "String"> .eq(!StringUtils.isEmpty(param.get${field.capitalName}()), ${entity}::get${field.capitalName}, param.get${field.capitalName}()) <#else> .eq(param.get${field.capitalName}() != null, ${entity}::get${field.capitalName}, param.get${field.capitalName}()) </#if> </#if> </#list>; IPage<${entity}> page = page(pageUtils.page(), queryWrapper); return page; } /** * ${table.comment!}详情 * @param id * @return */ @Override public ${entity} info(Long id) { return getById(id); } /** * ${table.comment!}新增 * @param param 根据需要进行传值 * @return */ @Override public void add(${entity} param) { save(param); } /** * ${table.comment!}修改 * @param param 根据需要进行传值 * @return */ @Override public void modify(${entity} param) { updateById(param); } /** * ${table.comment!}删除(单个条目) * @param id * @return */ @Override public void remove(Long id) { removeById(id); } /** * ${table.comment!}删除(多个条目) * @param ids * @return */ @Override public void removes(List<Long> ids) { removeByIds(ids); } } </#if>

4.创建配置类Generator.java

package com.自己工具类.util;

import com.baomidou.mybatisplus.annotation.DbType;
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.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.FileType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
 * TODO: 类描述
 *
 * @author ZHANG
 * @email 
 * @date 2020/6/4 11:29
 */
public class Generator {
    /** 作者 */
    private static String AUTHOR = "zhang";
    /** 生成的实体类忽略表前缀: 不需要则置空 */
    private static String ENTITY_IGNORE_PREFIX = "";
    /** 表名 */
    private static String[] TABLES = {
            "emp",
    };


    // 各层文件输出到模块, 没有则置空
    /** Entity.java, Mapper.java, Mapper.xml输出模块路径 */
    private static String DAO_OUTPUT_MODULE = "";
    /** mapper.xml输出模块路径(需要注意放置的位置:默认从模块/src/main下开始) */
    private static String XML_OUTPUT_MODULE = "";
    /** IService.java, serviceImpl.java输出模块路径 */
    private static String SERVICE_OUTPUT_MODULE = "";
    /** Controller.java输出模块路径 */
    private static String Controller_OUTPUT_MODULE = "";


    /** 父包名路径(文件输出路径,也是导包的路径) */
    private static String PARENT_PACKAGE_PATH = "/com/自己的父类包";

    // 各层包名
    private static String ENTITY_PATH = "/entity/";
    private static String MAPPER_PATH = "/mapper/";
    private static String XML_PATH = "/resources/mapper/";
    private static String SERVICE_PATH = "/service/";
    private static String SERVICE_IMPL_PATH = "/service/impl/";
    private static String CONTROLLER_PATH = "/controller/";


    // 数据库
    private static String username = "root";
    private static String password = "root";
    private static String url = "jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8&characterEncoding=UTF-8&allowMultiQueries=true";
    private static DbType DB_TYPE = DbType.MYSQL;
    private static String driverClassName = "com.mysql.cj.jdbc.Driver";


    // 自定义输出模板和位置
    // 文件位置输出模式: file output path = projectPath + XX_OUTPUT_PATH  + File
    // XX_OUTPUT_PATH = modulePath + packagePath
    /** entity输出模板 */
    private static String ENTITY_TEMPLATE = "templates/entity.java.ftl";
    private static String ENTITY_OUTPUT_PATH = DAO_OUTPUT_MODULE + "/src/main/java" + PARENT_PACKAGE_PATH + DAO_OUTPUT_MODULE + ENTITY_PATH;
    /** mapper.xml输出模板 */
    private static String XML_TEMPLATE = "templates/mapper.xml.ftl";
    private static String XML_OUTPUT_PATH = DAO_OUTPUT_MODULE + "/src/main" + XML_OUTPUT_MODULE + XML_PATH;
    /** mapper.java输出模板 */
    private static String MAPPER_TEMPLATE = "templates/mapper.java.ftl";
    private static String MAPPER_OUTPUT_PATH = DAO_OUTPUT_MODULE + "/src/main/java" + PARENT_PACKAGE_PATH + DAO_OUTPUT_MODULE + MAPPER_PATH;
    /** service输出模板 */
    private static String SERVICE_TEMPLATE = "templates/service.java.ftl";
    private static String SERVICE_OUTPUT_PATH = SERVICE_OUTPUT_MODULE + "/src/main/java" + PARENT_PACKAGE_PATH + SERVICE_OUTPUT_MODULE + SERVICE_PATH;
    /** serviceImpl输出模板 */
    private static String SERVICE_IMPL_TEMPLATE = "templates/serviceImpl.java.ftl";
    private static String SERVICE_IMPL_OUTPUT_PATH = SERVICE_OUTPUT_MODULE + "/src/main/java" + PARENT_PACKAGE_PATH + SERVICE_OUTPUT_MODULE + SERVICE_IMPL_PATH;
    /** controller输出模板 */
    private static String CONTROLLER_TEMPLATE = "templates/controller.java.ftl";
    private static String CONTROLLER_OUTPUT_PATH = Controller_OUTPUT_MODULE + "/src/main/java" + PARENT_PACKAGE_PATH + Controller_OUTPUT_MODULE + CONTROLLER_PATH;


    public static void main(String[] args) {

        // 全局配置
        GlobalConfig globalConfig = globalConfig();
        // 数据源配置
        DataSourceConfig dataSourceConfig = dataSourceConfig();
        // 策略配置
        StrategyConfig strategyConfig = strategyConfig();
        // 包配置
        PackageConfig packageConfig = packageConfig();
        // 模板配置
        TemplateConfig templateConfig = templateConfig();
        // 自定义配置
        InjectionConfig injectionConfig = injectionConfig();

        // 执行
        new AutoGenerator().setGlobalConfig(globalConfig)
                .setDataSource(dataSourceConfig)
                .setStrategy(strategyConfig)
                .setPackageInfo(packageConfig)
                // 因为使用了自定义模板,所以需要把各项置空否则会多生成一次
                .setTemplate(templateConfig)
                // 使用的模板引擎,如果不是默认模板引擎则需要添加模板依赖到pom
                .setTemplateEngine(new FreemarkerTemplateEngine())
                .setCfg(injectionConfig)
                .execute();
    }

    /**
     * 全局配置
     */
    private static GlobalConfig globalConfig() {
        return new GlobalConfig()
                // 打开文件
                .setOpen(false)
                // 文件覆盖
                .setFileOverride(true)
                // 开启activeRecord模式
                .setActiveRecord(true)
                // XML ResultMap: mapper.xml生成查询映射结果
                .setBaseResultMap(true)
                // XML ColumnList: mapper.xml生成查询结果列
                .setBaseColumnList(true)
                // swagger注解; 须添加swagger依赖
                .setSwagger2(true)
                // 作者
                .setAuthor(AUTHOR);
                // 设置实体类名称
                //.setEntityName("");
    }

    /**
     * 数据源配置
     */
    private static DataSourceConfig dataSourceConfig() {
        return new DataSourceConfig()
                // 数据库类型
                .setDbType(DB_TYPE)
                // 连接驱动
                .setDriverName(driverClassName)
                // 地址
                .setUrl(url)
                // 用户名
                .setUsername(username)
                // 密码
                .setPassword(password);
    }

    /**
     * 策略配置
     */
    private static StrategyConfig strategyConfig() {
        return new StrategyConfig()
                // 表名生成策略:下划线连转驼峰
                .setNaming(NamingStrategy.underline_to_camel)
                // 表字段生成策略:下划线连转驼峰
                .setColumnNaming(NamingStrategy.underline_to_camel)
                // 需要生成的表
                .setInclude(TABLES)
                // 生成controller
                .setRestControllerStyle(true)
                // 去除表前缀
                .setTablePrefix(ENTITY_IGNORE_PREFIX)
                // controller映射地址:驼峰转连字符
                .setControllerMappingHyphenStyle(true)
                // 是否启用builder 模式
                .setEntityBuilderModel(true)
                // 是否为lombok模型; 需要lombok依赖
                .setEntityLombokModel(true)
                // 生成实体类字段注解
                .setEntityTableFieldAnnotationEnable(true);
    }

    /**
     * 包配置
     * 设置包路径用于导包时使用,路径示例:com.path
     */
    private static PackageConfig packageConfig() {

        String entity = DAO_OUTPUT_MODULE + ENTITY_PATH;
        String mapper = DAO_OUTPUT_MODULE + MAPPER_PATH;
        String xml = DAO_OUTPUT_MODULE + XML_PATH;
        String service = SERVICE_OUTPUT_MODULE + SERVICE_PATH;
        String serviceImpl = SERVICE_OUTPUT_MODULE + SERVICE_IMPL_PATH;
        String controller = Controller_OUTPUT_MODULE + CONTROLLER_PATH;

        return new PackageConfig()
                // 父包名
                .setParent(PARENT_PACKAGE_PATH.replace('/', '.').substring(1))
                .setEntity(entity.replace('/', '.').substring(1, entity.length()-1))
                .setMapper(mapper.replace('/', '.').substring(1, mapper.length()-1))
                .setXml(xml.replace('/', '.').substring(1, xml.length()-1))
                .setService(service.replace('/', '.').substring(1, service.length()-1))
                .setServiceImpl(serviceImpl.replace('/', '.').substring(1, serviceImpl.length()-1))
                .setController(controller.replace('/', '.').substring(1, controller.length()-1));
    }

    /**
     * 模板配置
     */
    private static TemplateConfig templateConfig() {
        return new TemplateConfig()
                // 置空后方便使用自定义输出位置
                .setEntity(null)
                .setXml(null)
                .setMapper(null)
                .setService(null)
                .setServiceImpl(null)
                .setController(null);
    }

    /**
     * 自定义配置
     */
    private static InjectionConfig injectionConfig() {
        return new InjectionConfig() {
            @Override
            public void initMap() {
                // 注入配置
            }
        }
                // 判断是否创建文件
                .setFileCreate(new IFileCreate() {
                    @Override
                    public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {

                        // 检查文件目录,不存在自动递归创建
                        checkDir(filePath);

                        // 指定需要覆盖的文件
                        // 文件结尾名字参照 全局配置 中对各层文件的命名,未修改为默认值
                        if (isExists(filePath) && (!filePath.endsWith("Mapper.xml") && !filePath.endsWith("Dao.java") && !filePath.endsWith("Mapper.java"))) {
                            return false;
                        }

                        return true;
                    }
                })
                // 自定义输出文件
                .setFileOutConfigList(fileOutConfigList());
    }

    /**
     * 自定义输出文件配置
     */
    private static List<FileOutConfig> fileOutConfigList() {
        List<FileOutConfig> list = new ArrayList<>();
        // 当前项目路径
        final String projectPath = System.getProperty("user.dir");

        // 实体类文件输出
        list.add(new FileOutConfig(ENTITY_TEMPLATE) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return projectPath + ENTITY_OUTPUT_PATH + tableInfo.getEntityName() + StringPool.DOT_JAVA;
            }
        });
        // mapper xml文件输出
        list.add(new FileOutConfig(XML_TEMPLATE) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return projectPath + XML_OUTPUT_PATH + tableInfo.getMapperName() + StringPool.DOT_XML;
            }
        });
        // mapper文件输出
        list.add(new FileOutConfig(MAPPER_TEMPLATE) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return projectPath + MAPPER_OUTPUT_PATH + tableInfo.getMapperName() + StringPool.DOT_JAVA;
            }
        });
        // service文件输出
        list.add(new FileOutConfig(SERVICE_TEMPLATE) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return projectPath + SERVICE_OUTPUT_PATH + tableInfo.getServiceName() + StringPool.DOT_JAVA;
            }
        });
        // service impl文件输出
        list.add(new FileOutConfig(SERVICE_IMPL_TEMPLATE) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return projectPath + SERVICE_IMPL_OUTPUT_PATH + tableInfo.getServiceImplName() + StringPool.DOT_JAVA;
            }
        });
        // controller文件输出
        list.add(new FileOutConfig(CONTROLLER_TEMPLATE) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                return projectPath + CONTROLLER_OUTPUT_PATH + tableInfo.getControllerName() + StringPool.DOT_JAVA;
            }
        });

        return list;
    }

    /**
     * 判断文件是否存在
     * @param path 路径
     * @return
     */
    private static boolean isExists(String path) {
        File file = new File(path);
        return file.exists();
    }
}

5补发一下PageUtils的代码

import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

@Component
public class PageUtils {
    // 页面
    private static final String PAGE_STR = "current";
    private static final Integer DEFAULT_PAGE = 1;
    // 页面数据数量
    private static final String SIZE_STR = "size";
    private static final Integer DEFAULT_SIZE = 10;
    // 排序 是否正序排列,默认 true
    private static final String SORT_STR = "sort";
    private static final Boolean DEFAULT_SORT = true;
    private static final String SORT_NAME_STR = "sortName";

    @Autowired
    private HttpServletRequest request;

    /**
     * 获取分页数据
     */
    public Page page(){

        Page page = new Page();
        page.setCurrent(getPages());
        page.setSize(getSize());
        List<OrderItem> orderItems = getOrders(getSort(),getSortName());
        if(orderItems != null && orderItems.size() > 0){
            page.setOrders(orderItems);
        }

        return page;
    }
    /**
     * 自定义设置分页数据
     */
    public Page getPage(Long pages,Long size,boolean sort,String sortName){

        Page page = new Page();
        if(pages!=null){
            page.setCurrent(pages);
        }
        if(size!=null){
            page.setSize(size);
        }
        List<OrderItem> orderItems = getOrders(sort,sortName);
        if(orderItems != null && orderItems.size() > 0){
            page.setOrders(orderItems);
        }

        return page;
    }
    /**
     * 排序
     */
    private List<OrderItem> getOrders(boolean sort,String sortName){

        // 排序字段
        if(StringUtils.isBlank(sortName)){
            return null;
        }

        List<OrderItem> orderItems = new ArrayList<>();
        OrderItem orderItem = new OrderItem();
        orderItem.setColumn(sortName);
        orderItem.setAsc(sort);

        orderItems.add(orderItem);

        return orderItems;
    }

    /**
     * 获取page参数
     */
    private Integer getPages(){
        String page = request.getParameter(PAGE_STR);
        return StringUtils.isBlank(page) ? DEFAULT_PAGE : Integer.valueOf(page);
    }

    /**
     * 获取size参数
     */
    private Integer getSize(){
        String page = request.getParameter(SIZE_STR);
        return StringUtils.isBlank(page) ? DEFAULT_SIZE : Integer.valueOf(page);
    }

    /**
     * 获取sortName参数
     */
    private String getSortName(){
        return request.getParameter(SORT_NAME_STR);
    }

    /**
     * 获取sort参数 是否正序排列,默认 true
     */
    private boolean getSort(){

        String str = request.getParameter(SORT_STR);

        return StringUtils.isBlank(str) ? DEFAULT_SORT : Boolean.valueOf(str);
    }

}

6.最后run。有不对的请留言,一起学习。

你可能感兴趣的:(MyBatisPlus,generator,java,mybatis,mysql)