使用Java代码获取mapper.xml中的sql语句

使用场景

项目中我们常常在java文件中使用Jdbc执行SQL的方式来进行某些业务场景的批量更新操作;由于业务场景的复杂性,大量的SQL写在java文件中,偶尔也会进行参数的拼接操作;这就导致整体的SQL语句格式错乱、维护起来相对困难。

面对以上的现状,本篇文章将会实现另外一种SQL的管理方式,将执行SQL放在MybatisMapper.xml文件中,借助工具类将SQL解析出来,最终使用jdbc方式执行SQL,以致实现最终的业务场景。

代码实现

创建工具类SqlHelper.java用于解析获取mapper.xml中对应的SQL语句,并进行参数的绑定操作。

SqlHelper.java

import cn.hutool.core.collection.CollUtil;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeHandlerRegistry;

import java.text.DateFormat;
import java.util.*;
import java.util.regex.Matcher;


public class SqlHelper {

 /**
  * 获取Mapper.xml文件中的SQL
  *
  * @param sqlSessionFactory
  * @param namespace
  * @param params
  * @return
  */

 public static String getMapperSQL(SqlSessionFactory sqlSessionFactory, String namespace, Object params) {
  Configuration configuration = sqlSessionFactory.getConfiguration();
  MappedStatement mappedStatement = configuration.getMappedStatement(namespace);
  TypeHandlerRegistry typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();
  BoundSql boundSql = mappedStatement.getBoundSql(params);
  Object parameterObject = boundSql.getParameterObject();
  List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
  StringBuilder sqlStringBuilder = new StringBuilder(boundSql.getSql().replaceAll("n"""));
  String sql = sqlStringBuilder.toString();
  if (CollUtil.isNotEmpty(parameterMappings)) {
   if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
    sql = sql.replaceFirst("\?", Matcher.quoteReplacement(getParameterValue(parameterObject)));
   } else {
    MetaObject metaObject = configuration.newMetaObject(parameterObject);
    for (ParameterMapping parameterMapping : parameterMappings) {
     String propertyName = parameterMapping.getProperty();
     if (metaObject.hasGetter(propertyName)) {
      Object obj = metaObject.getValue(propertyName);
      sql = sql.replaceFirst("\?", Matcher.quoteReplacement(getParameterValue(obj)));
     } else if (boundSql.hasAdditionalParameter(propertyName)) {
      Object obj = boundSql.getAdditionalParameter(propertyName);  // 该分支是动态sql
      sql = sql.replaceFirst("\?", Matcher.quoteReplacement(getParameterValue(obj)));
     } else {
      sql = sql.replaceFirst("\?""缺失");
     }
    }
   }
   return sql;
  }
  return "";
 }

 private static String getParameterValue(Object obj) {
  String value = null;
  if (obj instanceof String) {
   value = "'" + obj.toString() + "'";
  } else if (obj instanceof Date) {
   DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
   value = "'" + formatter.format(new Date()) + "'";
  } else {
   if (Objects.nonNull(obj)) {
    value = obj.toString();
   } else {
    value = "";
   }
  }
  return value;
 }
}

mapper接口:SqlBaseMapper.java

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface SqlBaseMapper {

 List<String> selectIdList(@Param("tempName") String tempName, @Param("tempDate") String tempDate);
}

SqlBaseMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxkfz.simplememory.mapper.SqlBaseMapper">
    <select id="selectIdList" resultType="java.lang.String" parameterType="java.lang.String">
        select tmp_id from temp where 1=1
          <if test="tempName != null and tempName != ''">
              and temp_name = #{tempName,jdbcType=VARCHAR}
          </if>
         <if test="tempDate != null and tempDate != ''">
             and temp_date = #{tempDate,jdbcType=VARCHAR}
         </if>
    </select>
</mapper>

演示示例

新建测试Controller

@Autowired
private SqlSessionFactory sqlSessionFactory;

@Autowired
private JdbcTemplate jdbcTemplate;

@GetMapping("/getIdList")
public void getIdList(){
   Map map = new HashMap<String,String>();
   map.put("tempName","xxkfz");
   map.put("tempDate","20210823");
   String sql = SqlHelper.getMapperSQL(sqlSessionFactory, "com.xxkfz.simplememory.mapper.SqlBaseMapper.selectIdList", map);
   System.out.println("执行SQL = " + sql);
   List<String> stringList = jdbcTemplate.queryForList(sql, String.class);
   System.out.println("stringList = " + stringList);
}

启动项目,在浏览器地址栏访问:http://127.0.0.1:9998/test/getIdList

查看控制台SQL的输出以及执行结果情况:

使用Java代码获取mapper.xml中的sql语句


使用Java代码获取mapper.xml中的sql语句

原文始发于微信公众号(SimpleMemory):使用Java代码获取mapper.xml中的sql语句

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/137762.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!