自定义注解实现数据库手机号码不重复校验

视频讲解详见 https://www.bilibili.com/video/BV1tq4y1a7B6/

第一步 创建校验手机号格式的正则工具类

public class PhoneUtils {

    private static final String REGEX_MOBILE ="((\\+86|0086)?\\s*)((134[0-8]\\d{7})|(((13([0-3]|[5-9]))|(14[5-9])|15([0-3]|[5-9])|(16(2|[5-7]))|17([0-3]|[5-8])|18[0-9]|19([0-9]))\\d{8})|(14(0|1|4)0\\d{7})|(1740([0-5]|[6-9]|[10-12])\\d{7}))";

    /**
     * 正则:固定电话号码,可带区号,然后至少6,8位数字
     */
    private static final String REGEX_TEL = "^(\\d{3,4}-)?\\d{6,8}$";
    private static final Pattern PATTERN_REGEX_TEL = Pattern.compile(REGEX_TEL);

    /**
     * 判断是否是手机号
     * @param tel 手机号
     * @return boolean true:是  false:否
     */
    public static boolean isMobile(String tel) {
        if (StringUtils.isEmpty(tel)){
            return false;
        }
        return Pattern.matches(REGEX_MOBILE, tel);
    }

    /**
     * 验证固定电话号码
     */
    public static boolean isTel( String str) {
        return isMatch(PATTERN_REGEX_TEL, str);
    }

    public static boolean isMatch(Pattern pattern, String str) {
        return StringUtils.isNotEmpty(str) && pattern.matcher(str).matches();
    }

    public static void main(String[] args) {
        System.out.println(isTel("2887438"));
    }

}

第二步 编写两个需要的注解

@Target(ElementType.METHOD)//作用于方法
@Retention(RetentionPolicy.RUNTIME)//运行时生效
public @interface CheckPhone {

}
@Target(ElementType.FIELD) //作用于字段
@Retention(RetentionPolicy.RUNTIME) //运行时有效
public @interface PhoneFlag  {

}

第三步 编写需要的切面类

@Aspect
@Component
public class CheckPhoneAspect {
    @Resource
    UserInfoService userInfoService;
    /**
     * @annotation 声明以注解的方式来定义切点,里面写自己定义的注解的路径即可
     *
     */
    @Before("@annotation(com.asiainfo.idsp.iptv.common.myAnnotation.CheckPhone)")
    public void before(JoinPoint point) throws Throwable {
        // 获取所有参数
        Object[] args = point.getArgs();
        for (Object arg : args) {
            if (null == arg){
                return;
            }
            Class c = arg.getClass();
            // 获取class对象内的字段
            Field[] fields = c.getDeclaredFields();
            if (null != fields){
                for (Field field : fields) {
                    String methodName = "get";
                    // 字段名称
                    String name = field.getName();
                    // 组装获取字段方法名
                    String first = name.substring(0,1).toUpperCase();
                    if (name.length() > 1){
                        String second = name.substring(1);
                        methodName = methodName.concat(first).concat(second);
                    }else {
                        methodName = methodName.concat(first);
                    }
                    // 获取注解,存在PhoneFlag注解就进行校验
                    PhoneFlag annotation = field.getAnnotation(PhoneFlag.class);
                    if (null != annotation){
                        // 校验电话号码格式是否正确
                        // invoke()反射获取字段值
                        String phone = (String) c.getMethod(methodName).invoke(arg);
                        if (StringUtils.isNotBlank(phone)){
                            if (!PhoneUtils.isMobile(phone)){
                                throw new BusinessException("电话格式不正确");
                            }
                            // 查询数据库,校验手机号码是否存在
                            // 先判断id是否为空 如果不为空就是修改操作,修改允许修改的手机号码与原来的手机号码相同
                            Object id = c.getMethod("getId").invoke(arg);
                            final QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
                            wrapper.eq("phone", phone);
                            if (null == id){
                                // 如果没有id就是新增操作
                                final List<UserInfo> list = userInfoService.list(wrapper);
                                if (list.size() > 0) {
                                    throw new BusinessException("手机号码已存在");
                                }
                            }else {
                            // 如果id不为空,就是修改操作,校验修改的手机号码与原来的手机号码是否相同
                                // 排除自己
                                wrapper.ne("id", id);
                                final List<UserInfo> list = userInfoService.list(wrapper);
                                if (list.size() > 0){
                                    throw new BusinessException("手机号码已存在");
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

第四步 在实体类的字段上和需要的校验的方法上加上两个注解
image

image

posted @ 2022-04-05 22:18  小猫爱哭鬼  阅读(286)  评论(0编辑  收藏  举报