我的两篇文章,Easy Code的使用教程(带模板)以及另外一篇MyBatis-Plus的easycode模板,看的人还是挺多的,也有反映Easy Code的使用教程(带模板)的vm自动化有问题的,因此我今天重塑了一下我的vm,这次将更加强大!!!写这篇文章,一来是解决问题,二来是记录一下我写的vm。

非常标准的domain,mapper,service,serviceimpl,controller,yaml,xml,以及一个banner图,全部都有,并且保证无bug,以阿里开发手册为指导,制造了具有restful风格的API,统一返回类。

返回json

org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.2 com.alibaba druid-spring-boot-starter 1.2.14 com.mysql mysql-connector-j runtime org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test
##引入宏定义
$!{define.vm}##使用宏定义设置回调(保存位置与文件后缀)
#save("/domain", ".java")##使用宏定义设置包后缀
#setPackageSuffix("domain")##使用全局变量实现默认包导入
$!{autoImport.vm}
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;##使用宏定义实现类注释信息
#tableComment("实体类")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class $!{tableInfo.name} implements Serializable {
private static final long serialVersionUID = $!tool.serial();
#foreach($column in $tableInfo.fullColumn)
#if(${column.comment})/**${column.comment}*/#end
private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end
}
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Mapper"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/mapper"))##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())#set($pk = $tableInfo.pkColumn.get(0))
#end#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}mapper;import $!{tableInfo.savePackageName}.domain.$!{tableInfo.name};
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** $!{tableInfo.comment}($!{tableInfo.name})表数据库访问层** @author $!author* @since $!time.currTime()*/
@Mapper
public interface $!{tableName} {/*** 通过ID查询单条数据** @param $!pk.name 主键* @return 实例对象*/$!{tableInfo.name} queryById($!pk.shortType $!pk.name);/*** 查询指定行数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 查询条件* @return 对象列表*/List<$!{tableInfo.name}> queryAll($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 统计总行数** @param $!tool.firstLowerCase($!{tableInfo.name}) 查询条件* @return 总行数*/long count($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 新增数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象* @return 影响行数*/int insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 批量新增数据(MyBatis原生foreach方法)** @param entities List<$!{tableInfo.name}> 实例对象列表* @return 影响行数*/int insertBatch(@Param("entities") List<$!{tableInfo.name}> entities);/*** 批量新增或按主键更新数据(MyBatis原生foreach方法)** @param entities List<$!{tableInfo.name}> 实例对象列表* @return 影响行数* @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参*/int insertOrUpdateBatch(@Param("entities") List<$!{tableInfo.name}> entities);/*** 修改数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象* @return 影响行数*/int update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 通过主键删除数据** @param $!pk.name 主键* @return 影响行数*/int deleteById($!pk.shortType $!pk.name);}
##引入mybatis支持
$!{mybatisSupport.vm}##设置保存名称与保存位置
$!callback.setFileName($tool.append($!{tableInfo.name}, "Mapper.xml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources/mapper"))##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())#set($pk = $tableInfo.pkColumn.get(0))
#end
#foreach($column in $tableInfo.fullColumn)
#end insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($velocityHasNext), #end#end)values (#foreach($column in $tableInfo.otherColumn)#{$!{column.name}}#if($velocityHasNext), #end#end) insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($velocityHasNext), #end#end)values(#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($velocityHasNext), #end#end) insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($velocityHasNext), #end#end)values(#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($velocityHasNext), #end#end) on duplicate key update#foreach($column in $tableInfo.otherColumn)$!column.obj.name = values($!column.obj.name)#if($velocityHasNext),#end#end update $!{tableInfo.obj.name}
#foreach($column in $tableInfo.otherColumn)$!column.obj.name = #{$!column.name},
#end where $!pk.obj.name = #{$!pk.name} delete from $!{tableInfo.obj.name} where $!pk.obj.name = #{$!pk.name}
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Service"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service"))##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())#set($pk = $tableInfo.pkColumn.get(0))
#end#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service;import $!{tableInfo.savePackageName}.domain.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.util.R;/*** $!{tableInfo.comment}($!{tableInfo.name})表服务接口** @author $!author* @since $!time.currTime()*/
public interface $!{tableName} {/*** 通过ID查询单条数据** @param $!pk.name 主键* @return 实例对象*/R queryById($!pk.shortType $!pk.name);/*** 全查询** @param $!tool.firstLowerCase($!{tableInfo.name}) 筛选条件* @return 查询结果*/R queryAll($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 新增数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象* @return 实例对象*/R insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 修改数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象* @return 实例对象*/R update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 通过主键删除数据** @param $!pk.name 主键* @return 是否成功*/R deleteById($!pk.shortType $!pk.name);}
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "ServiceImpl"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/service/impl"))##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())#set($pk = $tableInfo.pkColumn.get(0))
#end#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}service.impl;import $!{tableInfo.savePackageName}.domain.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.mapper.$!{tableInfo.name}Mapper;
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;
import $!{tableInfo.savePackageName}.util.R;
import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** $!{tableInfo.comment}($!{tableInfo.name})表服务实现类** @author $!author* @since $!time.currTime()*/
@Service("$!tool.firstLowerCase($!{tableInfo.name})Service")
public class $!{tableName} implements $!{tableInfo.name}Service {
@Resource
private $!{tableInfo.name}Mapper $!tool.firstLowerCase($!{tableInfo.name})Mapper;/*** 通过ID查询单条数据** @param $!pk.name 主键* @return 实例对象*/
@Override
public R queryById($!pk.shortType $!pk.name) {return R.ok().setData(this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.queryById($!pk.name));}/*** 全查询** @param $!{tool.firstLowerCase($tableInfo.name)} 筛选条件* @return 查询结果*/
@Override
public R queryAll($!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {return R.ok().setData(this.$!{tool.firstLowerCase($tableInfo.name)}Mapper.queryAll($!{tool.firstLowerCase($tableInfo.name)}));}/*** 新增数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象* @return 实例对象*/
@Override
public R insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.insert($!tool.firstLowerCase($!{tableInfo.name}));return R.ok().setData($!tool.firstLowerCase($!{tableInfo.name}));}/*** 修改数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象* @return 实例对象*/
@Override
public R update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.update($!tool.firstLowerCase($!{tableInfo.name}));return R.ok().setData(this.queryById($!{tool.firstLowerCase($!{tableInfo.name})}.get$!tool.firstUpperCase($pk.name)()));}/*** 通过主键删除数据** @param $!pk.name 主键* @return 是否成功*/
@Override
public R deleteById($!pk.shortType $!pk.name) {boolean del = this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.deleteById($!pk.name) > 0;return R.ok().setData(del);}}
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Controller"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/controller"))
##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())#set($pk = $tableInfo.pkColumn.get(0))
#end#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}controller;import $!{tableInfo.savePackageName}.domain.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;
import $!{tableInfo.savePackageName}.util.R;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;/*** $!{tableInfo.comment}($!{tableInfo.name})表控制层** @author $!author* @since $!time.currTime()*/
@RestController
@RequestMapping("$!tool.firstLowerCase($tableInfo.name)")
public class $!{tableName} {
/*** 服务对象*/
@Resource
private $!{tableInfo.name}Service $!tool.firstLowerCase($tableInfo.name)Service;/*** 全查询** @param $!{tool.firstLowerCase($tableInfo.name)} 筛选条件* @return 查询结果*/
@GetMapping
public R queryAll($!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {return this.$!{tool.firstLowerCase($tableInfo.name)}Service.queryAll($!{tool.firstLowerCase($tableInfo.name)});}/*** 通过主键查询单条数据** @param id 主键* @return 单条数据*/
@GetMapping("{id}")
public R queryById(@PathVariable("id") $!pk.shortType id) {return this.$!{tool.firstLowerCase($tableInfo.name)}Service.queryById(id);}/*** 新增数据** @param $!{tool.firstLowerCase($tableInfo.name)} 实体* @return 新增结果*/
@PostMapping
public R add(@RequestBody $!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {return this.$!{tool.firstLowerCase($tableInfo.name)}Service.insert($!{tool.firstLowerCase($tableInfo.name)});}/*** 编辑数据** @param $!{tool.firstLowerCase($tableInfo.name)} 实体* @return 编辑结果*/
@PutMapping
public R edit(@RequestBody $!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {return this.$!{tool.firstLowerCase($tableInfo.name)}Service.update($!{tool.firstLowerCase($tableInfo.name)});}/*** 删除数据** @param id 主键* @return 删除是否成功*/
@DeleteMapping
public R deleteById($!pk.shortType id) {return this.$!{tool.firstLowerCase($tableInfo.name)}Service.deleteById(id);}}
##设置回调
$!callback.setFileName($tool.append("R.java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/util"))#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}util;import lombok.Data;import java.io.Serializable;/*** 统一返回对象R** @author $!author* @since $!time.currTime()*/
@Data
public class R implements Serializable {private static final long serialVersionUID = $!tool.serial();private int code;private String message;private Object data;/*** 设置数据** @param data 数据* @return R*/public R setData(Object data) {this.data = data;return this;}/*** 操作成功** @return R*/public static R ok() {R r = new R();r.code = 200;r.message = "OK";return r;}/*** 认证授权失败。 包括密钥信息不正确;数字签名错误;授权已超时** @return R*/public static R fail() {R r = new R();r.code = 401;r.message = "fail";return r;}/*** 系统异常** @return R*/public static R exp() {R r = new R();r.code = 500;r.message = "exception";return r;}
}
##设置回调
$!callback.setFileName($tool.append("application.yaml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources"))
server:port: 8080spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedruid:# 下面为连接池的补充设置,应用到上面所有数据源中# 初始化大小,最小,最大initial-size: 15min-idle: 8max-active: 30# 配置获取连接等待超时的时间max-wait: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒time-between-eviction-runs-millis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒min-evictable-idle-time-millis: 300000# 打开PSCache,并且指定每个连接上PSCache的大小pool-prepared-statements: truemax-pool-prepared-statement-per-connection-size: 60validation-query: SELECT 1 FROM DUALstat-view-servlet:enabled: trueurl: urlusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Drivermybatis:mapper-locations: classpath:mapper/*.xmlconfiguration:# call-setters-on-nulls 参数的作用是查询的某一行某一列为null,是否返回call-setters-on-nulls: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImpl
##设置回调
$!callback.setFileName($tool.append("banner.txt"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources"))
${AnsiColor.BRIGHT_YELLOW}// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| ^_^ |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | \\\ - /// | | //
// | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕机 永无BUG //







org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.2 com.alibaba druid-spring-boot-starter 1.2.15 org.hibernate.validator hibernate-validator 8.0.0.Final io.springfox springfox-boot-starter 3.0.0 com.mysql mysql-connector-j runtime org.projectlombok lombok true
##设置回调
$!callback.setFileName($tool.append("AccessFilter.java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/config"))#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 提供跨域支持** @author $!author* @since $!time.currTime()*/
@Slf4j
@Configuration
public class AccessFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) res;response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Headers", "*");// 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {response.setStatus(HttpStatus.OK.value());return;}chain.doFilter(req, res);}@Overridepublic void destroy() {}
}
##设置回调
$!callback.setFileName($tool.append("application.yaml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources"))
spring:profiles:active: test
##设置回调
$!callback.setFileName($tool.append("application-dev.yaml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources"))
server:port: 8080swagger:enabled: truespring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8mvc:pathmatch:matching-strategy: ant_path_matcherdatasource:type: com.alibaba.druid.pool.DruidDataSourcedruid:# 下面为连接池的补充设置,应用到上面所有数据源中# 初始化大小,最小,最大initial-size: 15min-idle: 8max-active: 30# 配置获取连接等待超时的时间max-wait: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒time-between-eviction-runs-millis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒min-evictable-idle-time-millis: 300000# 打开PSCache,并且指定每个连接上PSCache的大小pool-prepared-statements: truemax-pool-prepared-statement-per-connection-size: 60validation-query: SELECT 1 FROM DUALurl: jdbc:mysql://localhost:3306/study_spaceusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Drivermybatis:mapper-locations: classpath:mapper/*.xmlconfiguration:# call-setters-on-nulls 参数的作用是查询的某一行某一列为null,是否返回call-setters-on-nulls: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImpl
##设置回调
$!callback.setFileName($tool.append("application-prod.yaml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources"))
server:port: 8080swagger:enabled: falsespring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8datasource:type: com.alibaba.druid.pool.DruidDataSourcedruid:# 下面为连接池的补充设置,应用到上面所有数据源中# 初始化大小,最小,最大initial-size: 15min-idle: 8max-active: 30# 配置获取连接等待超时的时间max-wait: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒time-between-eviction-runs-millis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒min-evictable-idle-time-millis: 300000# 打开PSCache,并且指定每个连接上PSCache的大小pool-prepared-statements: truemax-pool-prepared-statement-per-connection-size: 60validation-query: SELECT 1 FROM DUALurl: jdbc:mysql://localhost:3306/study_spaceusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Drivermybatis:mapper-locations: classpath:mapper/*.xmlconfiguration:# call-setters-on-nulls 参数的作用是查询的某一行某一列为null,是否返回call-setters-on-nulls: true
##设置回调
$!callback.setFileName($tool.append("application-test.yaml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources"))
server:port: 8080swagger:enabled: truespring:jackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8mvc:pathmatch:matching-strategy: ant_path_matcherdatasource:type: com.alibaba.druid.pool.DruidDataSourcedruid:# 下面为连接池的补充设置,应用到上面所有数据源中# 初始化大小,最小,最大initial-size: 15min-idle: 8max-active: 30# 配置获取连接等待超时的时间max-wait: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒time-between-eviction-runs-millis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒min-evictable-idle-time-millis: 300000# 打开PSCache,并且指定每个连接上PSCache的大小pool-prepared-statements: truemax-pool-prepared-statement-per-connection-size: 60validation-query: SELECT 1 FROM DUALurl: jdbc:mysql://localhost:3306/study_spaceusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Drivermybatis:mapper-locations: classpath:mapper/*.xmlconfiguration:# call-setters-on-nulls 参数的作用是查询的某一行某一列为null,是否返回call-setters-on-nulls: truelog-impl: org.apache.ibatis.logging.stdout.StdOutImpl
##设置回调
$!callback.setFileName($tool.append("banner.txt"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources"))
${AnsiColor.BRIGHT_YELLOW}// _ooOoo_ //
// o8888888o //
// 88" . "88 //
// (| ^_^ |) //
// O\ = /O //
// ____/`---'\____ //
// .' \\| |// `. //
// / \\||| : |||// \ //
// / _||||| -:- |||||- \ //
// | | \\\ - /// | | //
// | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕机 永无BUG //
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Controller"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/mvc/controller"))
##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())#set($pk = $tableInfo.pkColumn.get(0))
#end#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}mvc.controller;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import $!{tableInfo.savePackageName}.mvc.domain.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.mvc.service.$!{tableInfo.name}Service;
import $!{tableInfo.savePackageName}.util.R;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;/*** $!{tableInfo.comment}($!{tableInfo.name})表控制层** @author $!author* @since $!time.currTime()*/
@Slf4j
@RestController
@RequestMapping("$!tool.firstLowerCase($tableInfo.name)")
@Api(tags = "$!{tableInfo.comment}($!{tableInfo.name})表控制层")
public class $!{tableName} {
/*** 服务对象*/
@Resource
private $!{tableInfo.name}Service $!tool.firstLowerCase($tableInfo.name)Service;/*** 全查询** @param $!{tool.firstLowerCase($tableInfo.name)} 筛选条件* @return 查询结果*/
@ApiOperation("全查询")
@GetMapping
public R queryAll(@ApiParam(value = "$!{tool.firstLowerCase($tableInfo.name)} 筛选条件") $!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {return this.$!{tool.firstLowerCase($tableInfo.name)}Service.queryAll($!{tool.firstLowerCase($tableInfo.name)});}/*** 通过主键查询单条数据** @param id 主键* @return 单条数据*/
@ApiOperation("通过主键查询单条数据")
@GetMapping("{id}")
public R queryById(@ApiParam(value = "id 主键") @PathVariable("id") $!pk.shortType id) {return this.$!{tool.firstLowerCase($tableInfo.name)}Service.queryById(id);}/*** 新增数据** @param $!{tool.firstLowerCase($tableInfo.name)} 实体* @return 新增结果*/
@ApiOperation("新增数据")
@PostMapping
public R add(@ApiParam(value = "$!{tool.firstLowerCase($tableInfo.name)} 实体") @RequestBody $!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {return this.$!{tool.firstLowerCase($tableInfo.name)}Service.insert($!{tool.firstLowerCase($tableInfo.name)});}/*** 编辑数据** @param $!{tool.firstLowerCase($tableInfo.name)} 实体* @return 编辑结果*/
@ApiOperation("编辑数据")
@PutMapping
public R edit(@ApiParam(value = "$!{tool.firstLowerCase($tableInfo.name)} 实体") @RequestBody $!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {return this.$!{tool.firstLowerCase($tableInfo.name)}Service.update($!{tool.firstLowerCase($tableInfo.name)});}/*** 删除数据** @param id 主键* @return 删除是否成功*/
@ApiOperation("删除数据")
@DeleteMapping
public R deleteById(@ApiParam(value = "id 主键") $!pk.shortType id) {return this.$!{tool.firstLowerCase($tableInfo.name)}Service.deleteById(id);}}
##引入宏定义
$!{define.vm}##使用宏定义设置回调(保存位置与文件后缀)
#save("/mvc/domain", ".java")#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}mvc.domain;import lombok.extern.slf4j.Slf4j;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;##使用宏定义实现类注释信息
#tableComment("实体类")
@Slf4j
@Data
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("$!{tableInfo.comment}($!{tableInfo.name})实体类")
public class $!{tableInfo.name} implements Serializable {
private static final long serialVersionUID = $!tool.serial();
#foreach($column in $tableInfo.fullColumn)
#if(${column.comment})/**${column.comment}*/#end
@ApiModelProperty(value = "#if(${column.comment})${column.comment}#end")
private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end
}
##设置回调
$!callback.setFileName($tool.append("logback.xml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources"))
logback %d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n ${LOG_HOME}/error/%d{yyyy-MM-dd}-error.log 10 %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{30} - %msg%n 10MB ERROR ACCEPT DENY ${LOG_HOME}/%d{yyyy-MM-dd}.log 10 %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{30} - %msg%n 10MB
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Mapper"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/mvc/mapper"))##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())#set($pk = $tableInfo.pkColumn.get(0))
#end#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}mvc.mapper;import $!{tableInfo.savePackageName}.mvc.domain.$!{tableInfo.name};
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** $!{tableInfo.comment}($!{tableInfo.name})表数据库访问层** @author $!author* @since $!time.currTime()*/
@Mapper
public interface $!{tableName} {/*** 通过ID查询单条数据** @param $!pk.name 主键* @return 实例对象*/$!{tableInfo.name} queryById($!pk.shortType $!pk.name);/*** 查询指定行数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 查询条件* @return 对象列表*/List<$!{tableInfo.name}> queryAll($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 统计总行数** @param $!tool.firstLowerCase($!{tableInfo.name}) 查询条件* @return 总行数*/long count($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 新增数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象* @return 影响行数*/int insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 批量新增数据(MyBatis原生foreach方法)** @param entities List<$!{tableInfo.name}> 实例对象列表* @return 影响行数*/int insertBatch(@Param("entities") List<$!{tableInfo.name}> entities);/*** 批量新增或按主键更新数据(MyBatis原生foreach方法)** @param entities List<$!{tableInfo.name}> 实例对象列表* @return 影响行数* @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参*/int insertOrUpdateBatch(@Param("entities") List<$!{tableInfo.name}> entities);/*** 修改数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象* @return 影响行数*/int update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 通过主键删除数据** @param $!pk.name 主键* @return 影响行数*/int deleteById($!pk.shortType $!pk.name);}
##引入mybatis支持
$!{mybatisSupport.vm}##设置保存名称与保存位置
$!callback.setFileName($tool.append($!{tableInfo.name}, "Mapper.xml"))
$!callback.setSavePath($tool.append($modulePath, "/src/main/resources/mapper"))##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())#set($pk = $tableInfo.pkColumn.get(0))
#end
#foreach($column in $tableInfo.fullColumn)
#end insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($velocityHasNext), #end#end)values (#foreach($column in $tableInfo.otherColumn)#{$!{column.name}}#if($velocityHasNext), #end#end) insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($velocityHasNext), #end#end)values(#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($velocityHasNext), #end#end) insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.otherColumn)$!column.obj.name#if($velocityHasNext), #end#end)values(#foreach($column in $tableInfo.otherColumn)#{entity.$!{column.name}}#if($velocityHasNext), #end#end) on duplicate key update#foreach($column in $tableInfo.otherColumn)$!column.obj.name = values($!column.obj.name)#if($velocityHasNext),#end#end update $!{tableInfo.obj.name}
#foreach($column in $tableInfo.otherColumn)$!column.obj.name = #{$!column.name},
#end where $!pk.obj.name = #{$!pk.name} delete from $!{tableInfo.obj.name} where $!pk.obj.name = #{$!pk.name}
##设置回调
$!callback.setFileName($tool.append("R.java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/util"))#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}util;
import lombok.extern.slf4j.Slf4j;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.io.Serializable;/*** 统一返回对象R** @author $!author* @since $!time.currTime()*/
@Slf4j
@Data
@ApiModel("统一返回对象R")
public class R implements Serializable {private static final long serialVersionUID = $!tool.serial();@ApiModelProperty(value = "响应编码")private int code;@ApiModelProperty(value = "响应信息")private String message;@ApiModelProperty(value = "响应数据")private Object data;/*** 设置数据** @param data 数据* @return R*/public R setData(Object data) {this.data = data;return this;}/*** 操作成功** @return R*/public static R ok() {R r = new R();r.code = 200;r.message = "OK";return r;}/*** 认证授权失败。 包括密钥信息不正确;数字签名错误;授权已超时** @return R*/public static R fail() {R r = new R();r.code = 401;r.message = "fail";return r;}/*** 系统异常** @return R*/public static R exp() {R r = new R();r.code = 500;r.message = "exception";return r;}
}
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "Service"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/mvc/service"))##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())#set($pk = $tableInfo.pkColumn.get(0))
#end#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}mvc.service;import $!{tableInfo.savePackageName}.mvc.domain.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.util.R;/*** $!{tableInfo.comment}($!{tableInfo.name})表服务接口** @author $!author* @since $!time.currTime()*/
public interface $!{tableName} {/*** 通过ID查询单条数据** @param $!pk.name 主键* @return 实例对象*/R queryById($!pk.shortType $!pk.name);/*** 全查询** @param $!tool.firstLowerCase($!{tableInfo.name}) 筛选条件* @return 查询结果*/R queryAll($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 新增数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象* @return 实例对象*/R insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 修改数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象* @return 实例对象*/R update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name}));/*** 通过主键删除数据** @param $!pk.name 主键* @return 是否成功*/R deleteById($!pk.shortType $!pk.name);}
##定义初始变量
#set($tableName = $tool.append($tableInfo.name, "ServiceImpl"))
##设置回调
$!callback.setFileName($tool.append($tableName, ".java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/mvc/service/impl"))##拿到主键
#if(!$tableInfo.pkColumn.isEmpty())#set($pk = $tableInfo.pkColumn.get(0))
#end#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}mvc.service.impl;
import lombok.extern.slf4j.Slf4j;
import $!{tableInfo.savePackageName}.mvc.domain.$!{tableInfo.name};
import $!{tableInfo.savePackageName}.mvc.mapper.$!{tableInfo.name}Mapper;
import $!{tableInfo.savePackageName}.mvc.service.$!{tableInfo.name}Service;
import $!{tableInfo.savePackageName}.util.R;
import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** $!{tableInfo.comment}($!{tableInfo.name})表服务实现类** @author $!author* @since $!time.currTime()*/
@Slf4j
@Service("$!tool.firstLowerCase($!{tableInfo.name})Service")
public class $!{tableName} implements $!{tableInfo.name}Service {
@Resource
private $!{tableInfo.name}Mapper $!tool.firstLowerCase($!{tableInfo.name})Mapper;/*** 通过ID查询单条数据** @param $!pk.name 主键* @return 实例对象*/
@Override
public R queryById($!pk.shortType $!pk.name) {return R.ok().setData(this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.queryById($!pk.name));}/*** 全查询** @param $!{tool.firstLowerCase($tableInfo.name)} 筛选条件* @return 查询结果*/
@Override
public R queryAll($!{tableInfo.name} $!{tool.firstLowerCase($tableInfo.name)}) {return R.ok().setData(this.$!{tool.firstLowerCase($tableInfo.name)}Mapper.queryAll($!{tool.firstLowerCase($tableInfo.name)}));}/*** 新增数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象* @return 实例对象*/
@Override
public R insert($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.insert($!tool.firstLowerCase($!{tableInfo.name}));return R.ok().setData($!tool.firstLowerCase($!{tableInfo.name}));}/*** 修改数据** @param $!tool.firstLowerCase($!{tableInfo.name}) 实例对象* @return 实例对象*/
@Override
public R update($!{tableInfo.name} $!tool.firstLowerCase($!{tableInfo.name})) {this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.update($!tool.firstLowerCase($!{tableInfo.name}));return R.ok().setData(this.queryById($!{tool.firstLowerCase($!{tableInfo.name})}.get$!tool.firstUpperCase($pk.name)()));}/*** 通过主键删除数据** @param $!pk.name 主键* @return 是否成功*/
@Override
public R deleteById($!pk.shortType $!pk.name) {boolean del = this.$!{tool.firstLowerCase($!{tableInfo.name})}Mapper.deleteById($!pk.name) > 0;return R.ok().setData(del);}}
##设置回调
$!callback.setFileName($tool.append("SwaggerConfig.java"))
$!callback.setSavePath($tool.append($tableInfo.savePath, "/config"))#if($tableInfo.savePackageName)package $!{tableInfo.savePackageName}.#{end}config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;import java.util.ArrayList;/*** Swagger配置** @author $!author* @since $!time.currTime()*/
@Slf4j
@Configuration
@EnableOpenApi
public class SwaggerConfig {/*** 用于读取配置文件 swagger 属性是否开启*/@Value("${swagger.enabled}")Boolean swaggerEnabled;@Beanpublic Docket docket() {return new Docket(DocumentationType.OAS_30).apiInfo(apiInfo())// 是否开启swagger.enable(swaggerEnabled).select()// 过滤条件,扫描指定路径下的文件.apis(RequestHandlerSelectors.basePackage("#if($tableInfo.savePackageName)$!{tableInfo.savePackageName}.#{end}mvc.controller"))// 指定路径处理,PathSelectors.any()代表不过滤任何路径//.paths(PathSelectors.any()).build();}/*** 作者信息*/private ApiInfo apiInfo() {Contact contact = new Contact("Peter Cheung", "https://github.com/PerCheung", "13733139823@163.com");return new ApiInfo("Spring Boot 集成 Swagger3 测试","Spring Boot 集成 Swagger3 测试接口文档","v1.0","https://github.com/PerCheung",contact,"Apache 2.0","https://www.apache.org/licenses/LICENSE-2.0",new ArrayList<>());}
}