# 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 注解说明:

# 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());
    }
}