背景
既知平正,务追险绝
在做项目的时候,在做数据库交互查询指定字段的时候,总是容易遇到查询的指定列名有被命名为常量,要么就是直接来个字符串,这种时候既不容易维护,又容易写错,于是想自己封装一下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);
}