一、本节内容
二、修改ID为雪花算法
MybatisPlusGenerator
配置//全局主键类型
.idType(IdType.ASSIGN_ID)
MybatisPlusGenerator
,发现SystemLog.java
有更新三、引入mapstruct
1. 添加依赖
org.mapstruct
mapstruct
1.5.5.Final
provided
2. 添加构建工具
org.apache.maven.plugins
maven-compiler-plugin
3.8.1
1.8
1.8
org.projectlombok
lombok
1.18.30
org.mapstruct
mapstruct-processor
1.5.5.Final
3. 调整spring-boot-starter-freemarker
和mybatis-plus-generator
的scope
为test
(非必须)
这2个jar仅在测试阶段,自动生成文件使用,因此可以指定为test属性
org.springframework.boot
spring-boot-starter-freemarker
test
com.baomidou
mybatis-plus-generator
3.5.3.2
test
4. 添加validation依赖,后面校验会用到
org.springframework.boot
spring-boot-starter-validation
四、调整controller.java.ftl
模板
@RequestBody
注解),增加校验@Validated
save
反参、removeById
入参id、getById
入参id,接收字符串String,内部转成Long执行业务逻辑。原因:方便前端接口定义,防止js long int失真package ${package.Controller};
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.common.http.RestResult;
import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.stereotype.Controller;
import ${superControllerClassPackage};
import javax.annotation.Resource;
/**
*
* ${table.comment!} 前端控制器
*
*
* @author ${author}
* @since ${date}
*/
@RestController
@Controller
@RequestMapping("/${package.ModuleName}/${controllerMappingHyphen}${table.entityPath}")
class ${table.controllerName} : ${superControllerClass}()
@Api(tags = "${table.comment!}")
public class ${table.controllerName} extends ${superControllerClass} {
public class ${table.controllerName} {
@Resource
private ${table.serviceName} ${table.serviceName?uncap_first};
@PostMapping("/save")
@ApiOperation(value = "新增${table.comment!}")
public RestResult save(@RequestBody @Validated ${entity} ${entity?uncap_first}) {
${table.serviceName?uncap_first}.save(${entity?uncap_first});
return RestResult.getSuccessResult(String.valueOf(${entity?uncap_first}.getId()));
}
@PostMapping("/removeById")
@ApiOperation(value = "根据id删除${table.comment!}")
public RestResult removeById(String id) {
boolean success = ${table.serviceName?uncap_first}.removeById(Long.parseLong(id));
return RestResult.getSuccessResult(success);
}
@PostMapping("/updateById")
@ApiOperation(value = "根据id更新${table.comment!}")
public RestResult updateById(@RequestBody @Validated ${entity} ${entity?uncap_first}) {
boolean success = ${table.serviceName?uncap_first}.updateById(${entity?uncap_first});
return RestResult.getSuccessResult(success);
}
@PostMapping("/getById")
@ApiOperation(value = "根据id查询${table.comment!}")
public RestResult getById(String id) {
${entity} ${entity?uncap_first} = ${table.serviceName?uncap_first}.getById(Long.parseLong(id));
return RestResult.getSuccessResult(${entity?uncap_first});
}
@PostMapping("/page")
@ApiOperation(value = "分页查询${table.comment!}")
public RestResult page(Integer pageNum, Integer pageSize) {
Page page = ${table.serviceName?uncap_first}.page(new Page(pageNum, pageSize));
return RestResult.getSuccessResult(page);
}
}
重新生成的SystemLogController
如下:
package com.example.demo.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.common.http.RestResult;
import com.example.demo.model.SystemLog;
import com.example.demo.service.SystemLogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
*
* 系统日志表 前端控制器
*
*
* @author chenzl
* @since 2023-10-11
*/
@RestController
@RequestMapping("/systemLog")
@Api(tags = "系统日志表")
public class SystemLogController {
@Resource
private SystemLogService systemLogService;
@PostMapping("/save")
@ApiOperation(value = "新增系统日志表")
public RestResult save(@RequestBody @Validated SystemLog systemLog) {
systemLogService.save(systemLog);
return RestResult.getSuccessResult(String.valueOf(systemLog.getId()));
}
@PostMapping("/removeById")
@ApiOperation(value = "根据id删除系统日志表")
public RestResult removeById(String id) {
boolean success = systemLogService.removeById(Long.parseLong(id));
return RestResult.getSuccessResult(success);
}
@PostMapping("/updateById")
@ApiOperation(value = "根据id更新系统日志表")
public RestResult updateById(@RequestBody @Validated SystemLog systemLog) {
boolean success = systemLogService.updateById(systemLog);
return RestResult.getSuccessResult(success);
}
@PostMapping("/getById")
@ApiOperation(value = "根据id查询系统日志表")
public RestResult getById(String id) {
SystemLog systemLog = systemLogService.getById(Long.parseLong(id));
return RestResult.getSuccessResult(systemLog);
}
@PostMapping("/page")
@ApiOperation(value = "分页查询系统日志表")
public RestResult page(Integer pageNum, Integer pageSize) {
Page page = systemLogService.page(new Page(pageNum, pageSize));
return RestResult.getSuccessResult(page);
}
}
五、使用mapstruct
1. 新建创建入参类SystemLogSaveCommand.java
com.baomidou.mybatisplus.annotation
相关注解内容package com.example.demo.model.command;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@ApiModel(value = "SystemLogSaveCommand", description = "系统日志表新增入参")
public class SystemLogSaveCommand {
@ApiModelProperty("日志信息描述")
private String description;
@ApiModelProperty("方法名称")
private String method;
@ApiModelProperty("日志类型 0是正常,1是异常")
private String logType;
@ApiModelProperty("请求的ip")
private String requestIp;
@ApiModelProperty("异常错误码")
private String exceptionCode;
@ApiModelProperty("异常详情")
private String exceptionDetail;
@ApiModelProperty("请求参数")
private String params;
@ApiModelProperty("请求的用户id")
private String userId;
@ApiModelProperty("创建人")
private String createdBy;
}
2. 新建更新入参类SystemLogUpdateCommand.java
com.baomidou.mybatisplus.annotation
相关注解内容@NotBlank(message = "id不能为空")
,控制更新时id必传package com.example.demo.model.command;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
@Getter
@Setter
@ApiModel(value = "SystemLogUpdateCommand", description = "系统日志表")
public class SystemLogUpdateCommand {
@NotBlank(message = "id不能为空")
private String id;
@ApiModelProperty("日志信息描述")
private String description;
@ApiModelProperty("方法名称")
private String method;
@ApiModelProperty("日志类型 0是正常,1是异常")
private String logType;
@ApiModelProperty("请求的ip")
private String requestIp;
@ApiModelProperty("异常错误码")
private String exceptionCode;
@ApiModelProperty("异常详情")
private String exceptionDetail;
@ApiModelProperty("请求参数")
private String params;
@ApiModelProperty("请求的用户id")
private String userId;
@ApiModelProperty("最后修改人")
private String updatedBy;
@ApiModelProperty("版本号")
private Integer version;
}
3. 新建详情反参类SystemLogDetailResp.java
com.baomidou.mybatisplus.annotation
相关注解内容package com.example.demo.model.resp;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
@Getter
@Setter
@ApiModel(value = "SystemLogDetailResp", description = "系统日志表")
public class SystemLogDetailResp {
private String id;
@ApiModelProperty("日志信息描述")
private String description;
@ApiModelProperty("方法名称")
private String method;
@ApiModelProperty("日志类型 0是正常,1是异常")
private String logType;
@ApiModelProperty("请求的ip")
private String requestIp;
@ApiModelProperty("异常错误码")
private String exceptionCode;
@ApiModelProperty("异常详情")
private String exceptionDetail;
@ApiModelProperty("请求参数")
private String params;
@ApiModelProperty("请求的用户id")
private String userId;
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
@ApiModelProperty("创建人")
private String createdBy;
@ApiModelProperty("最后修改时间")
private LocalDateTime updateTime;
@ApiModelProperty("最后修改人")
private String updatedBy;
@ApiModelProperty("版本号")
private Integer version;
}
4. 新建分页反参类SystemLogPageResp.java
com.baomidou.mybatisplus.annotation
相关注解内容package com.example.demo.model.resp;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
@Getter
@Setter
@ApiModel(value = "SystemLogPageResp", description = "系统日志表")
public class SystemLogPageResp {
private String id;
@ApiModelProperty("日志信息描述")
private String description;
@ApiModelProperty("方法名称")
private String method;
@ApiModelProperty("日志类型 0是正常,1是异常")
private String logType;
@ApiModelProperty("请求的ip")
private String requestIp;
@ApiModelProperty("异常错误码")
private String exceptionCode;
@ApiModelProperty("异常详情")
private String exceptionDetail;
@ApiModelProperty("请求参数")
private String params;
@ApiModelProperty("请求的用户id")
private String userId;
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
@ApiModelProperty("创建人")
private String createdBy;
@ApiModelProperty("最后修改时间")
private LocalDateTime updateTime;
@ApiModelProperty("最后修改人")
private String updatedBy;
@ApiModelProperty("版本号")
private Integer version;
}
5. 新建mapstruct转换类SystemLogConverter
package com.example.demo.model.converter;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.model.SystemLog;
import com.example.demo.model.command.SystemLogSaveCommand;
import com.example.demo.model.command.SystemLogUpdateCommand;
import com.example.demo.model.resp.SystemLogDetailResp;
import com.example.demo.model.resp.SystemLogPageResp;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface SystemLogConverter {
SystemLogConverter INSTANCE = Mappers.getMapper(SystemLogConverter.class);
SystemLog convert(SystemLogSaveCommand command);
SystemLog convert(SystemLogUpdateCommand command);
SystemLogDetailResp convert2DetailResp(SystemLog systemLog);
Page convert2PageResp(Page page);
}
6. 改造出入参SystemLogController
save
方法入参修改为SystemLogSaveCommand
,使用SystemLogConverter
转换为SystemLog
执行后续操作,可以拷贝所有属性到SystemLog
updateById
方法入参修改为SystemLogUpdateCommand
,使用SystemLogConverter
转换为SystemLog
执行后续操作,可以拷贝所有属性到SystemLog
,同时将id从String转换为Long参与后续逻辑getById
方法出参使用SystemLogConverter
转换为SystemLogDetailResp
后返回,可以把id转换为String,同时不返回deleteFlag
属性page
方法出参使用SystemLogConverter
转换为SystemLogPageResp
后返回,可以把id转换为String,同时不返回deleteFlag
属性package com.example.demo.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.common.http.RestResult;
import com.example.demo.model.SystemLog;
import com.example.demo.model.command.SystemLogSaveCommand;
import com.example.demo.model.command.SystemLogUpdateCommand;
import com.example.demo.model.converter.SystemLogConverter;
import com.example.demo.model.resp.SystemLogDetailResp;
import com.example.demo.model.resp.SystemLogPageResp;
import com.example.demo.service.SystemLogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
*
* 系统日志表 前端控制器
*
*
* @author chenzl
* @since 2023-10-11
*/
@RestController
@RequestMapping("/systemLog")
@Api(tags = "系统日志表")
public class SystemLogController {
@Resource
private SystemLogService systemLogService;
@PostMapping("/save")
@ApiOperation(value = "新增系统日志表")
public RestResult save(@RequestBody @Validated SystemLogSaveCommand command) {
SystemLog systemLog = SystemLogConverter.INSTANCE.convert(command);
systemLogService.save(systemLog);
return RestResult.getSuccessResult(String.valueOf(systemLog.getId()));
}
@PostMapping("/removeById")
@ApiOperation(value = "根据id删除系统日志表")
public RestResult removeById(String id) {
boolean success = systemLogService.removeById(Long.parseLong(id));
return RestResult.getSuccessResult(success);
}
@PostMapping("/updateById")
@ApiOperation(value = "根据id更新系统日志表")
public RestResult updateById(@RequestBody @Validated SystemLogUpdateCommand command) {
SystemLog systemLog = SystemLogConverter.INSTANCE.convert(command);
boolean success = systemLogService.updateById(systemLog);
return RestResult.getSuccessResult(success);
}
@PostMapping("/getById")
@ApiOperation(value = "根据id查询系统日志表")
public RestResult getById(String id) {
SystemLog systemLog = systemLogService.getById(Long.parseLong(id));
SystemLogDetailResp resp = SystemLogConverter.INSTANCE.convert2DetailResp(systemLog);
return RestResult.getSuccessResult(resp);
}
@PostMapping("/page")
@ApiOperation(value = "分页查询系统日志表")
public RestResult page(Integer pageNum, Integer pageSize) {
Page page = systemLogService.page(new Page(pageNum, pageSize));
Page resp = SystemLogConverter.INSTANCE.convert2PageResp(page);
return RestResult.getSuccessResult(resp);
}
}
六、添加乐观锁拦截器
com.example.demo.config.MybatisPlusConfig
新增乐观锁拦截器OptimisticLockerInnerInterceptor
package com.example.demo.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
/**
* 添加分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
//如果配置多个插件,切记分页最后添加
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//如果有多数据源可以不配具体类型 否则都建议配上具体的DbType
//interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
七、自动填充创建和更新时间和操作人
package com.example.demo.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "createdBy", String.class, "system");
}
@Override
public void updateFill(MetaObject metaObject) {
// 起始版本 3.3.0(推荐)
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
this.strictUpdateFill(metaObject, "updatedBy", String.class, "system");
}
}
八、项目地址
gitee
PS:可以通过tag下载本文对应的代码版本
九、结尾
集成mapstruct已完成,有问题可以联系chenzhenlindx@qq.com