# base模块讲解
# BaseEntity
实体基类,提取了实体中的常用字段,不需要每个实体中再重复定义这些字段,底层封装了mybatis-plus,因此需要在实体字段上添加@TableField注解
@Data
public class BaseEntity<T extends Model<?>> extends Model<T> {
/**
* 主键
* 默认采用UUID作为主键,可以根据自己的需求进行修改
*/
@ApiModelProperty(value = "主键", dataType = "String")
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
/**
* 创建时间
*/
@ApiModelProperty(value = "创建时间", dataType = "Date")
@TableField(value = "create_time", fill = FieldFill.INSERT)
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/**
* 修改时间
*/
@ApiModelProperty(value = "修改时间", dataType = "Date")
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;
/**
* 当前页
*/
@ApiModelProperty(value = "当前页", dataType = "Integer")
@TableField(exist = false)
private Integer current;
/**
* 每页条数
*/
@ApiModelProperty(value = "每页条数", dataType = "Integer")
@TableField(exist = false)
private Integer size;
}
mybatis-plus 注解说明:
- @TableName (opens new window) 表名注解,标识实体类对应的表,配置在实体类上
- @TableId (opens new window) 主键注解 配置在实体类主键字段
- IdType (opens new window) 主键自增策略 ,ASSIGN_UUID为32 位 UUID 字符串(推荐使用ASSIGN_UUID)
- @TableField (opens new window) 字段注解(非主键)
- @TableLogic (opens new window) 表字段逻辑处理注解(逻辑删除)详解 (opens new window)
- 其他注解请参考mybatis-plus官方文档 (opens new window)自行启用或实现 Model 父类
# BaseMapper
mapper接口的基类,所有mapper都需要继承该接口
public interface BaseMapper<T> extends Mapper<T> {
int insert(T entity);
int deleteById(Serializable id);
int deleteById(T entity);
int deleteByMap(@Param("cm") Map<String, Object> columnMap);
int delete(@Param("ew") Wrapper<T> queryWrapper);
int deleteBatchIds(@Param("coll") Collection<?> idList);
int updateById(@Param("et") T entity);
int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);
T selectById(Serializable id);
List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);
List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);
default T selectOne(@Param("ew") Wrapper<T> queryWrapper);
default boolean exists(Wrapper<T> queryWrapper);
Long selectCount(@Param("ew") Wrapper<T> queryWrapper);
List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);
List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);
List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);
<P extends IPage<T>> P selectPage(P page, @Param("ew") Wrapper<T> queryWrapper);
<P extends IPage<Map<String, Object>>> P selectMapsPage(P page, @Param("ew") Wrapper<T> queryWrapper);
}
# BaseService
service层基类,所有Service需要继承BaseService接口,
@Service
public interface BaseService<T> extends IService<T> {
/**
* 保存一个实体,null的属性也会保存,不会使用数据库默认值
*
* @param record
* @return
*/
int insert(T record);
/**
* 根据主键字段进行删除,方法参数必须包含完整的主键属性
*
* @param key
* @return
*/
int deleteById(Serializable key);
/**
* 根据主键字段批量删除
*
* @param ids 要删除的主键列表,以逗号分隔
* @return
*/
int deleteByIds(String ids);
/**
* 根据实体属性作为条件进行删除,查询条件使用等号
*
* @param record
* @return
*/
int delete(T record);
/**
* 根据主键更新实体全部字段,null值也会被更新
*
* @param columnPrimaryKey 数据库主键 如数据库库表中 user表的主键为id
* @param primaryKeyValue 数据库主键的值:如数据库库表中 user表的主键为id ,其中值为3 表示 针对 id=3的数据 所有字段进行更新
* @param record 实体对象
* @return
*/
int updateAllByPrimaryKey(String columnPrimaryKey, Object primaryKeyValue, T record);
/**
* 根据主键更新属性不为null的值,局部更新
*
* @param record
* @return
*/
int updateNotNullByPrimaryKey(T record);
/**
* 查询表中所有数据
*
* @return
*/
List<T> selectAll();
/**
* 根据主键查询一条数据
*
* @param key
* @return
*/
T selectById(Serializable key);
/**
* 根据实体中的属性值进行查询,查询条件使用等号
*
* @param record
* @return
*/
List<T> selectList(T record);
T selectOne(T t);
/**
* 根据 entity 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
* @param t 实体对象封装操作类(可以为 null)
*/
IPage<T> selectPage(Page<T> page, T t);
/**
* 根据 Wrapper 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件
* @param t 实体对象封装操作类
*/
IPage<Map<String, Object>> selectMapsPage(Page<Map<String, Object>> page, T t);
}
# BaseServiceImpl
所有ServiceImpl需要继承BaseServiceImpl实现类
public class BaseServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements BaseService<T> {
...
}
# BaseResponse
公共响应类
/**
* 公共响应类
*
* @param <T>
*/
@Data
public class BaseResponse<T> {
private String code;
private String msg;
private T data;
public BaseResponse() {
}
public BaseResponse(String code, String msg, T data) {
this.setCode(code);
this.setMsg(msg);
this.setData(data);
}
public static <T> BaseResponse<T> success() {
return new BaseResponse<T>(SysExceptionEnum.SUCCESS.getCode(), SysExceptionEnum.SUCCESS.getMsg(), null);
}
public static <T> BaseResponse<T> success(T data) {
return new BaseResponse<T>(SysExceptionEnum.SUCCESS.getCode(), SysExceptionEnum.SUCCESS.getMsg(), data);
}
public static <T> BaseResponse<T> success(String message, T data) {
return new BaseResponse<T>(SysExceptionEnum.SUCCESS.getCode(), message, data);
}
public static <T> BaseResponse<T> paramError() {
return new BaseResponse<T>(SysExceptionEnum.PARAM_ERROR.getCode(), SysExceptionEnum.PARAM_ERROR.getMsg(), null);
}
public static <T> BaseResponse<T> error() {
return new BaseResponse<T>(SysExceptionEnum.ERROR.getCode(), SysExceptionEnum.ERROR.getMsg(), null);
}
public static <T> BaseResponse<T> error(String message) {
return new BaseResponse<T>(SysExceptionEnum.ERROR.getCode(), message, null);
}
public static <T> BaseResponse<T> error(String code, String message) {
return new BaseResponse<T>(code, message, null);
}
public static <T> BaseResponse<T> error(String code, String message, T data) {
return new BaseResponse<T>(code, message, data);
}
public boolean isSuccess() {
return SysExceptionEnum.SUCCESS.getCode().equals(this.code);
}
}
# BaseController
BaseController是controller的基类,封装常用的增删改查和分页接口,所有的controller都需要继承该类
public class BaseController<T extends BaseEntity> {
@Autowired
private BaseService<T> baseService;
/**
* 保存一个实体,null的属性也会保存,会使用数据库默认值
*/
@ApiOperation(value = "保存实体")
@PostMapping(value = "insert")
public BaseResponse insert(@RequestBody T t) {
baseService.insert(t);
return BaseResponse.success();
}
/**
* 根据实体属性作为条件进行删除,查询条件使用等号
*
* @param record 对象
* @return
*/
@ApiOperation(value = "根据实体属性条件删除")
@PostMapping(value = "delete")
public BaseResponse delete(@RequestBody T record) {
return BaseResponse.success(baseService.delete(record));
}
/**
* 根据主键字段进行删除,方法参数必须包含完整的主键属性
*
* @param id
* @return
*/
@ApiOperation(value = "根据主键删除")
@PostMapping(value = "deleteById")
public BaseResponse deleteById(@RequestParam("id") String id) {
if (StringUtils.isBlank(id)) {
return BaseResponse.error("id 不能为空");
}
return BaseResponse.success(baseService.deleteById(id));
}
@ApiOperation(value = "根据主键批量删除")
@PostMapping(value = "/deleteByIds")
public BaseResponse deleteByIds(@RequestParam("ids") String ids) {
return BaseResponse.success(baseService.deleteByIds(ids));
}
/**
* 根据主键字段进行更新,null的属性不会更新
*/
@ApiOperation(value = "根据主键更新数据")
@PostMapping(value = "updateById")
public BaseResponse updateById(@RequestBody T t) {
if (StringUtils.isBlank(t.getId())) {
return BaseResponse.error("id 不能为空");
}
baseService.updateNotNullByPrimaryKey(t);
return BaseResponse.success();
}
/**
* 查询表中所有数据
*
* @mbggenerated
*/
@ApiOperation(value = "查询所有数据")
@GetMapping(value = "selectAll")
public BaseResponse selectAll() {
return BaseResponse.success(baseService.selectAll());
}
/**
* 根据主键查询一条数据
*
* @mbggenerated
*/
@ApiOperation(value = "根据id查询数据")
@GetMapping(value = "selectById")
public BaseResponse selectById(@RequestParam("id") String id) {
return BaseResponse.success(baseService.selectById(id));
}
/**
* 据实体中的属性值进行查询,查询条件使用等号
*
* @mbggenerated
*/
@ApiOperation(value = "根据实体属性条件进行查询")
@GetMapping(value = "selectList")
public BaseResponse selectList(T t) {
return BaseResponse.success(baseService.selectList(t));
}
/**
* <p>
* 根据 entity 条件,查询一条记录
* </p>
*/
@ApiOperation(value = "根据实体属性条件查询一条数据")
@GetMapping(value = "selectOne")
public BaseResponse selectOne(T t) {
return BaseResponse.success(baseService.selectOne(t));
}
/**
* 分页查询
*
* @param t
* @return
*/
@ApiOperation(value = "根据实体属性条件分页查询")
@GetMapping("/selectPage")
public BaseResponse<IPage<T>> selectPage(T t) {
IPage<T> pageData = baseService.selectPage(new Page<>(t.getCurrent(), t.getSize()), t);
return BaseResponse.success(pageData);
}
# BaseBusinessException
自定义业务异常基类,在自定义业务异常时都需要继承该类
@Data
public class BaseBusinessException extends RuntimeException{
private static final long serialVersionUID = 1L;
/**
* 系统错误码
*/
private String code;
/**
* 错误描述
*/
private String message;
public BaseBusinessException(String message) {
super(message);
}
public BaseBusinessException(BaseExceptionEnum baseEnum) {
this.code = baseEnum.getCode();
this.message = baseEnum.getMsg();
}
public BaseBusinessException(String code, String message, Throwable cause) {
super(cause);
this.code = code;
this.message = message;
}
public BaseBusinessException(String code, String message) {
super();
this.code = code;
this.message = message;
}
}
# BaseExceptionEnum
BaseExceptionEnum是自定义异常码枚举基类,在自定义异常码枚举时都需要实现该接口,并在其中定义各自的错误码
public interface BaseExceptionEnum {
String getCode();
String getMsg();
}
# SysExceptionEnum
系统异常码枚举类
public enum SysExceptionEnum implements BaseExceptionEnum {
FILE_NOT_FOUND_EXCEPTION("99001005","文件未找到异常"),
NO_HANDLER_FOUND_EXCEPTION("99001006","请求路径未匹配异常"),
NULL_POINTER_EXCEPTION("99001007","空指针异常"),
PARAM_VALIDATION_ERROR("99001008","参数校验异常"),
BUSINESS_EXE_ERROR("99001009","业务处理异常"),
SUCCESS("200","success"),
PARAM_ERROR("400","fail"),
ERROR("500","error");
private String code;
private String msg;
SysExceptionEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
# ExceptionHandlerAdvice
ExceptionHandlerAdvice是HOS的全局异常拦截机制,
@RestControllerAdvice是对Controller进行增强的,可以全局捕获spring mvc抛的异常,并匹配相应的ExceptionHandler,然后重新封装异常信息,返回值,统一格式返回给前端。
@Slf4j
@RestControllerAdvice(basePackages = {"com"})
public class ExceptionHandlerAdvice {
@ExceptionHandler({MethodArgumentNotValidException.class})
public BaseResponse validationErrorHandler(MethodArgumentNotValidException e) {
List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
StringBuilder stringBuilder = new StringBuilder();
allErrors.forEach(objectError -> stringBuilder.append(objectError.getDefaultMessage()).append(";"));
return BaseResponse.error(SysExceptionEnum.PARAM_VALIDATION_ERROR.getCode(), stringBuilder.toString());
}
/**
* 自定义异常
*
* @param e
* @return
*/
@ExceptionHandler({BaseBusinessException.class})
public BaseResponse handleBusinessMsgException(BaseBusinessException e) {
log.error("BusinessException code:{}, msg:{}", e.getCode(), e.getMessage());
return BaseResponse.error(e.getCode(), e.getMessage());
}
/**
* 文件未找到异常
*
* @param e
* @return
*/
@ExceptionHandler({FileNotFoundException.class})
public BaseResponse handleFileNotFoundException(FileNotFoundException e) {
return BaseResponse.error(SysExceptionEnum.FILE_NOT_FOUND_EXCEPTION.getCode(), SysExceptionEnum.FILE_NOT_FOUND_EXCEPTION.getMsg());
}
/**
* 请求路径未匹配异常
*
* @param e
* @return
*/
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler({NoHandlerFoundException.class})
public BaseResponse handleNoHandlerFoundException(NoHandlerFoundException e) {
return BaseResponse.error(SysExceptionEnum.NO_HANDLER_FOUND_EXCEPTION.getCode(), SysExceptionEnum.NO_HANDLER_FOUND_EXCEPTION.getMsg());
}
/**
* 异常
*
* @param e
* @return
*/
@ExceptionHandler({Exception.class})
public BaseResponse handleException(Exception e) {
log.error("系统处理异常", e);
return BaseResponse.error(SysExceptionEnum.BUSINESS_EXE_ERROR.getCode(), SysExceptionEnum.BUSINESS_EXE_ERROR.getMsg());
}
}