mybatis-plus-generator 代碼生成器
MyBatis-Plus
應該是很多人都在使用的,那mybatis-plus-generator
肯定也不會陌生。官網上提供了詳細的文檔說明,但是每個人都有自己的編碼規范,mybatis-plus-generator
默認只會生成最簡的文件,所以我根據自己的編碼規范,重新加了注釋和修改了模板,並且挑出了自己認為比較重要的參數。
當然,你也可以自己去根據官方文檔,修改自己的模板,最終都是為了自己的方便,不用寫太多無用代碼,做太多無用功。
目錄結構:
- java
- Generator.java
- resources
- template
- controller.java.ftl
- service.java.ftl
- serviceImpl.java.ftl
- entity.java.ftl
- mapper.java.ftl
- mapper.xml.ftl
maven依賴:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
代碼:
Generator.java
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableField;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.querys.PostgreSqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.*;
/**
* @author HongCheng
* <p>創建於 2021/4/13 15:32</p>
*/
public class Generator {
// TODO 數據庫連接地址
// static String jdbcUrl = "jdbc:oracle:thin:@localhost:1521:orcl";
static String jdbcUrl = "jdbc:postgresql://127.0.0.1:5432/demo";
// TODO 數據庫連接用戶名
static String username = "root";
// TODO 數據庫連接密碼
static String password = "root";
// TODO 要生成的表名
static String tableName = "demo_user";
// TODO 作者
static String author = "作者";
// TODO 輸出文件目錄
static String outDir = "D:\\Desktop\\code\\";
// TODO 是否使用標准doc注解
static boolean isStandardDoc = true;
// 自定義doc注解
static String customAnnotationAuthor = "@作者:";
static String customAnnotationDate = "@日期:";
static String customAnnotationParam = "@入參:";
static String customAnnotationReturn = "@出參:";
// TODO entity 包名
static String entityPackageName = "com.demo.map.entity";
// TODO mapper 包名
static String mapperPackageName = "com.demo.map.mapper";
// TODO xml 包名
static String xmlPackageName = "com.demo.map.mapper";
// TODO service 包名
static String servicePackageName = "com.demo.map.service";
// TODO controller 包名
static String controllerPackageName = "com.demo.map.controller";
// serviceImpl 包名
static String serviceImplPackageName = servicePackageName + ".impl";
// 模板主目錄
static String templatePath = "/template";
// controller 模板地址
static String controllerTemplate = templatePath + "/" + "controller.java";
// service 模板地址
static String serviceTemplate = templatePath + "/" + "service.java";
// serviceImpl 模板地址
static String serviceImplTemplate = templatePath + "/" + "serviceImpl.java";
// entity 模板地址
static String entityTemplate = templatePath + "/" + "entity.java";
// mapper 模板地址
static String mapperTemplate = templatePath + "/" + "mapper.java";
// mapper xml 模板地址
static String xmlTemplate = templatePath + "/" + "mapper.xml";
// oracle驅動
static String ORACLE_DRIVER = "oracle.jdbc.OracleDriver";
// postgresql驅動
static String POSTGRESQL_DRIVER = "org.postgresql.Driver";
// sqlserver驅動
static String SQL_SERVER_DRIVER = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
// mysql驅動
static String MYSQL_DRIVER = "com.mysql.jdbc.Driver";
public static void main(String[] args) {
// 代碼生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
gc.setOutputDir( outDir + tableName); // 輸出路徑
gc.setFileOverride(false); // 不覆蓋已有文件
gc.setAuthor(author); // 作者
gc.setOpen(false); // 打開文件夾
gc.setSwagger2(true); // 實體屬性 Swagger2 注解
gc.setBaseResultMap(true); // 生成BaseResultMap
gc.setBaseColumnList(true); // 生成BaseColumnList
gc.setDateType(DateType.ONLY_DATE); // 只使用 java.util.date 代替
gc.setActiveRecord(false); // 不開啟 ActiveRecord 模式
gc.setEntityName(null); // 實體命名方式不進行處理,如果需要處理可寫成:%sEntity 生成 UserEntity
gc.setMapperName("%sMapper"); // mapper 命名方式 例如:%sMapper 生成 UserMapper.java
gc.setXmlName("%sMapper"); // Mapper xml 命名方式 例如:%sMapper 生成 UserMapper.xml
gc.setServiceName("I%sService"); // service 命名方式 例如:I%sService 生成 IUserService.java
gc.setServiceImplName("%sServiceImpl"); // service impl 命名方式 例如:%sServiceImpl 生成 UserServiceImpl
gc.setControllerName("%sController"); // controller 命名方式 例如:%sController 生成 UserController
gc.setIdType(IdType.ASSIGN_UUID); // 主鍵id使用UUID
mpg.setGlobalConfig(gc);
// 數據源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl(jdbcUrl);
if (jdbcUrl.toLowerCase().contains("postgresql")){
dsc.setDriverName(POSTGRESQL_DRIVER);
// 添加自定義字段
dsc.setDbQuery(new CustomPostgreSqlQuery());
}else if (jdbcUrl.toLowerCase().contains("sqlserver")){
dsc.setDriverName(SQL_SERVER_DRIVER);
}else if (jdbcUrl.toLowerCase().contains("oracle")){
dsc.setDriverName(ORACLE_DRIVER);
}else if (jdbcUrl.toLowerCase().contains("mysql")){
dsc.setDriverName(MYSQL_DRIVER);
}else{
throw new RuntimeException("數據庫地址錯誤");
}
dsc.setUsername(username);
dsc.setPassword(password);
mpg.setDataSource(dsc);
// 數據庫表配置
StrategyConfig strategy = new StrategyConfig();
strategy.setSkipView(true); // 是否跳過視圖
strategy.setNaming(NamingStrategy.underline_to_camel); // 表命名下划線轉駝峰
strategy.setColumnNaming(NamingStrategy.underline_to_camel); // 列命名下划線轉駝峰
strategy.setTablePrefix(null); // 表前綴
strategy.setFieldPrefix(null); // 字段前綴
strategy.setSuperControllerClass("com.demo.core.boot.ctrl.BaseController"); // 控制器父類
strategy.setChainModel(true); // 【實體】使用鏈式模型
strategy.setEntityLombokModel(true);
strategy.setEntityBooleanColumnRemoveIsPrefix(false); // Boolean類型字段不移除is前綴
strategy.setRestControllerStyle(true); // 生成 @RestController 控制器
strategy.setEntityTableFieldAnnotationEnable(true); // 是否生成實體時,生成字段注解
List<TableFill> tableFills = new LinkedList<>();
new TableFill("modify_time", FieldFill.INSERT);
new TableFill("modifier", FieldFill.INSERT);
new TableFill("create_time", FieldFill.UPDATE);
new TableFill("creator", FieldFill.UPDATE);
strategy.setTableFillList(tableFills); // 字段填充
strategy.setControllerMappingHyphenStyle(true); // @RequestMapping("/managerUserActionHistory") -> @RequestMapping("/manager-user-action-history")
strategy.setInclude(tableName); // 要生成的表名
mpg.setStrategy(strategy);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName(null); //父包模塊名
pc.setParent(null); // 父包名。如果為空,將下面子包名必須寫全部, 否則就只需寫子包名
pc.setEntity(entityPackageName); // Entity包名
pc.setMapper(mapperPackageName); // Mapper包名
pc.setService(servicePackageName); // Service包名
pc.setServiceImpl(serviceImplPackageName); // Service Impl包名
pc.setController(controllerPackageName); // Controller包名
pc.setXml(xmlPackageName); // Mapper XML包名
mpg.setPackageInfo(pc);
// 模板配置
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setController(controllerTemplate);
templateConfig.setServiceImpl(serviceImplTemplate);
templateConfig.setService(serviceTemplate);
templateConfig.setEntity(entityTemplate);
templateConfig.setMapper(mapperTemplate);
templateConfig.setXml(xmlTemplate);
mpg.setTemplate(templateConfig);
// 引擎設置
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
// 自定義map
CustomInjectionConfigBuilder customInjectionConfigBuilder = new CustomInjectionConfigBuilder();
customInjectionConfigBuilder.setDataSourceConfig(dsc);
if (isStandardDoc == false){
customInjectionConfigBuilder.setAnnotationAuthor(customAnnotationAuthor);
customInjectionConfigBuilder.setAnnotationDate(customAnnotationDate);
customInjectionConfigBuilder.setAnnotationParam(customAnnotationParam);
customInjectionConfigBuilder.setAnnotationReturn(customAnnotationReturn);
}
mpg.setCfg(customInjectionConfigBuilder.build());
// 執行
mpg.execute();
}
/**
* 自定義數據庫字段查詢,主要是增加字段非空判斷
* */
static class CustomPostgreSqlQuery extends PostgreSqlQuery{
@Override
public String tableFieldsSql() {
return "SELECT A.attnotnull, A.attname AS name,format_type (A.atttypid,A.atttypmod) AS type,col_description (A.attrelid,A.attnum) AS comment, (CASE WHEN (SELECT COUNT (*) FROM pg_constraint AS PC WHERE A.attnum = PC.conkey[1] AND PC.contype = 'p') > 0 THEN 'PRI' ELSE '' END) AS key FROM pg_class AS C,pg_attribute AS A WHERE A.attrelid='%s.%s'::regclass AND A.attrelid= C.oid AND A.attnum> 0 AND NOT A.attisdropped ORDER BY A.attnum";
}
@Override
public String[] fieldCustom() {
return new String[]{"attnotnull"};
}
}
static class CustomInjectionConfigBuilder{
private CustomInjectionConfig customInjectionConfig;
public void setDataSourceConfig(DataSourceConfig dsc) {
init();
this.customInjectionConfig.dsc = dsc;
}
public void setAnnotationAuthor(String annotationAuthor) {
init();
this.customInjectionConfig.annotationAuthor = annotationAuthor;
}
public void setAnnotationDate(String annotationDate) {
init();
this.customInjectionConfig.annotationDate = annotationDate;
}
public void setAnnotationParam(String annotationParam) {
init();
this.customInjectionConfig.annotationParam = annotationParam;
}
public void setAnnotationReturn(String annotationReturn) {
init();
this.customInjectionConfig.annotationReturn = annotationReturn;
}
public CustomInjectionConfig build(){
return this.customInjectionConfig;
}
private void init(){
if (Objects.isNull(this.customInjectionConfig)){
this.customInjectionConfig = new CustomInjectionConfig();
}
}
}
/**
* 自定義數據map構建
* */
static class CustomInjectionConfig extends InjectionConfig{
// 數據源配置
private DataSourceConfig dsc;
// doc 注釋
private String annotationAuthor = "@author";
private String annotationDate = "@date";
private String annotationParam = "@param";
private String annotationReturn = "@return";
public CustomInjectionConfig() {}
public CustomInjectionConfig(DataSourceConfig dsc){
this.dsc = dsc;
}
@Override
public void initMap() {
List<TableInfo> tableInfoList = this.getConfig().getTableInfoList();
Map<String, Object> tableFieldCustomMap = new HashMap<>();
// doc注釋
tableFieldCustomMap.put("annotationAuthor", annotationAuthor);
tableFieldCustomMap.put("annotationDate", annotationDate);
tableFieldCustomMap.put("annotationParam", annotationParam);
tableFieldCustomMap.put("annotationReturn", annotationReturn);
// 處理數據庫字段
for (TableInfo tableInfo : tableInfoList) {
List<TableField> fields = tableInfo.getFields();
Map<String, Object> fieldCustomMap = new HashMap<>();
// 對象的駝峰寫法
fieldCustomMap.put("firstLowerServiceName" ,StringUtils.firstToLowerCase(tableInfo.getServiceName()));
fieldCustomMap.put("firstLowerControllerName" ,StringUtils.firstToLowerCase(tableInfo.getControllerName()));
fieldCustomMap.put("firstLowerEntityName" ,StringUtils.firstToLowerCase(tableInfo.getEntityName()));
fieldCustomMap.put("firstLowerMapperName" ,StringUtils.firstToLowerCase(tableInfo.getMapperName()));
// 處理字段的長度校驗和非空校驗
for (TableField field : fields) {
if (dsc.getDbType().equals(DbType.POSTGRE_SQL)){
// 字符類型的長度
if (Objects.nonNull(field.getColumnType().getType()) && Objects.equals(field.getColumnType().getType().toLowerCase(), "string")){
String type = field.getType();
if (type.contains("(") && type.contains(")")){
String length = type.substring(type.indexOf("(") + 1, type.indexOf(")"));
fieldCustomMap.put(field.getPropertyName() + "-Length", length);
}
}
if (field.getCustomMap() != null){
Object attnotnull = field.getCustomMap().get("attnotnull");
if (attnotnull != null && (attnotnull instanceof Boolean && (Boolean)attnotnull
|| Objects.equals(attnotnull.toString().toLowerCase(), "t") || Objects.equals(attnotnull.toString().toLowerCase(), "true"))){
if (Objects.nonNull(field.getColumnType().getType()) && Objects.equals(field.getColumnType().getType().toLowerCase(), "string")){
fieldCustomMap.put(field.getPropertyName() + "-NotBlank", true);
}else{
fieldCustomMap.put(field.getPropertyName() + "-NotNull", true);
}
}
}
}
}
tableFieldCustomMap.put(tableInfo.getName(), fieldCustomMap);
}
this.setMap(tableFieldCustomMap);
}
}
}
controller.java.ftl
package ${package.Controller};
import org.springframework.web.bind.annotation.RequestMapping;
import com.demo.core.tool.api.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import com.demo.common.exception.BaseRuntimeException;
<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage??>
import ${superControllerClassPackage};
</#if>
<#-- swagger的注解 -->
<#if swagger2>
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;
</#if>
<#-- 自定義代碼要用的 -->
<#if cfg[table.name]["firstLowerServiceName"]??>
import javax.annotation.Resource;
import ${package.Service}.${table.serviceName};
import ${package.Entity}.${entity};
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotBlank;
import java.util.Arrays;
import java.util.List;
</#if>
/**
* ${table.comment!} 前端控制器
* ${cfg["annotationAuthor"]} ${author}
* ${cfg["annotationDate"]} ${date}
*/
@Slf4j
@Validated
<#if restControllerStyle>
@RestController
<#else>
@Controller
</#if>
@RequestMapping("<#if package.ModuleName??>/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}</#if>")
<#if swagger2>
@Api(value = "API - ${table.controllerName}", tags = "${table.comment!table.controllerName}")
</#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>
<#if cfg[table.name]["firstLowerServiceName"]??>
@Resource
private ${table.serviceName} ${cfg[table.name]["firstLowerServiceName"]};
/**
* 新增 ${table.comment!} 記錄
* ${cfg["annotationAuthor"]} ${author}
* ${cfg["annotationDate"]} ${date}
*/
@PostMapping("/save")
<#if swagger2>
@ApiOperation(value = "新增 ${table.comment!} 記錄")
</#if>
@Transactional(rollbackFor = Exception.class)
public R<${entity}> save(@Validated ${entity} ${cfg[table.name]["firstLowerEntityName"]}){
// 新增
boolean save = this.${cfg[table.name]["firstLowerServiceName"]}.save(${cfg[table.name]["firstLowerEntityName"]});
if (save){
return R.data(this.${cfg[table.name]["firstLowerServiceName"]}.getById(${cfg[table.name]["firstLowerEntityName"]}.getId()));
}else{
throw new BaseRuntimeException("新增失敗");
}
}
/**
* 修改 ${table.comment!} 記錄
* ${cfg["annotationAuthor"]} ${author}
* ${cfg["annotationDate"]} ${date}
*/
@PostMapping("/update")
<#if swagger2>
@ApiOperation(value = "修改 ${table.comment!} 記錄")
</#if>
@Transactional(rollbackFor = Exception.class)
public R<${entity}> update(@Validated ${entity} ${cfg[table.name]["firstLowerEntityName"]}){
// 修改
${entity} oldEntity = this.${cfg[table.name]["firstLowerServiceName"]}.getById(${cfg[table.name]["firstLowerEntityName"]}.getId());
LambdaUpdateWrapper<${entity}> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.setEntity(oldEntity);
boolean update = this.${cfg[table.name]["firstLowerServiceName"]}.update(${cfg[table.name]["firstLowerEntityName"]} ,updateWrapper);
if (update){
return R.data(this.${cfg[table.name]["firstLowerServiceName"]}.getById(${cfg[table.name]["firstLowerEntityName"]}.getId()));
}else{
throw new BaseRuntimeException("修改失敗");
}
}
/**
* 刪除 ${table.comment!} 記錄
* ${cfg["annotationAuthor"]} ${author}
* ${cfg["annotationDate"]} ${date}
*/
@PostMapping("/delete")
<#if swagger2>
@ApiOperation(value = "刪除 ${table.comment!} 記錄")
@ApiImplicitParams({
@ApiImplicitParam(name = "ids", value = "主鍵id,如果多個,英文逗號隔開", required = true, dataType = "string", paramType = "query")
})
</#if>
@Transactional(rollbackFor = Exception.class)
public R<List<${entity}>> delete(@Validated @NotBlank(message = "請選擇記錄再進行刪除") String ids){
List<String> idList = Arrays.asList(ids.trim().split(","));
List<${entity}> ${cfg[table.name]["firstLowerEntityName"] + "s"} = this.${cfg[table.name]["firstLowerServiceName"]}.listByIds(idList);
boolean remove = this.${cfg[table.name]["firstLowerServiceName"]}.removeByIds(idList);
if (remove){
return R.data(${cfg[table.name]["firstLowerEntityName"] + "s"});
}else{
throw new BaseRuntimeException("刪除失敗");
}
}
/**
* 分頁獲取 ${table.comment!} 列表
* ${cfg["annotationAuthor"]} ${author}
* ${cfg["annotationDate"]} ${date}
*/
@PostMapping("/page")
<#if swagger2>
@ApiOperation(value = "分頁獲取 ${table.comment!} 列表")
@ApiImplicitParams({
@ApiImplicitParam(name = "size", value = "頁面大小,默認10", dataType = "int", paramType = "query"),
@ApiImplicitParam(name = "current", value = "當前頁碼,默認1", dataType = "int", paramType = "query"),
})
</#if>
public R<Page<${entity}>>page(<#if swagger2>@ApiIgnore</#if> Page page){
Page page1 = this.${cfg[table.name]["firstLowerServiceName"]}.page(page);
return R.data(page1);
}
/**
* 獲取 ${table.comment!} 詳情
* ${cfg["annotationAuthor"]} ${author}
* ${cfg["annotationDate"]} ${date}
*/
@PostMapping("/detail")
<#if swagger2>
@ApiOperation(value = "獲取 ${table.comment!} 詳情")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "主鍵id", required = true, dataType = "string", paramType = "query")
})
</#if>
public R<${entity}> detail(@Validated @NotBlank(message = "請選擇記錄再進行查看詳情") String id){
${entity} ${cfg[table.name]["firstLowerEntityName"]} = this.${cfg[table.name]["firstLowerServiceName"]}.getById(id);
return R.data(${cfg[table.name]["firstLowerEntityName"]});
}
</#if>
}
</#if>
service.java.ftl
package ${package.Service};
import ${package.Entity}.${entity};
import ${superServiceClassPackage};
/**
* ${table.comment!} 服務類接口
* ${cfg["annotationAuthor"]} ${author}
* ${cfg["annotationDate"]} ${date}
*/
<#if kotlin>
interface ${table.serviceName} : ${superServiceClass}<${entity}>
<#else>
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
}
</#if>
serviceImpl.java.ftl
package ${package.ServiceImpl};
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.demo.common.utils.UuidUtil;
import com.demo.common.utils.ValidateUtil;
import com.demo.core.secure.utils.AuthUtil;
import org.apache.commons.lang3.StringUtils;
import java.util.Objects;
import java.util.Date;
import com.demo.common.exception.BaseRuntimeException;
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
<#if cfg[table.name]["firstLowerMapperName"]??>
import javax.annotation.Resource;
</#if>
/**
* ${table.comment!} 服務實現類
* ${cfg["annotationAuthor"]} ${author}
* ${cfg["annotationDate"]} ${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} {
<#if cfg[table.name]["firstLowerMapperName"]??>
@Resource
private ${table.mapperName} ${cfg[table.name]["firstLowerMapperName"]};
</#if>
/**
* 修改前的准備,包括驗證數據和填充數據
* ${cfg["annotationParam"]} ${cfg[table.name]["firstLowerEntityName"]}
* ${cfg["annotationAuthor"]} ${author}
* ${cfg["annotationDate"]} ${date}
*/
private void prepareBeforeUpdate(${entity} ${cfg[table.name]["firstLowerEntityName"]}){
if (StringUtils.isBlank(${cfg[table.name]["firstLowerEntityName"]}.getId())){
throw new BaseRuntimeException("請選中一條記錄進行修改。");
}
LambdaQueryWrapper<${entity}> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(${entity}::getId, ${cfg[table.name]["firstLowerEntityName"]}.getId());
if (this.${cfg[table.name]["firstLowerMapperName"]}.selectCount(queryWrapper) <= 0){
throw new BaseRuntimeException("當前修改的記錄不存在,請刷新后再試。");
}
${cfg[table.name]["firstLowerEntityName"]}.setModifier(Objects.nonNull(AuthUtil.getUser())? AuthUtil.getUserId().toString() : null);
${cfg[table.name]["firstLowerEntityName"]}.setModifyTime(new Date());
${cfg[table.name]["firstLowerEntityName"]}.setCreator(null);
${cfg[table.name]["firstLowerEntityName"]}.setCreateTime(null);
// 驗證數據是否符合
ValidateUtil.validateEntity(true, ${cfg[table.name]["firstLowerEntityName"]});
}
/**
* 新增前的准備,包括驗證數據和填充數據
* ${cfg["annotationParam"]} ${cfg[table.name]["firstLowerEntityName"]}
* ${cfg["annotationAuthor"]} ${author}
* ${cfg["annotationDate"]} ${date}
*/
private void prepareBeforeSave(${entity} ${cfg[table.name]["firstLowerEntityName"]}){
if (StringUtils.isBlank(${cfg[table.name]["firstLowerEntityName"]}.getId())){
${cfg[table.name]["firstLowerEntityName"]}.setId(UuidUtil.get32UUID());
}
${cfg[table.name]["firstLowerEntityName"]}.setCreator(Objects.nonNull(AuthUtil.getUser())? AuthUtil.getUserId().toString() : null);
${cfg[table.name]["firstLowerEntityName"]}.setCreateTime(new Date());
${cfg[table.name]["firstLowerEntityName"]}.setModifier(null);
${cfg[table.name]["firstLowerEntityName"]}.setModifyTime(null);
// 驗證數據是否符合
ValidateUtil.validateEntity(true, ${cfg[table.name]["firstLowerEntityName"]});
}
}
</#if>
entity.java.ftl
package ${package.Entity};
<#list table.importPackages as pkg>
import ${pkg};
</#list>
<#if swagger2>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
</#if>
<#if entityLombokModel>
import lombok.Data;
import lombok.EqualsAndHashCode;
<#if chainModel>
import lombok.experimental.Accessors;
</#if>
</#if>
<#-- ---------- ${table.comment!} 這種寫法全稱是:${字段!字段為空時的默認值} ---------->
/**
* ${table.comment!} 實體類
* ${cfg["annotationAuthor"]} ${author}
* ${cfg["annotationDate"]} ${date}
*/
<#if entityLombokModel>
@Data
<#-- ---------- <#if superEntityClass??> 這種寫法是:如果superEntityClass不是null,就執行下面 ---------->
<#if superEntityClass??>
@EqualsAndHashCode(callSuper = true)
<#else>
@EqualsAndHashCode(callSuper = false)
</#if>
<#if chainModel>
@Accessors(chain = true)
</#if>
</#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 cfg[table.name][field.propertyName + "-Length"]??>
@Length(max = ${cfg[table.name][field.propertyName + "-Length"]!}, message = "${field.comment!}最大為${cfg[table.name][field.propertyName + "-Length"]!}個字符")
</#if>
<#-- 非空檢驗限制 -->
<#if cfg[table.name][field.propertyName + "-NotBlank"]??>
@NotBlank(message = "${field.comment!}不能為空")
</#if>
<#-- 非空檢驗限制 -->
<#if cfg[table.name][field.propertyName + "-NotNull"]??>
@NotNull(message = "${field.comment!}不能為空")
</#if>
<#-- 數據庫字段映射配置 -->
<#if field.keyFlag>
<#-- 主鍵 -->
<#if field.keyIdentityFlag>
@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
<#elseif idType??>
@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
<#elseif field.convert>
@TableId(value = "${field.annotationColumnName}")
</#if>
<#-- 普通字段 -->
<#elseif field.fill??>
<#-- ----- 存在字段填充設置 ----->
<#if field.convert>
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
<#else>
@TableField(fill = FieldFill.${field.fill})
</#if>
<#elseif field.convert>
@TableField(value = "${field.annotationColumnName}")
</#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 chainModel>
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 chainModel>
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>
}
mapper.java.ftl
package ${package.Mapper};
import ${package.Entity}.${entity};
import ${superMapperClassPackage};
/**
* ${table.comment!} Mapper 接口
* ${cfg["annotationAuthor"]} ${author}
* ${cfg["annotationDate"]} ${date}
*/
<#if kotlin>
interface ${table.mapperName} : ${superMapperClass}<${entity}>
<#else>
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
}
</#if>
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><#--生成公共字段 -->
<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>
</#if>
<#if baseColumnList>
<!-- 通用查詢結果列 -->
<sql id="Base_Column_List">
<#list table.commonFields as field>
${field.columnName},
</#list>
${table.fieldNames}
</sql>
</#if>
</mapper>
參考文檔:
代碼生成器(舊): https://baomidou.com/pages/d357af/#使用教程
FreeMarker在線手冊:http://freemarker.foofun.cn/