在我们平常开发的过程中,在添加或修改数据之前,为了避免有些数据重复问题,我们通常的做法都是先去数据库里面根据某个字段去数据库里面查询下这条数据是否存在。比如,会员注册的问题,一般会员的账号或者会员昵称都要求在数据表里面必须是唯一存在的。
但是作为一个企业级的web 项目,在实际开发过程中会有很多这种相似的业务,因为如果在每个接口里面都去做重复的事情无疑显得十分枯燥无味。因此,小编就在想能不能把这种类似的校验放在一个方法里面校验,这样我们就不用去写大量的重复业务代码了。
下面,小编就带大家看下我是如何使用自定义注解统一完成对数据重复性校验的。首先,我们创建一个自定义注解,如下图:
接着第二步,我们只需要自定义一个BaseService 继承mybatis plus中的ServiceImpl 类,然后重写saveOrUpdate方法。如下图:
@Override
public boolean saveOrUpdate(T entity) {
if (entity instanceof BaseEntity) {
Date now = new Date();
BaseEntity baseEntity = (BaseEntity) entity;
Map uniqueFieldMap = this.getUniqueField(entity);
BaseEntity result = null;
if (uniqueFieldMap.size() > 0) {
QueryWrapper queryWrapper = Wrappers.<T>query()
.select("id")
.allEq(uniqueFieldMap);
result = (BaseEntity) super.getOne(queryWrapper);
}
if (ObjectUtils.isNotEmpty(result)) {
ResultCode resultCode = new ResultCode(ResultCode.FAIL, "该数据已存在,请勿重复添加");
if (baseEntity.getId() != null) {
// 修改的数据id 不一样,存在相同数据
if (baseEntity.getId().intValue() != result.getId().intValue()) {
throw new BusinessException(resultCode);
}
} else {
throw new BusinessException(resultCode);
}
}
if (baseEntity.getId() == null) {
baseEntity.setCreateDate(now);
} else {
baseEntity.setUpdateDate(now);
}
}
return super.saveOrUpdate(entity);
}
/**
* 获取需要进行唯一约束校验的字段
* @return
*/
private Map<String, Object> getUniqueField(T entity) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(entity.getClass());
List<TableFieldInfo> fieldList = tableInfo.getFieldList();
Map uniqueField = new HashMap<>();
fieldList.forEach(tableFieldInfo -> {
Field field = tableFieldInfo.getField();
Unique unique = field.getAnnotation(Unique.class);
if (ObjectUtils.isNotEmpty(unique)) {
try {
field.setAccessible(true);
String column = ObjectUtils.isEmpty(unique.value()) ? field.getName() : unique.value();
uniqueField.put(column, field.get(entity));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
});
return uniqueField;
}
最后使用方式非常简单,我们只需要在对应的实体类的字段上加上唯一约束注解就可以了,如果有多个的话,系统在查询的时候会自动使用and 进行拼接查询。
如有不足之处,欢迎各位提提意见。