package com.artfess.base.valid; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import javax.xml.bind.ValidationException; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Component @Slf4j public class FieldRepeatUtils { /** * 实体类中id字段 */ private String idColumnName; /** * 实体类中id的值 */ private Object idColumnValue; // private String DEL = ""; /** * @param fields 验证的字段数组 * @param message 如果不满足返回的消息 * @param o 实体类 * @return */ public boolean fieldRepeat(String[] fields, String message, Object o) throws ValidationException, IllegalAccessException { try { // 没有校验的值返回true if (fields != null && fields.length == 0) { return true; } checkUpdateOrSave(o); checkRepeat(fields, o, message); return true; } catch (ValidationException ed) { throw new ValidationException(message); } catch (IllegalAccessException e) { throw new IllegalAccessException(e.getMessage()); } } /** * 通过传入的实体类中 @TableId 注解的值是否为空,来判断是更新还是保存 * 将值id值和id列名赋值 * id的值不为空 是更新 否则是插入 * * @param o 被注解修饰过的实体类 * @return */ public void checkUpdateOrSave(Object o) throws IllegalAccessException { Field[] fields = getAllFields(o.getClass()); for (Field f : fields) { // 设置私有属性可读 f.setAccessible(true); if (f.isAnnotationPresent(TableId.class)) { TableId tableId = f.getAnnotation(TableId.class); idColumnName = tableId.value(); idColumnValue = f.get(o); } // if (f.getName().equals("isDele")) { // DEL = f.getName(); // } } } /** * 获取本类及其父类的属性的方法 * * @param clazz 当前类对象 * @return 字段数组 */ private static Field[] getAllFields(Class clazz) { List fieldList = new ArrayList<>(); while (clazz != null) { fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()))); clazz = clazz.getSuperclass(); } Field[] fields = new Field[fieldList.size()]; return fieldList.toArray(fields); } /** * 通过传入的字段值获取数据是否重复 * * @param fields * @param o * @param message * @return */ public void checkRepeat(String[] fields, Object o, String message) throws ValidationException, IllegalAccessException { Model model = (Model) o; //Mybatis-plus 3.0以下用EntityWrapper QueryWrapper qw = new QueryWrapper<>(); Map queryMap = getColumns(fields, o); if (CollectionUtils.isEmpty(queryMap)) { log.info("未配置验证重复的字段"); return; } qw.and((obj) -> { int fildNum = 0; for (Map.Entry entry : queryMap.entrySet()) { fildNum++; if (1 == fildNum) { obj.eq(entry.getKey(), entry.getValue()); } else { obj.or().eq(entry.getKey(), entry.getValue()); } } }); // if (StringUtils.isNotBlank(DEL)) { // qw.eq("is_dele_", DelStatusEnum.N.getType()); // } if (idColumnValue != null) { //更新的话,那条件就要排除自身 qw.ne(idColumnName, idColumnValue); } List list = model.selectList(qw); if (list != null && list.size() > 0) { throw new ValidationException(message); } } /** * 多条件判断唯一性,将我们的属性和值组装在map中,方便后续拼接条件 * * @param fields * @param o * @return */ public Map getColumns(String[] fields, Object o) throws IllegalAccessException { Field[] fieldList = getAllFields(o.getClass()); Map map = new ConcurrentHashMap<>(); for (Field f : fieldList) { // ② 设置对象中成员 属性private为可读 f.setAccessible(true); // 判断字段是否包含在数组中,如果存在,则将它对应的列字段放入map中 if (ArrayUtils.contains(fields, f.getName())) { getMapData(map, f, o); } } return map; } /** * 得到查询条件 * * @param map 列字段 * @param f 字段 * @param o 传入的对象 */ private void getMapData(Map map, Field f, Object o) throws IllegalAccessException { try { if (f.isAnnotationPresent(TableField.class)) { TableField tableField = f.getAnnotation(TableField.class); Object val = f.get(o); if(null != val) { map.put(tableField.value(), val); } } } catch (IllegalAccessException i) { throw new IllegalAccessException("获取字段的值错误"); } } }