getBoundSql()传入List类型参数报错

前台想在查询数据的同时或之前获取查询数据的sql,于是想用getBoundSql来获取拼完参数的sql,但是传入参数类型为List的时候,总是报错,String和int类型可以正常返回。
这是代码

            List<String> list = new ArrayList<>();
            list.add("1234");
            list.add("5678567");
            list.add("12564534");
            String sql = sqlSessionFactory.getConfiguration().getMappedStatement("com.mapper.ConfigDOMapper.getTest").getBoundSql(list).getSql();
            System.out.println(sql);

报错信息

java.lang.UnsupportedOperationException: null

    at org.apache.ibatis.reflection.wrapper.CollectionWrapper.get(CollectionWrapper.java:38)

    at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:122)

    at org.apache.ibatis.scripting.xmltags.DynamicContext$ContextMap.get(DynamicContext.java:102)

    at org.apache.ibatis.scripting.xmltags.DynamicContext$ContextAccessor.getProperty(DynamicContext.java:113)

    at org.apache.ibatis.ognl.OgnlRuntime.getProperty(OgnlRuntime.java:3338)

    at org.apache.ibatis.ognl.ASTProperty.getValueBody(ASTProperty.java:121)

    at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)

    at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)

    at org.apache.ibatis.ognl.ASTNotEq.getValueBody(ASTNotEq.java:50)

    at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)

    at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)

    at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:560)

    at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:524)

    at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:46)

    at org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.evaluateBoolean(ExpressionEvaluator.java:32)

思路是对的,但是参数有问题,MappedStatement#getBoundSql 方法的参数是 mybatis 内部对 mapper 接口方法参数封装后的。正确获取 SQL 的示例代码如下。

@Component
public class TestCommandLiner implements CommandLineRunner {

    @Autowired
    private SqlSession sqlSession;

    @Override
    public void run(String... args) throws Exception {
        
        Configuration configuration = sqlSession.getConfiguration();
        
        // 先查找 Mapper 接口方法
        Method method = ReflectionUtils.findMethod(YysUserDao.class, "getByUserId", Integer.class);
        // 然后创建 mybatis 内部的方法签名对象
        MapperMethod.MethodSignature methodSignature = new MapperMethod.MethodSignature(configuration, YysUserDao.class, method);
        // 然后将正常调用的方法参数列表转换为 mybatis 内部的参数值
        Object arg = methodSignature.convertArgsToSqlCommandParam(Collections.singleton(1L).toArray());
        
        // 然后再获取执行的 SQL
        String sql = configuration.getMappedStatement(YysUserDao.class.getName() + "." + method.getName()).getBoundSql(arg).getSql();
        System.out.println(sql);
    }
}

如果有帮助,麻烦题主动动小手给个采纳。

img


写插件去拦截ParameterHandler,执行完setParameters你就能获取到sql了,其实这都不是问题,像mysql,简单的字符串或者数字,人家PreparedStatement能直接拿到最终的sql,如果你确定没有什么花里胡哨的参数类型,像clob,date这种,基本都够了,oracle的话,PreparedStatement就不行了

你倒是上代码啊