解析并替换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;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读