最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring JDBC參數(shù)處理與嵌入式數(shù)據(jù)庫的實戰(zhàn)指南

 更新時間:2025年10月29日 11:42:41   作者:lang20150928  
這篇文章介紹了Spring Framework中JDBC的支持,包括如何處理參數(shù)和數(shù)據(jù)值、處理BLOB和CLOB、為IN子句傳遞列表以及存儲過程調(diào)用中的復(fù)雜類型,本文用通俗易懂的方式講解Spring JDBC參數(shù)處理與嵌入式數(shù)據(jù)庫的相關(guān)操作,感興趣的朋友跟隨小編一起看看吧

以下內(nèi)容是 Spring Framework 官方文檔中關(guān)于 JDBC 支持的兩個重要章節(jié)(3.8 和 3.9),主要講解了在使用 Spring 的 JdbcTemplate 和相關(guān)工具時,如何處理一些常見的、復(fù)雜的數(shù)據(jù)庫操作問題,以及如何使用嵌入式數(shù)據(jù)庫(Embedded Database)進(jìn)行開發(fā)和測試。

下面我將用通俗易懂的方式,幫你系統(tǒng)地理解這段內(nèi)容的核心思想和關(guān)鍵知識點,并說明它們在實際開發(fā)中的意義。

?? 一、整體結(jié)構(gòu)概覽

章節(jié)主題用途
3.8參數(shù)與數(shù)據(jù)值處理常見問題解決 JDBC 操作中的特殊場景
3.9嵌入式數(shù)據(jù)庫支持快速搭建輕量級數(shù)據(jù)庫用于開發(fā)/測試

?? 二、深入理解 3.8 節(jié):參數(shù)與數(shù)據(jù)值處理的常見問題

? 3.8.1 提供 SQL 類型信息(SQL Type for Parameters)

? 問題背景:

Java 中的 null 值傳給數(shù)據(jù)庫時,JDBC 不知道它對應(yīng)的是 VARCHAR 還是 INTEGER,所以無法正確設(shè)置類型。這會導(dǎo)致插入 NULL 失敗。

? 解決方案:

Spring 允許你在設(shè)置參數(shù)時顯式指定 SQL 類型(來自 java.sql.Types 的常量)。

三種方式:

int 數(shù)組方式(適用于位置參數(shù))

jdbcTemplate.update(
    "INSERT INTO users(name, age) VALUES(?, ?)",
    "Tom", 25,
    new int[]{Types.VARCHAR, Types.INTEGER}  // 顯式指定類型
);

使用 SqlParameterValue 包裝參數(shù)

new SqlParameterValue(Types.VARCHAR, "Tom")

可以更精細(xì)控制,比如設(shè)置 scale(小數(shù)位數(shù))。

命名參數(shù) + SqlParameterSource
使用 MapSqlParameterSourceBeanPropertySqlParameterSource 并注冊類型:

MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("name", "Tom", Types.VARCHAR);
params.addValue("age", 25, Types.INTEGER);

?? 關(guān)鍵點:主要用于處理 NULL 插入或類型模糊的情況。

? 3.8.2 處理 BLOB 和 CLOB(大對象)

? 什么是 BLOB / CLOB?

  • BLOB:Binary Large Object → 圖片、音頻、PDF 等二進(jìn)制文件。
  • CLOB:Character Large Object → 大段文本(如文章、日志)。

? 為什么需要特殊處理?

普通 Stringbyte[] 在讀寫大文件時會占用大量內(nèi)存。理想做法是流式處理。

? Spring 的解決方案:LobHandler+LobCreator

功能接口方法
寫入 LOBLobCreatorsetBlobAsBinaryStream, setClobAsCharacterStream
讀取 LOBLobHandlergetBlobAsBytes, getClobAsString

示例:插入圖片和文本文件

jdbcTemplate.execute(
    "INSERT INTO docs(id, content, image) VALUES (?, ?, ?)",
    new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
        protected void setValues(PreparedStatement ps, LobCreator lc) throws SQLException {
            ps.setLong(1, 1L);
            lc.setClobAsCharacterStream(ps, 2, reader, (int)file.length()); // CLOB
            lc.setBlobAsBinaryStream(ps, 3, inputStream, (int)image.length()); // BLOB
        }
    }
);

?? 注意:lobHandler 通常是 DefaultLobHandler,但注意它不支持流式讀取超過 Integer.MAX_VALUE 的數(shù)據(jù)。

? 優(yōu)勢:避免一次性加載整個大文件到內(nèi)存。

? 3.8.3 為IN子句傳遞列表(List in IN Clause)

? 問題:

SQL 不允許預(yù)編譯語句動態(tài)占位符數(shù)量,比如:

SELECT * FROM users WHERE id IN (?)

但如果要傳 (1,2,3),就需要三個 ?。

? Spring 的解決方案:

自動拼接 SQL,根據(jù) List 長度生成對應(yīng)數(shù)量的 ?。

List<Long> ids = Arrays.asList(1L, 2L, 3L);
List<User> users = jdbcTemplate.query(
    "SELECT * FROM users WHERE id IN (:ids)",
    new MapSqlParameterSource("ids", ids),
    userRowMapper
);

? 使用 NamedParameterJdbcTemplate 自動處理。

?? 注意限制

  • 大多數(shù)數(shù)據(jù)庫對 IN 列表有上限(如 Oracle 是 1000)。
  • 如果超過,應(yīng)分批查詢。

? 3.8.4 存儲過程調(diào)用中的復(fù)雜類型(Complex Types)

? 問題:

某些數(shù)據(jù)庫(如 Oracle)支持自定義對象類型(如 STRUCT, ARRAY),Java 如何傳遞和接收?

? 解決方案:

輸出參數(shù)(返回復(fù)雜類型)→ SqlReturnType

declareParameter(new SqlOutParameter("item", OracleTypes.STRUCT, "ITEM_TYPE",
    (cs, idx, sqlType, typeName) -> {
        STRUCT struct = (STRUCT) cs.getObject(idx);
        // 轉(zhuǎn)換為 Java 對象
        return new TestItem(...);
    }));

輸入?yún)?shù)(傳入復(fù)雜類型)→ SqlTypeValue

SqlTypeValue value = new AbstractSqlTypeValue() {
    protected Object createTypeValue(Connection conn, ...) {
        StructDescriptor desc = new StructDescriptor("ITEM_TYPE", conn);
        return new STRUCT(desc, conn, new Object[]{id, name, date});
    }
};

然后作為參數(shù)傳入:

Map<String, Object> in = new HashMap<>();
in.put("item", value);
storedProc.execute(in);

? 適用于 Oracle、PostgreSQL 等支持復(fù)雜類型的數(shù)據(jù)庫。

??? 三、深入理解 3.9 節(jié):嵌入式數(shù)據(jù)庫(Embedded Database)

? 3.9.1 為什么要用嵌入式數(shù)據(jù)庫?

  • 輕量快速:無需安裝 MySQL/PostgreSQL。
  • 啟動快:內(nèi)存中運行,適合單元測試。
  • 隔離性好:每個測試獨立數(shù)據(jù)庫,不污染真實數(shù)據(jù)。
  • 便于自動化測試:CI/CD 中無需外部依賴。

常見用途:單元測試、集成測試、原型開發(fā)

? 3.9.2 通過 XML 創(chuàng)建嵌入式數(shù)據(jù)庫

<jdbc:embedded-database id="dataSource" generate-name="true">
    <jdbc:script location="classpath:schema.sql"/>
    <jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>
  • 自動創(chuàng)建 HSQL 內(nèi)存數(shù)據(jù)庫。
  • 執(zhí)行建表腳本和測試數(shù)據(jù)腳本。
  • 生成一個 DataSource Bean,可注入 DAO。

? 3.9.3 編程方式創(chuàng)建(推薦用于測試)

EmbeddedDatabase db = new EmbeddedDatabaseBuilder()
    .generateUniqueName(true)
    .setType(H2)
    .addScript("schema.sql")
    .addScripts("data.sql")
    .build();

? EmbeddedDatabase 實現(xiàn)了 DataSource,可以直接傳給 JdbcTemplate。

? 測試結(jié)束后記得 db.shutdown()

? 3.9.4 支持的嵌入式數(shù)據(jù)庫類型

類型說明
HSQL默認(rèn),老牌嵌入式數(shù)據(jù)庫
H2功能強大,支持 MySQL 模式、Web 控制臺
DerbyApache 開源,Java 編寫

推薦使用 H2,功能最全,調(diào)試方便。

? 3.9.5 測試數(shù)據(jù)訪問邏輯(最佳實踐模板)

class DataAccessTest {
    private EmbeddedDatabase db;
    @BeforeEach
    void setUp() {
        db = new EmbeddedDatabaseBuilder()
            .generateUniqueName(true)
            .addDefaultScripts() // 自動加載 schema.sql + data.sql
            .build();
    }
    @Test
    void shouldFindUserById() {
        JdbcTemplate template = new JdbcTemplate(db);
        List<User> users = template.query("SELECT * FROM users WHERE id = ?", 
            new Object[]{1}, userRowMapper);
        assertThat(users).hasSize(1);
    }
    @AfterEach
    void tearDown() {
        db.shutdown();
    }
}

? 這是典型的 集成測試模板。

? 3.9.6 為什么需要“唯一數(shù)據(jù)庫名”?

? 問題:

多個測試類都用相同的配置創(chuàng)建嵌入式數(shù)據(jù)庫,Spring 會復(fù)用同一個實例(因為默認(rèn)名字是 testdb),導(dǎo)致數(shù)據(jù)污染。

? 解決方案:

啟用唯一名稱生成:

.generateUniqueName(true)

或 XML 中:

<jdbc:embedded-database generate-name="true">

? 每次創(chuàng)建都是獨立數(shù)據(jù)庫,避免沖突。

? 3.9.7 擴展支持(高級)

你可以自定義:

  • 新的嵌入式數(shù)據(jù)庫類型(實現(xiàn) EmbeddedDatabaseConfigurer
  • 新的 DataSource 工廠(如連接池)

一般開發(fā)者不需要做,但框架開發(fā)者可以貢獻(xiàn)擴展。

?? 四、總結(jié):這些知識能用來做什么?

技術(shù)點實際應(yīng)用場景
SqlParameterValue插入 NULL 字段,確保類型正確
LobHandler存儲圖片、文檔、大文本(如博客內(nèi)容)
IN 子句傳 List批量查詢用戶、訂單等
SqlTypeValue調(diào)用 Oracle 存儲過程傳對象
嵌入式數(shù)據(jù)庫單元測試、快速原型、CI/CD 自動化

?? 五、學(xué)習(xí)建議

  1. 先掌握 JdbcTemplate 基礎(chǔ)用法(查詢、更新)
  2. 再學(xué)命名參數(shù)和 IN 子句(日常開發(fā)高頻)
  3. 測試時使用嵌入式數(shù)據(jù)庫(提升測試效率)
  4. 只有對接 Oracle 存儲過程時才深入 SqlTypeValue

?? 補充:現(xiàn)代 Spring 推薦替代方案

雖然這些技術(shù)仍然有效,但在現(xiàn)代 Spring Boot 項目中:

傳統(tǒng)技術(shù)現(xiàn)代替代
JdbcTemplate + LobHandler使用文件存儲服務(wù)(如 MinIO、S3)+ 數(shù)據(jù)庫存路徑
手動創(chuàng)建嵌入式數(shù)據(jù)庫使用 @DataJpaTest + H2(Spring Boot 自動配置)
SqlTypeValue使用 JPA + Hibernate 映射復(fù)雜類型,或 MyBatis

如果你告訴我你目前在做什么項目(比如:Web 后端?單元測試?還是對接 Oracle?),我可以給出更具體的建議 ??

到此這篇關(guān)于Spring JDBC實戰(zhàn):參數(shù)處理與嵌入式數(shù)據(jù)庫的文章就介紹到這了,更多相關(guān)Spring JDBC參數(shù)處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA異常處理捕獲與拋出原理解析

    JAVA異常處理捕獲與拋出原理解析

    這篇文章主要介紹了JAVA異常處理捕獲與拋出原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • Spring Boot 3 中 WebFilter 的執(zhí)行順序流程分析

    Spring Boot 3 中 WebFilter 的執(zhí)行順序流程分析

    Spring Boot中管理WebFilter順序,默認(rèn)為Integer.MAX_VALUE,需顯式使用@Order或Ordered接口定義優(yōu)先級,請求階段按順序值從小到大執(zhí)行,響應(yīng)階段按從大到小,相同順序值依賴Bean注冊順序,本文詳細(xì)說明在Spring Boot 3中如何管理這些過濾器的執(zhí)行流程,需要的朋友一起看看吧
    2025-08-08
  • 深入了解Java核心類庫--Math類

    深入了解Java核心類庫--Math類

    本文是小編最新給大家整理的關(guān)于Java中Math類常用方法的知識,通過實例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧,
    2021-07-07
  • Spring batch批處理框架

    Spring batch批處理框架

    本文主要介紹了Spring batch批處理框架的相關(guān)知識。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-04-04
  • java原裝代碼完成pdf在線預(yù)覽和pdf打印及下載

    java原裝代碼完成pdf在線預(yù)覽和pdf打印及下載

    本文主要介紹了java原裝代碼完成pdf在線預(yù)覽和pdf打印及下載的方法,具有一定的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • maven如何在tomcat8中實現(xiàn)自動部署

    maven如何在tomcat8中實現(xiàn)自動部署

    本篇文章主要介紹了maven如何在tomcat8中實現(xiàn)自動部署,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • java?map的key值轉(zhuǎn)駝峰命名的方法

    java?map的key值轉(zhuǎn)駝峰命名的方法

    這篇文章主要介紹了java?map的key值轉(zhuǎn)駝峰,通過實例代碼介紹了Map把“_”形式的key轉(zhuǎn)化為駝峰形式,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • 關(guān)于Java?CPU或內(nèi)存使用率過高問題定位

    關(guān)于Java?CPU或內(nèi)存使用率過高問題定位

    Spring?cloud微服務(wù)廣泛應(yīng)用后,服務(wù)的監(jiān)控和運維壓力也與日俱增,經(jīng)常有服務(wù)出現(xiàn)CPU或者內(nèi)存使用率過高的告警,那么遇到這樣的問題我們該如何排查呢?我們可以借助哪些工具來定位問題呢?本文將介紹一下遇到此類問題的解決思路和方法
    2024-10-10
  • Groovy編程入門攻略

    Groovy編程入門攻略

    這篇文章主要介紹了Groovy編程入門攻略,Groovy是一種同樣使用Java虛擬機的動態(tài)語言,需要的朋友可以參考下
    2015-07-07
  • 一文掌握IDEA中的Maven集成與創(chuàng)建

    一文掌握IDEA中的Maven集成與創(chuàng)建

    maven是用來幫助我們快速搭建項目結(jié)構(gòu)與開發(fā)環(huán)境的好工具,這篇文章主要介紹了一文掌握IDEA中的Maven集成與創(chuàng)建,需要的朋友可以參考下
    2023-02-02

最新評論

营山县| 泰来县| 兴隆县| 双峰县| 隆回县| 专栏| 德清县| 敦化市| 漳州市| 进贤县| 寿光市| 晋城| 韶山市| 尤溪县| 金阳县| 报价| 万山特区| 灌阳县| 上栗县| 五华县| 凤阳县| 印江| 景宁| 汝阳县| 庆云县| 彩票| 皋兰县| 巨鹿县| 穆棱市| 祁东县| 龙江县| 马公市| 白山市| 富川| 成安县| 肇庆市| 玉树县| 平定县| 尼木县| 宜良县| 大兴区|