Mybatis获取多参数完整执行SQL

本文介绍了如何利用Mybatis获取查询接口的有序参数列表,并结合该功能解决实际场景中的报表查询及Excel导出问题。通过分析BoundSql获取SQL和参数,然后转换SQL中的占位符为实际值,最终生成可用于导出Excel的完整SQL。示例代码展示了多参数和单个参数的封装方法。
摘要由CSDN通过智能技术生成

上一篇介绍了Mybatis如何获取查询接口的有序参数列表,这一篇会结合上一篇的内容解决实际问题,最近遇到了查询报表并将查询内容导出Excel文件的实际场景,需要获取到查询的完整SQL再通过导出工具导出Excel。

主要代码如下

//methodPath为执行方法的全限定名
//map为methodPath的参数列表,在查询接口多参数和单个参数的情况下会有一点差别
public String InSql(String methodPath, Map<String, Object> map) {
        BoundSql boundSql = sqlSessionFactory.getConfiguration().getMappedStatement(methodPath).getBoundSql(map);
        String sql = boundSql.getSql();
        //根据SQL获取参数列表
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();

        //定义集合存储映射参数
        List<Object> paramList = new ArrayList<>();

        //foreach标签标记 只进入if判断一次即把对应参数全部存入Set
        //由于foreach标签生成的元素的以"__frch_"开头的格式
        Set<String> flagSet = new HashSet<>();
        for (ParameterMapping pm : parameterMappings) {
            //判断是否为输入参数
            if (pm.getMode() != ParameterMode.OUT) {
                //获取Dao接口参数名
                String paramName = pm.getProperty();

                if (paramName.contains("__frch_")) {
                    int firstIndex = paramName.lastIndexOf("_", paramName.lastIndexOf("_") - 1);
                    int lastIndex = paramName.lastIndexOf("_");
                    //获取参数名称,这里获取到的参数名为XML文件中foreach标签中的item元素的值,这个值需要与第二层参数列表map设置的key保持一致才能获取到value。
                    paramName = paramName.substring(firstIndex + 1, lastIndex);
                    if (!flagSet.contains(paramName)) {
                        Map param = (Map) map.get("param");
                        String paramValues = (String) param.get(paramName);
                        String[] strings = paramValues.split(",");
                        for (String value : strings) {
                            paramList.add(value);
                        }
                        flagSet.add(paramName);
                    }
                } else if (paramName.contains("param.")) {
                    paramName = paramName.replace("param.", "");
                    Map param = (Map) map.get("param");
                    Object paramValue = param.get(paramName);
                    paramList.add(paramValue);
                } else {
                    Object o = map.get(paramName);
                    paramList.add(o);
                }
            }
        }
        while (sql.indexOf("?") != -1 && paramList != null && paramList.size() > 0 && paramList.get(0) != null) {
            Object paramValue = paramList.get(0);
            if (paramValue != null) {
                String value = "\'" + paramValue.toString() + "\'";
                /*if (paramValue instanceof String){
                    value = "\'"+paramValue.toString()+"\'";
                }else if(paramValue instanceof Date || paramValue instanceof Timestamp){
                    value = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", (Date) paramValue);
                    value = "str_to_date('" + value + "','%Y-%m-%d %T')";
                }*/
                sql = sql.replaceFirst("\\?", value);
                paramList.remove(0);
            }
        }
        return sql;
    }

多个参数封装

//查询接口
List<Map<String,Object>> getCarBackupData(@Param("currentUserId") int currentUserId, @Param("param") YsSearchCarParam param);

假设需要获取上面多参数接口的完整SQL,封装map参数:
Map<String,Object> param = new hashmap();
//在查询接口获取到currentUserId的值
param.put("currentUserId",param.getCurrentUserId);
//封装第二个map,key为XML文件中判断条件的字符串,value为判断条件的值
Map<String,Obejct> map = new hashMap();
map.put("yy1","yy1");
//在XML文件解析时,xx2被foreach标签解析
//生成类似于__frch_xx0:xx1,__frch_xx1:xx2,__frch__xx2:xx3的三个额外参数
map.put("xx2","xx1,xx2,xx3");
//再由最外层的map将第二参数的值封装起来,这里的键是@param设置的值
param.put("param",map);

单个参数封装

//查询接口
List<YsPeopleResult> selectPeopleLibResultList(YsSearchPeopleParam param);

//直接将SQL中需要的过滤参数放入map即可,map的键为XML文件中对应判断条件字符串
Map<String, Object> map = new HashMap<>();
map.put("searchNum", pici);

如果有bug或问题,欢迎各位在评论区交流。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值