编写重复简单的代码对于每个程序员来说,应该是一件相当烦躁的工作,代码生成器就很好的帮助你解决了这个问题。对于不同的项目,架构多少有些不一样,针对性的生成代码就使用到了模板引擎,freemarker就是一个很不错的模板引擎,使用简单便捷。
下面我们就使用mybatis-plus-genarator+freemarker来配置一个代码生成器:
首先需要引入相关依赖:
<!-- 代码生成器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.2.0</version>
</dependency>
<!-- freemaker引擎 -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
下面是我项目结构中的模板配置和生成器启动类:
Generator.java生成器代码如下:
package com.sinosoft;
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.io.File;
import java.util.ArrayList;
import java.util.List;
public class Generator {
// 数据库 URL
private static final String URL = "jdbc:mysql://****:3306/sc_vas_sit?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true";
// 数据库驱动
private static final String DRIVER_NAME = "com.mysql.cj.jdbc.Driver";
// 数据库用户名
private static final String USERNAME = "***";
// 数据库密码
private static final String PASSWORD = "*****";
// @author 值
private static final String AUTHOR = "***";
// 包的基础路径
private static final String BASE_PACKAGE_URL = "com.example.test";
// xml文件路径
private static final String XML_PACKAGE_URL = "/src/main/resources/mapper/";
// xml 文件模板
private static final String XML_MAPPER_TEMPLATE_PATH = "generator/freemarker/mapper.xml";
// mapper 文件模板
private static final String MAPPER_TEMPLATE_PATH = "generator/freemarker/mapper.java";
// entity 文件模板
private static final String ENTITY_TEMPLATE_PATH = "generator/freemarker/entity.java";
// service 文件模板
private static final String SERVICE_TEMPLATE_PATH = "generator/freemarker/service.java";
// serviceImpl 文件模板
private static final String SERVICE_IMPL_TEMPLATE_PATH = "generator/freemarker/serviceImpl.java";
// controller 文件模板
private static final String CONTROLLER_TEMPLATE_PATH = "generator/freemarker/controller.java";
public static void main(String[] args) {
AutoGenerator generator = new AutoGenerator();
// 全局配置
GlobalConfig globalConfig = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
globalConfig.setOutputDir(projectPath + "\\projectName\\src\\main\\java");
globalConfig.setAuthor(AUTHOR);
globalConfig.setOpen(false);
globalConfig.setFileOverride(false);
generator.setGlobalConfig(globalConfig);
// 数据源配置
DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setUrl(URL);
dataSourceConfig.setDriverName(DRIVER_NAME);
dataSourceConfig.setUsername(USERNAME);
dataSourceConfig.setPassword(PASSWORD);
generator.setDataSource(dataSourceConfig);
// 包配置
PackageConfig packageConfig = new PackageConfig();
packageConfig.setController("controller");
packageConfig.setEntity("entity");
packageConfig.setService("service");
packageConfig.setMapper("mapper");
packageConfig.setModuleName("test");
//packageConfig.setXml("mapper");
packageConfig.setParent(BASE_PACKAGE_URL);
generator.setPackageInfo(packageConfig);
// 配置自定义代码模板
TemplateConfig templateConfig = new TemplateConfig();
//templateConfig.setXml(XML_MAPPER_TEMPLATE_PATH);
templateConfig.setXml(null);
templateConfig.setMapper(MAPPER_TEMPLATE_PATH);
//templateConfig.setEntity(ENTITY_TEMPLATE_PATH);
templateConfig.setService(SERVICE_TEMPLATE_PATH);
templateConfig.setServiceImpl(SERVICE_IMPL_TEMPLATE_PATH);
templateConfig.setController(CONTROLLER_TEMPLATE_PATH);
generator.setTemplate(templateConfig);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
String templatePath = "/generator/freemarker/mapper.xml.ftl";
//String templatePath = "/templates/mapper.xml.ftl";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
return projectPath + "\\sc-vas-admin\\src\\main\\resources\\mapper\\" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
generator.setCfg(cfg);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setInclude("***");
strategy.setSuperEntityColumns("id");
strategy.setControllerMappingHyphenStyle(true);
strategy.setTablePrefix("t_");
generator.setStrategy(strategy);
generator.setTemplateEngine(new FreemarkerTemplateEngine());
generator.execute();
}
}
模板controller.java.ftl
package ${package.Controller};
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import com.sinosoft.core.base.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.extern.slf4j.Slf4j;
import ${package.Entity}.${entity};
import ${package.Service}.I${entity}Service;
import org.springframework.web.bind.annotation.ResponseBody;
import com.sinosoft.core.core.page.TableDataInfo;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import java.util.List;
<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@Slf4j
@RequestMapping("${package.ModuleName}")
public class ${entity}Controller extends BaseController {
private String prefix = "${package.ModuleName}";
@Autowired
private I${entity}Service ${entity?uncap_first}Service;
@RequiresPermissions("${package.ModuleName}:${entity}:view")
@RequestMapping("/index")
public String index() throws Exception {
return prefix+"/index";
}
/**
* 列表
*/
@RequiresPermissions("${package.ModuleName}:${entity}:view")
@PostMapping("/list")
@ResponseBody
public TableDataInfo list(${entity} dto) {
startPage();
return getDataTable(${entity?uncap_first}Service.findPageInfo(dto));
}
@GetMapping("/add")
@RequiresPermissions("${package.ModuleName}:${entity}:add")
public String add() {
return prefix + "/add";
}
}
模板service.java.ftl
package ${package.Service};
import com.sinosoft.core.base.service.BaseService;
import ${package.Entity}.${entity};
import java.util.List;
public interface I${entity}Service extends BaseService<${entity}>{
List<${entity}> findPageInfo(${entity} ${entity?uncap_first});
}
模板serviceImpl.java.ftl
package ${package.ServiceImpl};
import com.sinosoft.core.base.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.I${entity}Service;
import java.util.List;
@Slf4j
@Service("policyService")
public class ${entity}ServiceImpl extends BaseServiceImpl< ${table.mapperName}, ${entity}> implements I${entity}Service{
@Override
public List<${entity}> findPageInfo(${entity} ${entity?uncap_first}) {
return baseMapper.findPageInfo(${entity?uncap_first});
}
}
模板mapper.java.ftl
package ${package.Mapper};
import com.sinosoft.core.base.mybatis.BaseMapper;
import ${package.Entity}.${entity};
import java.util.List;
public interface ${entity}Mapper extends BaseMapper<${entity}>{
List<${entity}> findPageInfo(${entity} ${entity?uncap_first});
}
模板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}">
<!-- 通用查询映射结果 -->
<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><#--生成公共字段 -->
<result column="${field.name}" property="${field.propertyName}" />
</#list>
<#list table.fields as field>
<#if !field.keyFlag><#--生成普通字段 -->
<result column="${field.name}" property="${field.propertyName}" />
</#if>
</#list>
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
<#list table.commonFields as field>
${field.name},
</#list>
${table.fieldNames}
</sql>
<select id="findPageInfo" resultType="${package.Entity}.${entity}">
select <include refid="Base_Column_List" />
from ${table.name} t
<where>
<#list table.fields as field>
<#if field??>
<if test="${field.propertyName} != null and ${field.propertyName} != ''">
AND t.${field.name} = ${r"#{"}${field.propertyName}${r"}"}
</if>
</#if>
</#list>
</where>
</select>
</mapper>
执行Generator.java中main方法生成模块代码如下:
到这里代码生成器就完成了
需要注意的是:
1.service接口首字母是大写的I,不能去掉,否则会报错,在全局配置中虽然能改名称但是不好使;
2.旧版本mybatis-plus-generator只能生成后端相关代码,前端代码不好操作,如果想使用更全面的配置,可以使用新版本代码生成器,具体参考官方文档代码生成器(新) | MyBatis-Plus (baomidou.com)