1,测试实体类

package org.springblade.sample.test;import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;/*** @Author: 肖扬* @CreateTime: 2025-09-05* @Description: SqlSessionFactoryTest测试* @Version: 1.0*/
@Data
@TableName("session_factory_pojo")
public class SessionFactoryPojo {private Long id;private String name;private String age;
}

2,测试Mapper类

package org.springblade.sample.test;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springblade.sample.entity.PangolinCsvData;import java.util.List;@Mapper
public interface SessionFactoryMapper extends BaseMapper<SessionFactoryPojo> {void insertBatch(@Param("list") List<PangolinCsvData> list);
}

3,测试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="org.springblade.sample.test.SessionFactoryMapper"><insert id="insertBatch">INSERT INTO $TABLE_NAME$ (id,name,age) VALUES<foreach collection="list" item="item" index="index" separator=",">(#{item.id},#{item.name},#{item.age})</foreach></insert>
</mapper>

4,工具类

package org.springblade.sample.utils;import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.StringUtil;import java.sql.Timestamp;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** @Author: 肖扬* @CreateTime: 2025-09-05* @Description: MyBatis BoundSql 转可执行 SQL 工具类(支持 list、对象、map)* @Version: 2.0*/
@Slf4j
@UtilityClass
public class SqlBuilderUtil {private final Pattern LIST_PARAM_PATTERN = Pattern.compile("__frch_item_(\\d+)\\.(.+)");/*** 将 BoundSql 转换为可执行 SQL** @param boundSql    MyBatis BoundSql* @param paramObject Mapper 参数(支持 list、单对象、Map)* @param ListKey     参数key* @return 可执行 SQL 字符串*/public String buildExecutableSql(BoundSql boundSql, Object paramObject, String ListKey) {String sql = boundSql.getSql();List<ParameterMapping> paramMappings = boundSql.getParameterMappings();if (paramMappings == null || paramMappings.isEmpty()) {return sql;}StringBuilder resultSql = new StringBuilder(sql);for (ParameterMapping p : paramMappings) {String paramName = p.getProperty();Object paramValue = resolveParamValue(paramName, paramObject, ListKey);String replacement = formatSqlValue(paramValue);// 替换第一个 ? 为实际值int qIndex = resultSql.indexOf("?");if (qIndex >= 0) {resultSql.replace(qIndex, qIndex + 1, replacement);}}return resultSql.toString();}/*** 根据参数名解析参数值,支持 list / Map / 普通对象*/private Object resolveParamValue(String paramName, Object paramObject, String listKey) {if (paramObject == null) {return null;}// 1. 支持 list 参数(批量 insert/update)if (paramObject instanceof MapperMethod.ParamMap) {MapperMethod.ParamMap<?> paramMap = (MapperMethod.ParamMap<?>) paramObject;// list 参数if (StringUtil.isNotBlank(listKey) && paramMap.containsKey(listKey)) {List<?> listObj = (List<?>) paramMap.get(listKey);Matcher matcher = LIST_PARAM_PATTERN.matcher(paramName);if (matcher.matches()) {int index = Integer.parseInt(matcher.group(1));String property = matcher.group(2);if (listObj != null && index < listObj.size()) {return BeanUtil.toMap(listObj.get(index)).get(property);}}}// 其他 Map 参数(#{xxx} 这种)if (paramMap.containsKey(paramName)) {return paramMap.get(paramName);}}// 2. 直接传入 Mapif (paramObject instanceof Map) {return ((Map<?, ?>) paramObject).get(paramName);}// 3. 普通对象,通过反射取属性Map<String, Object> objMap = BeanUtil.toMap(paramObject);return objMap.get(paramName);}/*** 参数值转 SQL 字符串*/private String formatSqlValue(Object value) {if (value == null) {return "NULL";}if (value instanceof String) {// 简单转义单引号return "'" + ((String) value).replace("'", "''") + "'";}if (value instanceof Number) {return String.valueOf(value);}if (value instanceof Date) {return "'" + new Timestamp(((Date) value).getTime()) + "'";}return "'" + value.toString().replace("'", "''") + "'";}
}

5,测试Controller

package org.springblade.sample.test;import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.sample.utils.SqlBuilderUtil;
import org.springblade.scheduled.exception.ScheduledException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** @Author: 肖扬* @CreateTime: 2025-09-05* @Description: 测试SqlSessionFactoryTest* @Version: 1.0*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/scheduled/")
@Api(tags = "SqlSessionFactoryTest")
@Slf4j
public class SessionFactoryTestController {private final JdbcTemplate jdbcTemplate;private final SqlSessionFactory sqlSessionFactory;private final PlatformTransactionManager transactionManager;@GetMapping( "testSessionFactory")public void testSqlSessionFactory() {List<SessionFactoryPojo> list = new ArrayList<>();list.add(new SessionFactoryPojo(2L, "李四", "25"));String tableName = "session_factory_pojo";String mapperMethod = "org.springblade.sample.test.SessionFactoryMapper.insertBatch";MapperMethod.ParamMap<List<?>> paramMap = new MapperMethod.ParamMap<>();paramMap.put("list",list );//开启事务DefaultTransactionDefinition def = new DefaultTransactionDefinition();def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);TransactionStatus status = transactionManager.getTransaction(def);try (SqlSession sqlSession = sqlSessionFactory.openSession()) {Configuration configuration = sqlSession.getConfiguration();MappedStatement mappedStatement = configuration.getMappedStatement(mapperMethod);BoundSql boundSql = mappedStatement.getBoundSql(paramMap);//buildExecutableSql的listKey和paramMap的key和insertBatch的参数名称和一致String sql = SqlBuilderUtil.buildExecutableSql(boundSql, paramMap, "list");sql = sql.replace("$TABLE_NAME$", tableName);log.info("sql:{}", sql);jdbcTemplate.execute(sql);// 提交事务transactionManager.commit(status);}catch (Exception e){log.error("createTidalTask occurred exception: {}", e.getMessage(), e);// 发生异常时回滚事务transactionManager.rollback(status);throw new ScheduledException("任务执行失败!");}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/98403.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/98403.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/98403.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鹧鸪云光储流程系统全新升级:视频指引与分阶段模块使用指南

鹧鸪云光储流程系统近日完成重要更新&#xff0c;全面优化了操作指引体系&#xff0c;为用户带来更高效、直观的使用体验。本次升级重点推出了全套功能操作视频&#xff0c;并明确了不同业务阶段的核心模块使用指南&#xff0c;助力用户快速上手、提升工作效率。全覆盖视频操作…

ChatGPT 协作调优:把 SQL 查询从 5s 优化到 300ms 的全过程

ChatGPT 协作调优&#xff1a;把 SQL 查询从 5s 优化到 300ms 的全过程 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般绚烂的技术栈中&#xff0c;我是那个永不停歇的色彩收集者。 &#x1f98b; 每一个优化都是我培育的花朵&#xff0c;每一个…

复杂计算任务的智能轮询优化实战

目录 复杂计算任务的智能轮询优化实战 一、轮询方法介绍 二、三种轮询优化策略 1、用 setTimeout 替代 setInterval 2、轮询时间指数退避 3、标签页可见性检测&#xff08;Page Visibility API&#xff09; 三、封装一个简单易用的智能轮询方法 四、结语 作者&#xff…

Java开发中常用CollectionUtils方式,以及Spring中CollectionUtils常用方法示例

场景 Java开发中常用的CollectionUtils 一、Spring Framework的CollectionUtils 包路径&#xff1a;org.springframework.util.CollectionUtils 核心方法&#xff1a; isEmpty(Collection<?> coll) List<String> list null; boolean empty CollectionUtil…

人工智能学习:Transformer结构(文本嵌入及其位置编码器)

一、输入部分介绍 输入部分包含: 编码器源文本嵌入层及其位置编码器 解码器目标文本嵌入层及其位置编码器 在transformer的encoder和decoder的输入层中,使用了Positional Encoding,使得最终的输入满足: 这里,input_embedding是通过常规embedding层,将每一个词的…

⸢ 肆 ⸥ ⤳ 默认安全建设方案:c-1.增量风险管控

&#x1f44d;点「赞」&#x1f4cc;收「藏」&#x1f440;关「注」&#x1f4ac;评「论」 在金融科技深度融合的背景下&#xff0c;信息安全已从单纯的技术攻防扩展至架构、合规、流程与创新的系统工程。作为一名从业十多年的老兵&#xff0c;将系统阐述数字银行安全体系的建设…

第二课、熟悉Cocos Creator 编辑器界面

本文主要介绍Cocos Creator 编辑器界面中几个常规的面板功能&#xff0c;让新手了解编辑器界面中常规的面板功能&#xff0c;更好的使用Cocos Creator 编辑器。一、编辑器界面常规面板划分Cocos Creater编辑器默认样式如上&#xff0c;主要包含&#xff1a;1、工具栏&#xff0…

Elixir通过Onvif协议控制IP摄像机,扩展ExOnvif的摄像头连续移动功能 ContinuousMove

Elixir 通过Onvif 对IP设备进行控制时&#xff0c;可以使用 ExOnvif 库。ExOnvif官方文档 此文章仅提供了ContinuousMove的控制方式及示例。 Elixir Onvif协议控制IP设备的其他命令&#xff0c;可以参考以下链接 绝对移动 【AbsoluteMove】 调用指定预置位 【GotoPreset】 …

android studio JNI 环境配置实现 java 调用 c/c++

1、在 app 级的 build.gradle 文件配置两个地方 android{ defaultConfig{ // 在 defaultConfig 里配置下面代码 externalNativeBuild { cmake { cppFlags "-frtti -fexceptions"//添加对 c 的异常处理支持 …

静态时序分析详解之时序路径类型

目录 一、概览 二、时序路径 2.1 数据路径 2.2 时钟路径 2.3 时钟门控路径 2.4 异步路径 2.5 关键路径 2.6 False路径 2.7 单周期路径 2.8 多周期路径 2.9 最长路径和最短路径 三、参考资料 一、概览 ​ ​静态时序分析通过模拟最差条件下分析所有的时序路径&am…

SpringBoot埋点功能技术实现方案深度解析:架构设计、性能优化与扩展性实践

SpringBoot埋点功能技术实现方案深度解析&#xff1a;架构设计、性能优化与扩展性实践 1. 原理剖析与技术实现细节 1.1 埋点技术基本原理 埋点&#xff08;Tracking&#xff09;是通过在代码中植入特定逻辑&#xff0c;收集用户行为数据、系统运行状态和业务指标的技术手段。在…

自建prometheus监控腾讯云k8s集群

自建prometheus监控腾讯云k8s集群 使用场景 k8s集群&#xff08;腾讯云容器服务&#xff09; promtheus (外部自建服务) 腾讯云提供了容器内部自建 Prometheus 监控 TKE 集群的文档&#xff0c;参考。 当前的环境promethues建在k8S外的云服务器上&#xff0c;与上面链接文…

2025高教社国赛数学建模C题参考论文(含模型和代码)

2025 年高教社杯大学生数学建模竞赛 C 题参考论文 目录 NIPT 的时点选择与胎儿的异常判定 摘要 1 问题重述 2 问题分析 2.1 问题 1 分析 2.2 问题 2 分析 2.3 问题 3 分析 2.4 问题 4 分析 3 模型假设与符号定义 3.1 模型假设 4. 孕周在 10-25 周内检测有…

iOS开发环境搭建及打包流程

一、下载xcode 直接去苹果商店的appstore下载就行 二、clone项目 1.登录xcode苹果账号或对应代码仓库账号 2.clone项目 3.安装设备真机环境&#xff08;未安装过的话&#xff09; 三.安装cocoapods 1. 检查并更新 Ruby 环境 CocoaPods 是基于 Ruby 编写的&#xff0c;因此…

数据结构之链表(单向链表与双向链表)

一&#xff0c;链表描述链表是一种常见的重要的数据结构,是动态地进行存储分配的一种结构。常用于需存储的数据的数目无法事先确定。1.链表的一般结构链表的组成&#xff1a; 头指针&#xff1a;存放一个地址&#xff0c;该地址指向一个元素 结点&#xff1a;用户需要的实际数据…

从反向代理到负载均衡:Nginx + Tomcat 构建高可用Web服务架构

从反向代理到负载均衡&#xff1a;Nginx Tomcat 构建高可用Web服务架构 文章目录从反向代理到负载均衡&#xff1a;Nginx Tomcat 构建高可用Web服务架构一、基础铺垫&#xff1a;什么是反向代理&#xff1f;1.1 反向代理的核心原理1.2 Nginx反向代理实战配置步骤1&#xff1a…

Simulink中使用Test sequence单元测试

一、Tips 在对simulink模型进行Test sequence单元测试时&#xff0c;如果采取书写测试用例的话&#xff0c;有以下操作。 1、使用”fprintf(‘time%f\n’, t);“来打印当前step的时间&#xff1b; 二、数据类型转换 1、double类型 -> boolean类型 clc; clear all;% 1、doubl…

【mysql】SQL自连接:什么时候需要,什么时候不需要?

SQL自连接:什么时候需要,什么时候不需要? 通过具体示例和对比解析,彻底搞懂SQL自连接的使用场景 在处理SQL查询时,尤其是当表中存在自引用关系(如referee_id引用同一张表的id)时,很多开发者会疑惑:这个查询到底需不需要自连接?本文将通过多个具体示例,带你彻底弄清何…

「美」创新在于人,而不是产品 - AxureMost 落葵网

添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 第一章&#xff1a;创新的心理学 创新与心理安全 蜡烛问题&#xff1a;卡尔邓克尔的蜡烛问题实验揭示了创造性思维的重要性。通过颠覆对盒子用途的先入为主观念&#xff0c;参与者能够找到创新性的解决方案…

新规则,新游戏:AI时代下的战略重构与商业实践

当你的客服AI能够真正像员工一样理解客户的行业术语&#xff0c;当AI能主动从大量的客户咨询中筛选出高价值潜在客户 —— 这已经不再是理想中才能存在的场景&#xff0c;而是当下 “人工智能 ” 行动深入推进中&#xff0c;企业智能化转型的真实写照。 "人工智能 " …