java,通過SqlSessionFactory實現動態表明的插入和查詢(適用于一個版本一個表的場景)

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;企業智能化轉型的真實寫照。 "人工智能 " …