1-新增一个注解
@Documented //用来文档的
@Target(ElementType.TYPE) //作用目标:Class, interface (including annotation type), or enum declaration
@Retention(RetentionPolicy.RUNTIME) //生命周期:运行时
@Constraint(validatedBy = UniqueCheckValidator.class) //限定自定义注解使用的方法
public @interface UniqueCheck {
//需要校验的字段
String filedName();
//默认提示的文本
String message() default "字段已经存在";
//分组校验
Class<?>[] groups() default {};
//这个不知道干嘛用的
Class<? extends Payload>[] payload() default {};
}
2-定义处理校验逻辑的类
public class UniqueCheckValidator implements ConstraintValidator<UniqueCheck, Object> {
private String fieldName;
private Long id;
@Override
public void initialize(UniqueCheck constraintAnnotation) {
this.fieldName = constraintAnnotation.filedName();
}
@Override
public boolean isValid(Object o, ConstraintValidatorContext context) {
String message = check(o);
if (ObjectUtil.isNull(message)){
return true;
}
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(message).addConstraintViolation();
return false;
}
@SneakyThrows
private String check(Object o){
//需要校验的字段
String[] split = fieldName.split(",");
Class<?> aClass = o.getClass();
String beanName = aClass.getSimpleName().toLowerCase() + "Mapper";
BaseMapper mapper = (BaseMapper) SpringUtils.getBean(beanName);
Map<String, Object> paramsMap = new LinkedHashMap<>();
Field id = aClass.getDeclaredField("id");
id.setAccessible(true);
Object idValue = id.get(o);
Optional.ofNullable(id).ifPresent( i ->{
this.id = (Long) idValue;
});
for (String checkField : split) {
Field field = aClass.getDeclaredField(checkField);
field.setAccessible(true);
Object fieldValue = field.get(o);
//获取注解上的值(数据库字段名称)
String dbValue = field.getAnnotation(TableField.class).value();
paramsMap.put(dbValue, fieldValue);
}
return spliceWrapper(paramsMap,mapper);
}
//拼接参数
private String spliceWrapper(Map<String, Object> paramsMap, BaseMapper mapper){
if (paramsMap.size() < 1){
//没有需要校验的字段
return null;
}
QueryWrapper<Object> wrapper = new QueryWrapper<>();
Optional.ofNullable(id).ifPresent(o -> {
wrapper.ne("id",id);
});
for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
wrapper.eq(entry.getKey(),entry.getValue());
Long count = mapper.selectCount(wrapper);
if (count > 0){
return entry.getValue() + "已经存在";
}
wrapper.clear();
Optional.ofNullable(id).ifPresent(o -> {
wrapper.ne("id",id);
});
}
return null;
}
}
3-将注解加在所需校验的实体类上
@Data
@TableName("t_user")
@UniqueCheck(filedName = "username")
public class User implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
private String nickname;
@TableField("username")
private String username;
}
如果需要校验多个字段,改成@UniqueCheck(filedName = “username,nickname”),使用逗号隔开来,需要注意的是,需要校验的字段需要加上@TableField注解,这样才能被校验类获取到数据库表字段的值。
4-在接口处加上@Validated注解
@RequestMapping("add")
public Result add(@RequestBody @Validated User user){
userService.add(user);
return Result.success("新增成功");
}
版权声明:本文为m0_59996263原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。