创建接收lambda表达式参数来查询数据库中指定字段

131 阅读1分钟

背景

既知平正,务追险绝

在做项目的时候,在做数据库交互查询指定字段的时候,总是容易遇到查询的指定列名有被命名为常量,要么就是直接来个字符串,这种时候既不容易维护,又容易写错,于是想自己封装一下db交互层,通过传入指定类的lambda表达式,来规范和避免错误,于是参照了MybatisPlus中的QueryWapper实现原理,写了一个简单的工具类

tips:笔者现在项目使用的是Mongodb

实现

先创建一个函数式接口

/**
 * <p>函数式接口</p>
 *
 * @author Arvin 
 * @date 2023/3/8 15:45
 * @since 1.0.0
 */
@FunctionalInterface
public interface HapiFunction<T, R> extends Function<T, R>, Serializable {
}

定义解析类

/**
 * <p>参数工具类</p>
 *
 * @author Arvin 
 * @date 2023/3/8 15:49
 * @since 1.0.0
 */
public final class ParamUtil {

    private ParamUtil() {
    }

    public static String parsePropertyName(HapiFunction<?, ?> func) throws Exception {
        var method = func.getClass().getDeclaredMethod("writeReplace");
        method.setAccessible(Boolean.TRUE);
        var invoke = (SerializedLambda) method.invoke(func);
        var name = invoke.getImplMethodName();

        if (name.startsWith("is")) {
            name = name.substring(2);
        } else {
            if (!name.startsWith("get") && !name.startsWith("set")) {
                throw new BusinessException("");
            }

            name = name.substring(3);
        }

        if (name.length() == 1 || name.length() > 1 && !Character.isUpperCase(name.charAt(1))) {
            name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
        }

        return name;
    }
}

定义字符串工具类

/**
 * <p>字符串工具类</p>
 *
 * @author Arvin 
 * @date 2023/3/8 15:52
 * @since 1.0.0
 */
public class StringUtil {
    public static String camelToUnderline(String param) {
        if (StringUtil.isBlank(param)) {
            return StringPool.EMPTY;
        }
        int len = param.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c) && i > 0) {
                sb.append(StringPool.UNDERSCORE);
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }
}

测试

public static void main(String[] args) throws Exception {
    var propertyName = ParamUtil.parsePropertyName(User::getUserName);
    var dbColumName StringUtil.camelToUnderline(propertyName);
    System.out.println(dbColumName);
}