解析并替换sql中的#{var}
2020-09-09 本文已影响0人
YAOPRINCESS
package com.kang.mybatis.proxy;
import org.apache.ibatis.annotations.Select;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author klr
* @create 2020-09-09-20:21
*/
interface UserMapper{
@Select("select * from user where id=#{id} and name=#{name}")
List<User> selectUserList(int id,String name);
}
public class ProxyExample {
public static void main(String[] args) {
//动态代理UserMapper接口
UserMapper userMapper = (UserMapper) Proxy.newProxyInstance(ProxyExample.class.getClassLoader(), new Class[]{UserMapper.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] objects) throws Throwable {
//打印代理类调用的方法名
System.out.println(method.getName());
//打印参数
System.out.println(Arrays.toString(objects));
Map<String, Object> nameArgMap = buildMethodNameArgMap(method, objects);
Select annotation = method.getAnnotation(Select.class);
if (annotation != null) {
//如果注解存在,打印里面的信息
System.out.println(Arrays.asList(annotation.value()));
String sql = parseSql(annotation.value()[0], nameArgMap);
System.out.println(sql);
}
return null;
}
});
//通过代理类调用方法
userMapper.selectUserList(1,"kang");
}
//解析注解里的sql,往#{}中填充
public static String parseSql(String sql, Map < String, Object > nameArgMap) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < sql.length(); i++) {
char c = sql.charAt(i);
if (c == '#') {
int nextIndex = i + 1;
if (sql.charAt(nextIndex) == '{') {
StringBuilder argSB = new StringBuilder();
//替换#{}中的东西
i = parsePart(argSB, sql, nextIndex);//此时的charAt(i)=},但循环后会i++
//argSB中的内容就是要替换的参数名
Object value = nameArgMap.get(argSB.toString());
stringBuilder.append(value);
continue;
}
}
stringBuilder.append(c);
}
return stringBuilder.toString();
}
private static int parsePart(StringBuilder argSB, String sql, int nextIndex) {
nextIndex++;
for (; nextIndex < sql.length(); nextIndex++) {
if (sql.charAt(nextIndex) != '}') {
argSB.append(sql.charAt(nextIndex));
continue;
}
return nextIndex;
}
return 0;
}
public static Map<String,Object> buildMethodNameArgMap( Method method, Object[] objects) {
Map<String, Object> nameArgMap = new HashMap<>();
//通过方法得到参数名
Parameter[] parameters = method.getParameters();
int i[]={0};
Arrays.asList(parameters).forEach(parameter -> {
String name = parameter.getName();
nameArgMap.put(name, objects[i[0]]);
System.out.println(name);
i[0]++;
});
return nameArgMap;
}
}