IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 使用MyBatis解析出XML结构中的sql语句 -> 正文阅读

[大数据]使用MyBatis解析出XML结构中的sql语句

作者:treeSkill

1. 功能背景

项目上有一个需求,需要根据用户手动编写的带xml的<if>、<choose>等标签的sql脚本,解析(转换)出可执行的sql脚本进行查询。

以下代码夹带了自定义表达式替换参数值的动能,如不需要删除代码即可。

MyBatis版本为3.5.3

2. 具体实现

2.1. 原始脚本

select
	id aId,
	user_name aUserName,
	org_id aOrgId,
	sex aSex,
	img aImg 
from
	a_cyf_data a
<where>
	<choose>
	<when test='aaa=="@aaa@"'>
		id=@aaa@
	</when>
	<otherwise>
		id=@bbb@
	</otherwise>
	</choose>
</where>

2.2. 引入的包

import java.util.*;

import com.alibaba.fastjson.JSONObject;

import org.apache.ibatis.builder.xml.XMLMapperEntityResolver;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.parsing.XPathParser;
import org.apache.ibatis.scripting.xmltags.XMLScriptBuilder;
import org.apache.ibatis.session.Configuration;

2.3. 功能代码

/**
 * 根据sql和参数,替换sql内带@符号的表达式和xml标签
 * 
 * @author: xxx
 * @date: 2022-05-10 11:09:21
 * @param params 参数
 * @return
 */
public static SqlCondition replaceSqlPermission(SqlParameter params) {
	String sql = params.getSql();
	List<ReportDbParam> paramList = params.getParamList();
	// 转换paramList为JSONObject
	JSONObject paramsJson = new JSONObject();
	if (null != paramList && !paramList.isEmpty()) {
		// 循环替换@表达式为参数值
		for (ReportDbParam param : paramList) {
			String key = param.getParamName();
			String permission = "@" + key + "@";
			String value = param.getParamValue();
			// 判断是否有表达式
			if (sql.contains(permission)) {
				// 有则替换为参数值
				sql = sql.replaceAll(permission, value);
				paramsJson.put(key, value);
			}
		}
		// 替换XML标签
		if (sql.contains("<if") || sql.contains("<choose")) {
			// 追加select的xml标签
			sql = "<select>" + sql + "</select>";
			// 实例化解析XML对象
			XPathParser parser = new XPathParser(sql, false, null, new XMLMapperEntityResolver());
			XNode context = parser.evalNode("/select");
			Configuration configuration = new Configuration();
			configuration.setDatabaseId("");
			XMLScriptBuilder xmlScriptBuilder = new XMLScriptBuilder(configuration, context);
			SqlSource sqlSource = xmlScriptBuilder.parseScriptNode();
			// 获取转换xml标签后的sql对象
			BoundSql bs = sqlSource.getBoundSql(paramsJson);
			// 获取查询sql
			sql = bs.getSql();
		}
	}

	// 封装并返回
	SqlCondition sqlCondition = new SqlCondition();
	sqlCondition.setSql(sql);

	return sqlCondition;
}

2.4. 传入的参数

JSONObject params = JSONObject.parse("{\"aaa\":\"1\",\"bbb\":\"2\"}"));

2.5. 转换后的sql

select
	id aId,
	user_name aUserName,
	org_id aOrgId,
	sex aSex,
	img aImg 
from
	a_cyf_data a
 WHERE id=1

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-12 16:31:26  更:2022-05-12 16:33:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 1:41:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码