https://www.yuque.com/soumns-comkm/dtai8u/pzgak6
MybatisPlus实现自动填充
对于需要自动填充的内容(自动填充就相当于,对于某个用户更新时间,插入时间等,非人为输入的数据库内容通过代码来实现在提交事务的时候,自动添加这些内容,而不是使用set方法,调用实体类方法进行赋值)
第一步
可以通过在实体类上添加注解来实现自动填充
@TableField(fill = FieldFill.INSERT) private Date createTime;
例如,以上代码就是添加了某实体类的项上,就能在插入的时候,调用方法,进行自动填充。
第二步
新建一个实体类并且,实现接口,MetaObjectHandler并且实现接口中的接口。
@Component public class MyMetaObjectHandler implements MetaObjectHandler{ @Override public void insertFill(MetaObject metaObject){ this.setFieldValByName("createTime",new Date(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); } @Override public void updateFill(MetaObject metaObject){ this.setFieldValByName("updateTime",new Date(),metaObject); } }
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
private final String id = "id";
private final String createdBy = "createdBy";
private final String createdTime = "createdTime";
private final String updatedBy = "updatedBy";
private final String updatedTime = "updatedTime";
@Override
public void insertFill(MetaObject metaObject) {
if (metaObject.hasSetter(id)) {
this.setFieldValByName(id, IdUtil.simpleUUID().toUpperCase(), metaObject);
}
if (metaObject.hasSetter(createdBy)) {
this.setFieldValByName(createdBy, "SYSTEM", metaObject);
}
if (metaObject.hasSetter(createdTime)) {
this.setFieldValByName(createdTime, LocalDateTime.now(), metaObject);
}
if (metaObject.hasSetter(updatedBy)) {
this.setFieldValByName(updatedBy, "SYSTEM", metaObject);
}
if (metaObject.hasSetter(updatedTime)) {
this.setFieldValByName(updatedTime, LocalDateTime.now(), metaObject);
}
}
@Override
public void updateFill(MetaObject metaObject) {
if (metaObject.hasSetter(updatedBy)) {
this.setFieldValByName(updatedBy, "SYSTEM", metaObject);
}
if (metaObject.hasSetter(updatedTime)) {
this.setFieldValByName(updatedTime, LocalDateTime.now(), metaObject);
}
}
}
@Data
@Accessors(chain = true)
public class MyBaseBean implements Serializable {
@TableId(type = IdType.INPUT)
@TableField(value = "ID", fill = FieldFill.INSERT)
@ApiModelProperty(value = "主键ID")
private String id;
@TableField(value = "CREATED_BY", fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建人")
private String createdBy;
@TableField(value = "CREATED_TIME", fill = FieldFill.INSERT)
@ApiModelProperty(value = "创建时间")
private LocalDateTime createdTime;
@TableField(value = "UPDATED_BY", fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "修改人")
private String updatedBy;
@TableField(value = "UPDATED_TIME", fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "修改时间")
private LocalDateTime updatedTime;
@TableField(value = "DEL_FLAG")
@ApiModelProperty(value = "删除标记 0-否,1-是")
private Boolean delFlag;
}
乐观锁
手动实现乐观锁
1.在数据库中新增版本号字段,来表示当前版本号。
2.在类中添加版本号属性并且添加@Version注解,这里可以使用上一节的自动增长配置每次版本号更新后+1
3.配置乐观锁插件
@Bean public OptimisticLockerInterceptor optimisticLockerInterceptor(){ return new OptimisticLockerInterceptor(); }
五、如何选择
在乐观锁与悲观锁的选择上面,主要看下两者的区别以及适用场景就可以了。
1️⃣响应效率:如果需要非常高的响应速度,建议采用乐观锁方案,成功就执行,不成功就失败,不需要等待其他并发去释放锁。乐观锁并未真正加锁,效率高。一旦锁的粒度掌握不好,更新失败的概率就会比较高,容易发生业务失败。
2️⃣冲突频率:如果冲突频率非常高,建议采用悲观锁,保证成功率。冲突频率大,选择乐观锁会需要多次重试才能成功,代价比较大。
3️⃣重试代价:如果重试代价大,建议采用悲观锁。悲观锁依赖数据库锁,效率低。更新失败的概率比较低。
4️⃣乐观锁如果有人在你之前更新了,你的更新应当是被拒绝的,可以让用户从新操作。悲观锁则会等待前一个更新完成。这也是区别。
作者:mysql_______1
链接:https://www.jianshu.com/p/d2ac26ca6525
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
@ControllerAdvice
public class ExceptionControllerAdvice {
private Logger logger = LoggerFactory.getLogger(getClass());
private WebResponseExceptionTranslator webResponseExceptionTranslator = new WebResponseExceptionTranslator();
@ExceptionHandler(Exception.class)
public ResponseEntity responseEntity(Exception e) {
logger.warn("[responseEntity], Handling error: " + e.getClass().getSimpleName() + ", " + e.getMessage());
return webResponseExceptionTranslator.translate(e);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Error> bindException(MethodArgumentNotValidException e) {
BindingResult bindingResult = e.getBindingResult();
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
StringBuilder fieldNamesBuilder = new StringBuilder();
for (FieldError fieldError : fieldErrors) {
fieldNamesBuilder.append("'");
fieldNamesBuilder.append(fieldError.getField());
fieldNamesBuilder.append("', ");
}
// Convert to string and then remove trailing space.
String fieldNames = fieldNamesBuilder.toString().trim();
if (fieldNames.length() > 0) {
// Remove the trailing comma.
fieldNames = fieldNames.substring(0, fieldNames.length() - 1);
}
String message = "Invalid input value for " + fieldNames;
Error error = new Error(
"Method_Argument_Not_Valid_" + UUID.randomUUID(),
"Method_Argument_Not_Valid",
message);
logger.error("[bindException], MethodArgumentNotValidException={{}}", message);
return new ResponseEntity<>(
error,
HttpStatus.BAD_REQUEST);
}
@ExceptionHandler({ConstraintViolationException.class})
public ResponseEntity<Error> handleConstraintViolationException(final ConstraintViolationException ex) {
Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
StringBuilder fieldNamesBuilder = new StringBuilder();
for (Iterator<ConstraintViolation<?>> iterator = constraintViolations.iterator(); iterator.hasNext(); ) {
ConstraintViolation<?> next = iterator.next();
fieldNamesBuilder.append("'");
fieldNamesBuilder.append(next.getPropertyPath());
fieldNamesBuilder.append("', ");
}
// Convert to string and then remove trailing space.
String fieldNames = fieldNamesBuilder.toString().trim();
if (fieldNames.length() > 0) {
// Remove the trailing comma.
fieldNames = fieldNames.substring(0, fieldNames.length() - 1);
}
String message = "Invalid input value for " + fieldNames;
Error error = new Error(
"CONSTRAINT_VIOLATION" + UUID.randomUUID(),
" CONSTRAINT_VIOLATION",
message);
logger.error("[handleConstraintViolationException], ConstraintViolationException={{}}", message);
return new ResponseEntity<>(
error,
HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(NotRecordOwnerException.class)
public ResponseEntity<Error> bindException(NotRecordOwnerException e) {
Error error = new Error(
e.getErrorCode() + "_" + UUID.randomUUID(),
e.getErrorCode(),
"Data not found");
logger.error("[bindException], NotRecordOwnerException={{}}", e.getErrorCode());
return new ResponseEntity<>(
error,
HttpStatus.NOT_FOUND);
}
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<Error> bindException(ResourceNotFoundException e) {
Error error = new Error(
e.getErrorCode() + "_" + UUID.randomUUID(),
e.getErrorCode(),
"Data not found");
logger.error("[bindException], ResourceNotFoundException={{}}", e.getErrorCode());
return new ResponseEntity<>(
error,
HttpStatus.NOT_FOUND);
}
@ExceptionHandler({MethodArgumentTypeMismatchException.class})
public ResponseEntity<Error> handleMethodArgumentTypeMismatchException(final MethodArgumentTypeMismatchException ex) {
String message = "'" + ex.getName() + "' must be of type [" + ex.getRequiredType().getName() + "]";
Error error = new Error(
"METHOD_ARGUMENT_TYPE_MISMATCH_" + UUID.randomUUID(),
"METHOD_ARGUMENT_TYPE_MISMATCH",
message);
logger.error("[handleMethodArgumentTypeMismatchException], MethodArgumentTypeMismatchException={{}}",message);
return new ResponseEntity<>(
error,
HttpStatus.BAD_REQUEST);
}
@ExceptionHandler({AccessDeniedException.class})
public ResponseEntity<Error> handleAccessDeniedException(final AccessDeniedException ex) {
String message = ex.getMessage();
Error error = new Error(
"ACCESS_DENIED_EXCEPTION_" + UUID.randomUUID(),
"ACCESS_DENIED_EXCEPTION",
message);
logger.error("[handleAccessDeniedException], AccessDeniedException={{}}",message);
return new ResponseEntity<>(
error,
HttpStatus.UNAUTHORIZED);
}
public class Error {
private String id;
private String error;
private String error_description;
public Error(String id, String error, String error_description) {
this.id = id;
this.error = error;
this.error_description = error_description;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public String getError_description() {
return error_description;
}
public void setError_description(String error_description) {
this.error_description = error_description;
}
}
}