在一些依赖包中,常见有一些链式调用,这样使得在私有属性给值时更准确,代码更清晰,我试着剥离出来,拖去依赖关系,使其成为一个工具类。
package com.xinao.monitor.utils; import com.xinao.common.core.utils.StringUtils; import org.apache.commons.lang.text.StrSubstitutor; import org.springframework.util.ObjectUtils; import java.io.Serializable; import java.lang.invoke.SerializedLambda; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import java.util.function.Function; /** * 自定义条件构造器 */ public class IotUtils { private StringBuilder result; private Object then; private Class target; public IotUtils(){} @FunctionalInterface public interface Getter<Y,R> extends Function<Y,R>,Serializable { } public static IotUtils create() { IotUtils create = new IotUtils(); create.result = new StringBuilder(); return create; } public IotUtils set(Object o,Class r){ this.then = o; this.target = r; return this; } public IotUtils set(Class r){ this.target = r; this.then = new Object(); return this; } public <Y,Q> IotUtils and(Getter<Y,Q> getter, String condition){ if(this.then == null){ throw new RuntimeException("未注入对象"); } return and(getter, condition, this.then); } public <Y,Q> IotUtils and(Getter<Y,Q> getter, String condition, Object then) { SerializedLambda lambda = getSerializedLambda(getter); String methodName = lambda.getImplMethodName(); // get属性值 Object invoke = null; try { Method method = target.getDeclaredMethod(methodName); method.setAccessible(true); invoke = method.invoke(then); if(ObjectUtils.isEmpty(invoke)){ return this; } invoke = String.valueOf(invoke); } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); } String field = methodName.replace("get", ""); char[] cas = field.toCharArray(); cas[0] += 32; field = new String(cas); if(condition.equalsIgnoreCase("like")){ and(" and " + field + " " + condition + " %" + invoke + "%"); return this; } and(" and " + field + " " + condition + " " + invoke); return this; } public <Y,Q> IotUtils andAuto(Getter<Y,Q> getter, String condition, Object then) { if(StringUtils.isEmpty(String.valueOf(then))){ return this; } SerializedLambda lambda = getSerializedLambda(getter); String methodName = lambda.getImplMethodName(); String field = methodName.replace("get", ""); char[] cas = field.toCharArray(); cas[0] += 32; field = new String(cas); if(condition.equalsIgnoreCase("like")){ and(" and " + field + " " + condition + " %" + then + "%"); } and(" and " + field + " " + condition + " " + then); return this; } public IotUtils and(String condition) { result.append(" " + condition); return this; } public IotUtils and(boolean can, String condition) { if(can){ return and(condition); } return this; } // ${}替换 public IotUtils custom(String condition, Map val) { StrSubstitutor base = new StrSubstitutor(val); String replace = base.replace(condition); result.append(condition); return this; } public String end(){ try { String s = this.result.toString(); String where = s.replaceFirst("and", "where"); return where; }finally { this.result = null; } } private SerializedLambda getSerializedLambda(Serializable fn){ SerializedLambda lambda = null; Method method = null; try { method = fn.getClass().getDeclaredMethod("writeReplace"); method.setAccessible(Boolean.TRUE); lambda = (SerializedLambda) method.invoke(fn); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { throw new RuntimeException(e); } return lambda; } }