使用 Spring Boot 和 MyBatis-Plus 生成代码,可以大大简化开发流程,可以保持编码的规范性,生成单元测试等。以下是详细步骤:
配置pom.xml
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version>
</dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.4.1</version>
</dependency><!-- velocity-->
<dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>2.0</version>
</dependency><!-- swagger-->
<dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.8.0</version>
</dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.8.0</version>
</dependency><!-- 单元测试相关-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>
配置数据库连接
在 src/main/resources/application.properties 或 application.yml 中配置数据库连接信息:
server:port: 8000
spring:application:name: ocean-code-generationjackson:date-format: yyyy-MM-dd HH:mm:sstime-zone: GMT+8deserialization.accept_empty_string_as_null_object: truedatasource:driverClassName: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db-ocean?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=trueusername: rootpassword: 123456mvc:pathmatch:matching-strategy: ANT_PATH_MATCHERmybatis-plus:mapper-locations: classpath*:mapper/*Mapper.xmlconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
定义代码生成模版
模版代码目录截图:
核心代码
- controller.java.vm
package ${package.Controller};import ${package.base_packages}.common.BaseController;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.RequestMapping;
import ${package.base_packages}.common.ApiResult;
import ${package.base_packages}.common.PageResult;
import ${package.base_packages}.domain.dto.${entity}DTO;
import ${package.base_packages}.domain.entity.${entity};
import ${package.base_packages}.domain.qo.${entity}QO;
import ${package.base_packages}.domain.vo.${entity}VO;
import ${package.base_packages}.service.${entity}Service;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;/**1. $!{table.comment} 前端控制器2. 3. @author ${author}4. @time ${date}*/
@Api(value = "$!{table.comment}接口", tags = {"$!{table.comment}相关接口"})
#if(${restControllerStyle})
@RestController
#else
@Controller
#end
@RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
public class ${table.controllerName} extends BaseController {@Resourceprivate ${entity}Service service;@ApiOperation(value = "$!{table.comment}列表", notes = "$!{table.comment}列表", consumes = "application/json", produces = "application/json", httpMethod = "GET")@ApiResponses({@ApiResponse(code = 200, message = "OK"),@ApiResponse(code = 50000, message = "service exception")})@GetMapping("/list")public PageResult<${entity}VO> page(${entity}QO qo) {return service.page(qo);}@ApiOperation(value = "获取$!{table.comment}信息", notes = "获取$!{table.comment}信息", consumes = "application/json", produces = "application/json", httpMethod = "GET")@ApiImplicitParams({@ApiImplicitParam(name = "id", value = "$!{table.comment}ID", required = true)})@ApiResponses({@ApiResponse(code = 200, message = "OK", response = ${entity}.class),@ApiResponse(code = 50000, message = "service exception")})@GetMapping("/get/{id}")public ApiResult<${entity}> get(@PathVariable Long id) {${entity} entity = service.getById(id);if(null == entity) {return ApiResult.error();}return ApiResult.success(entity);}@ApiOperation(value = "保存$!{table.comment}", notes = "保存$!{table.comment}", consumes = "application/json", produces = "application/json", httpMethod = "POST")@ApiResponses({@ApiResponse(code = 200, message = "OK"),@ApiResponse(code = 50000, message = "service exception")})@PostMapping("/save")public ApiResult<Long> save(@RequestBody ${entity}DTO dto) {return service.save(dto);}@ApiOperation(value = "更新$!{table.comment}", notes = "更新$!{table.comment}", consumes = "application/json", produces = "application/json", httpMethod = "POST")@ApiResponses({@ApiResponse(code = 200, message = "OK"),@ApiResponse(code = 50000, message = "service exception")})@PostMapping("/update")public ApiResult<Long> update(@RequestBody ${entity}DTO dto) {return service.update(dto);}@ApiOperation(value = "删除$!{table.comment}", notes = "删除$!{table.comment}", consumes = "application/json", produces = "application/json", httpMethod = "DELETE")@ApiImplicitParams({@ApiImplicitParam(name = "id", value = "$!{table.comment}ID", required = true)})@ApiResponses({@ApiResponse(code = 200, message = "OK"),@ApiResponse(code = 50000, message = "service exception")})@DeleteMapping("/delete/{id}")public ApiResult<Void> delete(@PathVariable Long id) {service.removeById(id);return ApiResult.success();}
}
- service.java.vm
package ${package.Service};import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import ${package.qo_packages}.${entity}QO;
import ${package.vo_packages}.${entity}VO;
import ${package.dto_packages}.${entity}DTO;
import ${package.base_packages}.common.ApiResult;
import ${package.base_packages}.common.PageResult;/*** $!{table.comment} 服务类** @author ${author}* @time ${date}*/
#if(${kotlin})
interface ${table.serviceName} : ${superServiceClass}<${entity}>
#else
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {/*** @desc 分页查询** @param qo* @return ${package.base_packages}.common.PageResult<${package.vo_packages}.${entity}VO>*/PageResult<${entity}VO> page(${entity}QO qo);/*** @desc 保存** @param dto* @return ${package.base_packages}.common.ApiResult*/ApiResult<Long> save(${entity}DTO dto);/*** @desc 更新** @param dto* @return ${package.base_packages}.common.ApiResult*/ApiResult<Long> update(${entity}DTO dto);}
#end
- serviceImpl.java.vm
package ${package.ServiceImpl};import cn.hutool.core.bean.BeanUtil;
import ${package.base_packages}.common.ApiResult;
import ${package.base_packages}.common.PageResult;
import ${package.base_packages}.constant.ResultCode;
import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import ${package.qo_packages}.${entity}QO;
import ${package.vo_packages}.${entity}VO;
import ${package.dto_packages}.${entity}DTO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;/**1. $!{table.comment} 服务实现类2. 3. @author ${author}4. @time ${date}*/
@Service
public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {@Resourceprivate ${entity}Mapper mapper;@Overridepublic PageResult<${entity}VO> page(${entity}QO qo) {List<${entity}VO> data = mapper.list${entity}(qo);int total = mapper.count${entity}(qo);PageResult<${entity}VO> pageResult = PageResult.success(data, total);pageResult.setPageSize(qo.getPageSize());pageResult.setPageNum(qo.getPageNum());int pages = total % qo.getPageSize() == 0 ? total / qo.getPageSize() : total / qo.getPageSize() + 1;pageResult.setPages(pages);return pageResult;}@Override@Transactionalpublic ApiResult<Long> save(${entity}DTO dto) {${entity} entity = new ${entity}();BeanUtil.copyProperties(dto, entity);mapper.insert(entity);return ApiResult.success(entity.getId());}@Override@Transactionalpublic ApiResult<Long> update(${entity}DTO dto) {if(null == dto.getId()) {return ApiResult.error(ResultCode.PARAM_ERROR);}${entity} entity = new ${entity}();BeanUtil.copyProperties(dto, entity);mapper.updateById(entity);return ApiResult.success(entity.getId());}
}
- mapper.java.vm
package ${package.Mapper};import ${package.Entity}.${entity};
import ${superMapperClassPackage};
import ${package.qo_packages}.${entity}QO;
import ${package.vo_packages}.${entity}VO;
import java.util.List;
import org.apache.ibatis.annotations.Param;/**1. $!{table.comment} Mapper2. 3. @author ${author}4. @time ${date}*/
#if(${kotlin})
interface ${table.mapperName} : ${superMapperClass}<${entity}>
#else
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {/*** @desc $!{table.comment}列表** @param qo* @return java.util.List<${package.vo_packages}.${entity}VO>*/List<${entity}VO> list${entity}(@Param("qo") ${entity}QO qo);/*** @desc $!{table.comment}条数** @param qo* @return int*/int count${entity}(@Param("qo") ${entity}QO qo);
}
#end
- 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
#if(${baseColumnList})<!-- 通用查询结果列 --><sql id="Base_Column_List">
#foreach($field in ${table.commonFields})${field.columnName},
#end${table.fieldNames}</sql><select id="list${entity}" resultType="${package.vo_packages}.${entity}VO">SELECT
#foreach($field in ${table.commonFields})${field.columnName},
#end${table.fieldNames}FROM ${table.name}ORDER BY id DESCLIMIT #{qo.limit},#{qo.offset}</select><select id="count${entity}" resultType="java.lang.Integer">SELECT count(*) FROM ${table.name}</select>#end
</mapper>
- entity.java.vm
package ${package.Entity};#if(${swagger2})
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
#end
#if(${entityLombokModel})
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import java.io.Serializable;
#if(${chainModel})
import lombok.experimental.Accessors;
#end
#end/*** $!{table.comment}** @author ${author}* @time ${date}*/
#if(${entityLombokModel})
@Data#if(${superEntityClass})
@EqualsAndHashCode(callSuper = true)#else
@EqualsAndHashCode(callSuper = false)#end#if(${chainModel})
@Accessors(chain = true)#end
#end
#if(${swagger2})
@ApiModel(value="${entity}", description="$!{table.comment}")
#end
#if(${superEntityClass})
public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end {
#elseif(${activeRecord})
public class ${entity} extends Model<${entity}> {
#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" != "")#if(${swagger2})@ApiModelProperty(value = "${field.comment}")#else/*** ${field.comment}*/#end
#end
#if(${field.keyFlag})
## 普通字段
#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
#endprivate ${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")#endpublic ${field.propertyType} ${getprefix}${field.capitalName}() {return ${field.propertyName};}#if(${chainModel})public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {#elsepublic void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {#endthis.${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(${activeRecord})@Overrideprotected Serializable pkVal() {#if(${keyPropertyName})return this.${keyPropertyName};#elsereturn null;#end}#end
#if(!${entityLombokModel})@Overridepublic 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
}
- dto.java.vm
package ${package.dto_packages};import java.util.Date;
#if(${swagger2})
import io.swagger.annotations.ApiModelProperty;
#end
import lombok.Data;
import java.io.Serializable;/*** $!{table.comment}** @author ${author}* @time ${date}*/
@Data
public class ${entity}DTO implements Serializable {private static final long serialVersionUID = 1L;## ---------- BEGIN 字段循环遍历 ----------
#foreach($field in ${table.fields})
#if(${field.keyFlag})#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")#if(${swagger2})@ApiModelProperty(value = "${field.comment}")#else/*** ${field.comment}*/#end
#end
#if(${field.fill})## ----- 存在字段填充设置 -----#elseif(${field.convert})
@TableField("${field.annotationColumnName}")
#end
## 乐观锁注解
#if(${versionFieldName}==${field.name})
@Version
#end
## 逻辑删除注解
#if(${logicDeleteFieldName}==${field.name})
@TableLogic
#endprivate ${field.propertyType} ${field.propertyName};#end
## ---------- END 字段循环遍历 ----------}
- qo.java.vm
package ${package.qo_packages};import java.util.Date;
import ${package.base_packages}.common.PageDomain;
#if(${swagger2})
import io.swagger.annotations.ApiModelProperty;
#end
import lombok.Data;
import java.io.Serializable;/*** $!{table.comment}** @author ${author}* @time ${date}*/
@Data
public class ${entity}QO extends PageDomain implements Serializable {private static final long serialVersionUID = 1L;## ---------- BEGIN 字段循环遍历 ----------
#foreach($field in ${table.fields})
#if(${field.keyFlag})#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")#if(${swagger2})@ApiModelProperty(value = "${field.comment}")#else/*** ${field.comment}*/#end
#end
#if(${field.fill})## ----- 存在字段填充设置 -----#elseif(${field.convert})
@TableField("${field.annotationColumnName}")
#end
## 乐观锁注解
#if(${versionFieldName}==${field.name})
@Version
#end
## 逻辑删除注解
#if(${logicDeleteFieldName}==${field.name})
@TableLogic
#endprivate ${field.propertyType} ${field.propertyName};#end
## ---------- END 字段循环遍历 ----------}
- vo.java.vm
package ${package.vo_packages};import java.util.Date;
#if(${swagger2})
import io.swagger.annotations.ApiModelProperty;
#end
import lombok.Data;
import java.io.Serializable;/*** $!{table.comment}** @author ${author}* @time ${date}*/
@Data
public class ${entity}VO implements Serializable {private static final long serialVersionUID = 1L;## ---------- BEGIN 字段循环遍历 ----------
#foreach($field in ${table.fields})
#if(${field.keyFlag})#set($keyPropertyName=${field.propertyName})
#end
#if("$!field.comment" != "")#if(${swagger2})@ApiModelProperty(value = "${field.comment}")#else/*** ${field.comment}*/#end
#end
#if(${field.fill})## ----- 存在字段填充设置 -----#elseif(${field.convert})
@TableField("${field.annotationColumnName}")
#end
## 乐观锁注解
#if(${versionFieldName}==${field.name})
@Version
#end
## 逻辑删除注解
#if(${logicDeleteFieldName}==${field.name})
@TableLogic
#endprivate ${field.propertyType} ${field.propertyName};#end
## ---------- END 字段循环遍历 ----------}
单元测试代码
- controller.java.vm
package ${package.Controller};import ${package.base_packages}.common.ApiResult;
import ${package.base_packages}.common.PageResult;
import ${package.base_packages}.domain.dto.${entity}DTO;
import ${package.base_packages}.domain.entity.${entity};
import ${package.base_packages}.domain.qo.${entity}QO;
import ${package.base_packages}.domain.vo.${entity}VO;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import com.alibaba.fastjson2.JSON;@Slf4j
@SpringBootTest
class ${entity}ControllerTest {@Resourceprivate ${entity}Controller controller;@Testvoid page() {${entity}QO qo = new ${entity}QO();PageResult<${entity}VO> result = controller.page(qo);log.info("{}", JSON.toJSONString(result));}@Testvoid get() {Long id = 0L;ApiResult<${entity}> result = controller.get(id);log.info("{}", JSON.toJSONString(result));}@Testvoid save() {${entity}DTO dto = new ${entity}DTO();ApiResult<?> result = controller.save(dto);log.info("{}", JSON.toJSONString(result));}@Testvoid update() {${entity}DTO dto = new ${entity}DTO();ApiResult<?> result = controller.update(dto);log.info("{}", JSON.toJSONString(result));}@Testvoid delete() {Long id = 0L;ApiResult<?> result = controller.delete(id);log.info("{}", JSON.toJSONString(result));}
}
- service.java.vm
package ${package.Service};import ${package.qo_packages}.${entity}QO;
import ${package.vo_packages}.${entity}VO;
import ${package.dto_packages}.${entity}DTO;
import ${package.base_packages}.common.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import com.alibaba.fastjson2.JSON;
import javax.annotation.Resource;@Slf4j
@SpringBootTest
class ${entity}ServiceTest {@Resourceprivate ${entity}Service service;@Testvoid page() {${entity}QO qo = new ${entity}QO();PageResult<${entity}VO> result = service.page(qo);log.info("{}", JSON.toJSONString(result));}@Testvoid save() {${entity}DTO dto = new ${entity}DTO();service.save(dto);}@Testvoid update() {${entity}DTO dto = new ${entity}DTO();service.update(dto);}
}
- mapper.java.vm
package ${package.Mapper};import ${package.qo_packages}.${entity}QO;
import ${package.vo_packages}.${entity}VO;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import com.alibaba.fastjson2.JSON;
import javax.annotation.Resource;@Slf4j
@SpringBootTest
class ${entity}MapperTest {@Resourceprivate ${entity}Mapper mapper;@Testvoid list${entity}() {${entity}QO qo = new ${entity}QO();List<${entity}VO> result = mapper.list${entity}(qo);log.info("{}", JSON.toJSONString(result));}@Testvoid count${entity}() {${entity}QO qo = new ${entity}QO();int result = mapper.count${entity}(qo);log.info("{}", result);}
}
其他使用到的类
package com.angel.ocean.common;public class BaseController {}
package com.angel.ocean.common;import com.angel.ocean.constant.ResultCode;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;@Data
public class ApiResult<T> {@ApiModelProperty(value = "响应码")private Integer code;@ApiModelProperty(value = "提示信息")private String msg;@ApiModelProperty(value = "数据集合")private T data;public ApiResult(Integer code, String msg, T data) {this.code = code;this.msg = msg;this.data = data;}public static <T> ApiResult<T> success(T data) {return new ApiResult(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), data);}public static <T> ApiResult<T> success() {return new ApiResult(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), null);}public static <T> ApiResult<T> error(int code, String msg) {return new ApiResult(code, msg, null);}public static <T> ApiResult<T> error() {return new ApiResult(ResultCode.SERVICE_INTERNAL_ERROR.getCode(), ResultCode.SERVICE_INTERNAL_ERROR.getMsg(), null);}public static <T> ApiResult<T> error(ResultCode messageCode) {return new ApiResult(messageCode.getCode(), messageCode.getMsg(), null);}
}
package com.angel.ocean.common;import com.angel.ocean.constant.ResultCode;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.List;@Data
public class PageResult<T> implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty(value = "总条数")private Integer total;@ApiModelProperty(value = "数据集合")private List<T> rows;@ApiModelProperty(value = "响应码")private Integer code;@ApiModelProperty(value = "提示信息")private String msg;@ApiModelProperty(value = "页码,1-首页")private Integer pageNum;@ApiModelProperty(value = "每页数据大小")private Integer pageSize;@ApiModelProperty(value = "总页数")private Integer pages;public PageResult() {}public PageResult(List<T> list, int total) {this.rows = list;this.total = total;}public PageResult(int code, String msg) {this.code = code;this.msg = msg;}public PageResult(Integer total, List<T> rows, int code, String msg) {this.total = total;this.rows = rows;this.code = code;this.msg = msg;}public PageResult(Integer total, List<T> rows, int code, String msg, int pageNum, int pageSize) {this.total = total;this.rows = rows;this.code = code;this.msg = msg;this.pageNum = pageNum;this.pageSize = pageSize;this.pages = total % pageSize == 0 ? total / pageSize : total / pageSize + 1;}public static <T> PageResult<T> success(List<T> list, Integer total) {return new PageResult(total, list, ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg());}public static <T> PageResult<T> success(List<T> list, Integer total, Integer pageNum, Integer pageSize) {return new PageResult(total, list, ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), pageNum, pageSize);}public static <T> PageResult<T> error(ResultCode resultCode) {return new PageResult(resultCode.getCode(), resultCode.getMsg());}public static <T> PageResult<T> error() {return new PageResult(ResultCode.SERVICE_INTERNAL_ERROR.getCode(), ResultCode.SERVICE_INTERNAL_ERROR.getMsg());}
}
package com.angel.ocean.common;import io.swagger.annotations.ApiModelProperty;public class PageDomain {/**** 页码*/@ApiModelProperty(value = "页码,1-首页")private Integer pageNum;/**** 页面条数*/@ApiModelProperty(value = "每页数据大小")private Integer pageSize;@ApiModelProperty(hidden = true)private Integer limit;@ApiModelProperty(hidden = true)private Integer offset;public int getLimit() {limit = (getPageNum() - 1) * getPageSize();return limit;}public int getOffset() {offset = getPageSize();return offset;}public Integer getPageNum() {if(null == pageNum || pageNum < 1) {return 1;}return pageNum;}public void setPageNum(Integer pageNum) {this.pageNum = pageNum;}public Integer getPageSize() {if(null == pageSize || pageSize < 1) {pageSize = 10;}return pageSize;}public void setPageSize(Integer pageSize) {this.pageSize = pageSize;}
}
定义代码生成执行方法
package com.angel.ocean;import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
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.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.List;@SpringBootTest
class ApplicationTests {@Testvoid generate() {// 1、创建代码生成器AutoGenerator mpg = new AutoGenerator();// 表名String tableName = "sys_role";// 表前缀String tablePrefix = "";// 包名String packages = "com.angel.ocean";// 2、全局配置GlobalConfig gc = new GlobalConfig();String projectPath = System.getProperty("user.dir");gc.setOutputDir(projectPath + "/src/main/java");gc.setAuthor("Jaime.yu");gc.setOpen(false); //生成后是否打开资源管理器gc.setFileOverride(false); //重新生成时文件是否覆盖gc.setServiceName("%sService"); //去掉Service接口的首字母Igc.setIdType(IdType.AUTO); //主键策略gc.setDateType(DateType.ONLY_DATE); //定义生成的实体类中日期类型gc.setSwagger2(true); //开启Swagger2模式gc.setBaseResultMap(true); //启用通用查询映射结果gc.setBaseColumnList(true); //启用通用查询结果列mpg.setGlobalConfig(gc);// 3、数据源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setUrl("jdbc:mysql://localhost:3306/db-ocean?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false");dsc.setDriverName("com.mysql.cj.jdbc.Driver");dsc.setUsername("root");dsc.setPassword("123456");dsc.setDbType(DbType.MYSQL);mpg.setDataSource(dsc);// 4、包配置PackageConfig pc = new PackageConfig();pc.setModuleName(null); //模块名pc.setParent(packages);pc.setController("controller");pc.setEntity("domain.entity");pc.setService("service");pc.setMapper("mapper");mpg.setPackageInfo(pc);// 配置模板引擎TemplateConfig templateConfig = new TemplateConfig();templateConfig.setXml(null);mpg.setTemplate(templateConfig);// 注入自定义配置,可以在 VM 中使用 cfg.injectionConfig 设置的值InjectionConfig injectionConfig = new InjectionConfig() {@Overridepublic void initMap() {this.getConfig().getPackageInfo().put("base_packages", packages);this.getConfig().getPackageInfo().put("entity_packages", packages + StringPool.DOT + "domain" + StringPool.DOT + "entity");this.getConfig().getPackageInfo().put("dto_packages", packages + StringPool.DOT + "domain" + StringPool.DOT + "dto");this.getConfig().getPackageInfo().put("vo_packages", packages + StringPool.DOT + "domain" + StringPool.DOT + "vo");this.getConfig().getPackageInfo().put("qo_packages", packages + StringPool.DOT + "domain" + StringPool.DOT + "qo");}};//自定义文件输出位置(非必须)List<FileOutConfig> fileOutList = new ArrayList<FileOutConfig>();fileOutList.add(new FileOutConfig("/templates/qo.java.vm") {@Overridepublic String outputFile(TableInfo tableInfo) {return projectPath + getPath(packages) + "/domain/qo"+ "/" + tableInfo.getEntityName() + "QO" + StringPool.DOT_JAVA;}});fileOutList.add(new FileOutConfig("/templates/dto.java.vm") {@Overridepublic String outputFile(TableInfo tableInfo) {return projectPath + getPath(packages) + "/domain/dto"+ "/" + tableInfo.getEntityName() + "DTO" + StringPool.DOT_JAVA;}});fileOutList.add(new FileOutConfig("/templates/vo.java.vm") {@Overridepublic String outputFile(TableInfo tableInfo) {return projectPath + getPath(packages) + "/domain/vo"+ "/" + tableInfo.getEntityName() + "VO" +StringPool.DOT_JAVA;}});fileOutList.add(new FileOutConfig("/templates/mapper.xml.vm") {@Overridepublic String outputFile(TableInfo tableInfo) {return "src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;}});fileOutList.add(new FileOutConfig("/templates/test/mapper.java.vm") {@Overridepublic String outputFile(TableInfo tableInfo) {return projectPath + getTestPath(packages) + "/mapper"+ "/" + tableInfo.getEntityName() + "MapperTest" + StringPool.DOT_JAVA;}});fileOutList.add(new FileOutConfig("/templates/test/service.java.vm") {@Overridepublic String outputFile(TableInfo tableInfo) {return projectPath + getTestPath(packages) + "/service"+ "/" + tableInfo.getEntityName() + "ServiceTest" + StringPool.DOT_JAVA;}});fileOutList.add(new FileOutConfig("/templates/test/controller.java.vm") {@Overridepublic String outputFile(TableInfo tableInfo) {return projectPath + getTestPath(packages) + "/controller"+ "/" + tableInfo.getEntityName() + "ControllerTest" + StringPool.DOT_JAVA;}});injectionConfig.setFileOutConfigList(fileOutList);mpg.setCfg(injectionConfig);// 5、策略配置StrategyConfig strategy = new StrategyConfig();strategy.setInclude(tableName);//对那一张表生成代码strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略strategy.setTablePrefix(tablePrefix); //生成实体时去掉表前缀strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作strategy.setRestControllerStyle(true); //restful api风格控制器strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符mpg.setStrategy(strategy);// 6、执行mpg.execute();}private String getPath(String packages) {String path = "";if(StrUtil.isNotEmpty(packages)) {path = "/src/main/java/" + packages.replace(".", "/") + "/";}return path;}private String getTestPath(String packages) {String path = "";if(StrUtil.isNotEmpty(packages)) {path = "/src/test/java/" + packages.replace(".", "/") + "/";}return path;}}
代码生成截图
红色框中为生成的代码,包含controller/service/mapper/entity/dto/qo/vo,以及单元测试代码
启动服务
Swagger配置:
package com.angel.ocean.config;import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;/*** swagger配置文件*/
@Slf4j
@Configuration
@EnableSwagger2
public class Swagger2Config {@Beanpublic Docket createRestApi() {log.info("进入到swagger的配置中,swagger地址:http://<host>:<port>/swagger-ui.html");return new Docket(DocumentationType.SWAGGER_2)// 指定构建api文档的详细信息的方法:apiInfo().apiInfo(apiInfo()).select()// 指定要生成api接口的包路径,这里把controller作为包路径,生成controller中的所有接口.apis(RequestHandlerSelectors.basePackage("com.angel.ocean.controller")).paths(PathSelectors.any()).build();}/*** 构建api文档的详细信息* @return*/private ApiInfo apiInfo() {return new ApiInfoBuilder()// 设置页面标题.title("Spring Boot集成Swagger2接口总览")// 设置接口描述.description("Swagger接口学习")// 设置联系方式.contact(new Contact("测试swagger","http://localhost:8000/","861565437@qq.com"))// 设置版本.version("1.0")// 构建.build();}
}