美文网首页
解析并替换sql中的#{var}

解析并替换sql中的#{var}

作者: YAOPRINCESS | 来源:发表于2020-09-09 22:27 被阅读0次
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;
    }
}

相关文章

  • 解析并替换sql中的#{var}

  • mybatis中$和#的区别

    --- $符 仅仅为一个纯碎的string替换,在动态 SQL 解析阶段将会进行变量替换。会发生sql注入...

  • mybatis $#符号的区别

    ${ }:字符串替换 { }:占位符 ${ }在动态 SQL 解析阶段会直接进行变量替换,而#{ }会被解析成占位...

  • shell中调用sqlplus执行SQL文件并替换SQL中参数值

    实现shell中调用sqlplus执行SQL文件并替换SQL中参数值第一种方法:#!/bin/bash.....(...

  • IntelliJ IDEA插件开发

    在论坛看到一款IDEA的SQL格式化插件,可以替换SQL中的"?"并格式化,可以直接复制SQL到查询器查询,非常方...

  • SQL 注入

    一.什么是SQL注入?SQL注入是一种将sql代码添加到输入参数中,传递到sql服务器解析并执行的一种攻击手法。 ...

  • WEB安全之SQL注入

    1) 如何理解sql注入 sql注入是一种将sql代码添加到输入参数中,传递到sql服务器解析并执行的一种攻击手法...

  • WEB安全之SQL注入

    什么是SQL注入? SQL注入是一种将SQL代码添加到输入参数中传递到SQL服务器解析并执行的一种攻击手法。案列解...

  • Presto查询执行过程

    Presto中SQL运行过程 Coordinator接到SQL后,通过SQL语法解析器把SQL语法解析变成一个抽象...

  • SQL语言③--SQL是如何执行的

    1、Oracle中SQL语句是怎么执行的,什么是硬解析,什么是软解析? Oracle中SQL语句的执行过程...

网友评论

      本文标题:解析并替换sql中的#{var}

      本文链接:https://www.haomeiwen.com/subject/adnyektx.html