自己在写项目的时候,发现一旦涉及模糊查询,controller接到的参数,要么在sql中用concat函数拼接,要么在程序中自己手动拼接(“${}”这种方式不算,有sql注入风险),每有一个 String 类型的参数,都要拼一遍,就很麻烦, 索性就写了个小工具类
package tuo.li.wxb.util.stringUtil;
import org.springframework.stereotype.Component;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* @author aLiang
* @date 2019-12-29 10:33
* @description 模糊查询 “%”的拼接 工具类
* @point
*/
@Component
public class StringFormat<T> {
/**
* // javaBean 所在包路径
*/
private static String javaBeanPackage = "tuo.li.wxb.bean";
public T stringFormat(T t) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
// 获取需要替换字符串对象的字节码对象
Class tClass = t.getClass();
// 遍历该对象的暴力反射获取的所有方法
for (Method item : tClass.getDeclaredMethods()) {
// 强制获取
item.setAccessible(true);
// 如果是get方法的同时,返回值类型又是javaBean,那么递归调用该方法
if (item.getName().contains("get") && item.getReturnType().getName().contains(javaBeanPackage)) {
// 前端传过来的json可能有空对象的情况,(不在模糊查询的表单中)
if (item.invoke(t) != null) {
stringFormat((T) item.invoke(t));
}
}
// 如果该方法是get方法,同时返回值为String
if (item.getName().contains("get") && item.getReturnType().getName().equals("java.lang.String")) {
// 执行该方法,get传入对象对应字段的值
String temp = (String) item.invoke(t);
if (temp != null && !"".equals(temp)) {
// 获取get方法对应的set方法名称
String s = item.getName().replaceFirst("g", "s");
// 暴力反射获取set方法
Method declaredMethod = tClass.getDeclaredMethod(s, String.class);
// 强制获取
declaredMethod.setAccessible(true);
// 设置传入set方法的参数,即需要拼接的字符串
String parameter = "%" + temp + "%";
// 执行set方法,替换掉对象中字段数据类型为String的字段对应的数据
declaredMethod.invoke(t, parameter);
}
}
}
return t;
}
}
如果我们有一个 User 类 里面有个 name 和 username 字段, 前端有个模糊查询是会传到 controller 一个User 对象,我只需要 user = new StringFormat().stringFormat(user); 就可以拿到%拼接后的user数据对象,直接传给mapper层,mybatis调用就可以。
我把它放在了 ioc 里, 调用的时候直接就 user = StringFormat注入IOC时的引用名称.stringFormat(user);
这玩意儿自己练习用用就好,性能和bug也没检测, bug的话后续项目写下去可能会慢慢查出并改正,进而优化,但是性能绝对高不了,一堆反射,纯粹娱乐,方便自己,说白了就是懒的