使用场景
在项目中我们常常在java文件中使用Jdbc
执行SQL
的方式来进行某些业务场景的批量更新操作;由于业务场景的复杂性,大量的SQL
写在java
文件中,偶尔也会进行参数的拼接操作;这就导致整体的SQL
语句格式错乱、维护起来相对困难。
面对以上的现状,本篇文章将会实现另外一种SQL的管理方式,将执行SQL
放在Mybatis
的Mapper.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的输出以及执行结果情况:
原文始发于微信公众号(SimpleMemory):使用Java代码获取mapper.xml中的sql语句
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/137762.html