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

SpringBoot數(shù)據(jù)庫常見錯(cuò)誤DataIntegrityViolationException的原因及解決方案

 更新時(shí)間:2025年07月14日 10:28:06   作者:碼農(nóng)阿豪@新空間  
在SpringBoot+MyBatis/MyBatis-Plus開發(fā)過程中,數(shù)據(jù)庫操作是核心部分之一,然而,開發(fā)者經(jīng)常會遇到 org.springframework.dao.DataIntegrityViolationException異常本文將通過兩個(gè)典型案例,深入分析DataIntegrityViolationException的常見原因,并提供完整的解決方案

引言

在 Spring Boot + MyBatis/MyBatis-Plus 開發(fā)過程中,數(shù)據(jù)庫操作是核心部分之一。然而,由于 SQL 語法、數(shù)據(jù)類型不匹配、約束沖突等問題,開發(fā)者經(jīng)常會遇到 org.springframework.dao.DataIntegrityViolationException 異常。

本文將通過兩個(gè)典型案例,深入分析 DataIntegrityViolationException 的常見原因,并提供完整的解決方案。同時(shí),我們會結(jié)合代碼示例,幫助讀者理解如何避免類似問題。

1. DataIntegrityViolationException 概述

DataIntegrityViolationException 是 Spring 框架在數(shù)據(jù)庫操作失敗時(shí)拋出的異常,通常由以下原因引起:

  1. 數(shù)據(jù)類型不匹配(如字符串插入到 INT 列)
  2. 數(shù)據(jù)截?cái)啵ㄈ绯L字符串插入 VARCHAR(10))
  3. 違反約束(如 NOT NULL 列插入了 NULL)
  4. SQL 語法錯(cuò)誤(如 UPDATE 語句缺少 WHERE 條件)

接下來,我們通過兩個(gè)實(shí)際案例進(jìn)行分析。

2. 案例 1:SQL 語法錯(cuò)誤導(dǎo)致的數(shù)據(jù)類型轉(zhuǎn)換異常

問題描述

在執(zhí)行以下 MyBatis XML 映射的 SQL 時(shí),報(bào)錯(cuò):

org.springframework.dao.DataIntegrityViolationException: 
### Error updating database. Cause: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: 
Data truncation: Truncated incorrect DOUBLE value: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...'

錯(cuò)誤 SQL:

<update id="updateCookie">
    update task_management set cookie = #{cookie}
    <if test="creatorId != null">
        and creator_id = #{creatorId}
    </if>
</update>

問題分析

錯(cuò)誤原因:

  • SQL 語句缺少 WHERE 關(guān)鍵字,導(dǎo)致 and creator_id = #{creatorId} 被解析為 cookie = (#{cookie} and creator_id = #{creatorId})。
  • MySQL 嘗試將 JWT Token(字符串)和 creatorId 進(jìn)行邏輯運(yùn)算,導(dǎo)致類型轉(zhuǎn)換失敗。

錯(cuò)誤 SQL 實(shí)際執(zhí)行情況:

-- 錯(cuò)誤的 SQL
UPDATE task_management SET cookie = ('eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...' AND creator_id = 123);

-- 正確的 SQL 應(yīng)該是
UPDATE task_management SET cookie = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...' WHERE creator_id = 123;

解決方案

方法 1:使用 <where> 標(biāo)簽

<update id="updateCookie">
    UPDATE task_management
    SET cookie = #{cookie}
    <where>
        <if test="creatorId != null">
            AND creator_id = #{creatorId}
        </if>
    </where>
</update>

方法 2:使用 <trim> 標(biāo)簽

<update id="updateCookie">
    UPDATE task_management
    SET cookie = #{cookie}
    <trim prefix="WHERE" prefixOverrides="AND">
        <if test="creatorId != null">
            AND creator_id = #{creatorId}
        </if>
    </trim>
</update>

方法 3:使用注解方式

@Update("<script>" +
        "UPDATE task_management SET cookie = #{cookie}" +
        "<where>" +
        "   <if test='creatorId != null'>AND creator_id = #{creatorId}</if>" +
        "</where>" +
        "</script>")
void updateCookie(@Param("cookie") String cookie, @Param("creatorId") Long creatorId);

最佳實(shí)踐

  • 始終在 UPDATE/DELETE 語句中使用 WHERE 條件,避免全表更新。
  • 使用 MyBatis 動態(tài) SQL 標(biāo)簽(<where>、<trim>)防止語法錯(cuò)誤。
  • 啟用 SQL 日志,檢查實(shí)際執(zhí)行的 SQL:
logging.level.org.mybatis=DEBUG

3. 案例 2:數(shù)據(jù)截?cái)噱e(cuò)誤(Data Truncation)

問題描述

在插入數(shù)據(jù)時(shí),報(bào)錯(cuò):

org.springframework.dao.DataIntegrityViolationException:
### Error updating database. Cause: java.sql.SQLException: 
Data truncated for column 'match_status' at row 1

錯(cuò)誤 SQL:

INSERT INTO customer_order (match_status) VALUES ('pending_verification');

問題分析

可能原因:

  • match_statusENUM,但插入了不在枚舉列表的值。
  • match_statusTINYINT,但插入了字符串或超出范圍的值(如 256)。
  • match_statusVARCHAR(10),但插入了超長字符串(如 "pending_verification")。

排查方法:

  • 查看表結(jié)構(gòu):
DESC customer_order;
  • 檢查 match_status 列的定義:
SHOW CREATE TABLE customer_order;

解決方案

情況 1:match_status 是 ENUM

如果 match_statusENUM('pending', 'success', 'failed'),則只能插入這三個(gè)值之一:

ALTER TABLE customer_order 
MODIFY COLUMN match_status ENUM('pending', 'success', 'failed') NOT NULL;

代碼調(diào)整:

customerOrder.setMatchStatus("success"); // 正確
// customerOrder.setMatchStatus("invalid_status"); // 錯(cuò)誤

情況 2:match_status 是 TINYINT

如果 match_statusTINYINT(0-255),則不能插入字符串或超出范圍的值:

ALTER TABLE customer_order 
MODIFY COLUMN match_status TINYINT UNSIGNED NOT NULL DEFAULT 0;

代碼調(diào)整:

customerOrder.setMatchStatus(1); // 正確
// customerOrder.setMatchStatus(256); // 錯(cuò)誤(超出范圍)
// customerOrder.setMatchStatus("pending"); // 錯(cuò)誤(類型不匹配)

情況 3:match_status 是 VARCHAR 但長度不足

如果 match_statusVARCHAR(10),但插入了更長的字符串:

ALTER TABLE customer_order 
MODIFY COLUMN match_status VARCHAR(50); -- 擴(kuò)大長度

代碼調(diào)整:

customerOrder.setMatchStatus("pending"); // 正確
// customerOrder.setMatchStatus("pending_verification"); // 可能被截?cái)?

最佳實(shí)踐

  • 在數(shù)據(jù)庫設(shè)計(jì)階段明確字段類型和約束。
  • 在代碼中校驗(yàn)數(shù)據(jù)是否符合數(shù)據(jù)庫約束。
  • 使用日志監(jiān)控 SQL 執(zhí)行情況:
logging.level.org.springframework.jdbc=DEBUG

4. 總結(jié)與預(yù)防措施

問題類型錯(cuò)誤示例解決方案
SQL 語法錯(cuò)誤UPDATE ... SET col = val AND ...使用 <where> 標(biāo)簽
ENUM 不匹配插入不在枚舉列表的值修改數(shù)據(jù)庫或代碼
數(shù)值超出范圍TINYINT 插入 256檢查數(shù)據(jù)庫范圍
字符串超長VARCHAR(10) 插入 20 字符擴(kuò)大列長度或截?cái)鄶?shù)據(jù)

通用調(diào)試技巧

查看數(shù)據(jù)庫表結(jié)構(gòu):

DESC table_name;
SHOW CREATE TABLE table_name;

啟用 SQL 日志:

logging.level.org.mybatis=DEBUG
logging.level.org.springframework.jdbc=DEBUG

在代碼中校驗(yàn)數(shù)據(jù):

if (value.length() > 10) {
    throw new IllegalArgumentException("字段超長");
}

5. 結(jié)語

DataIntegrityViolationException 是 Spring Boot 開發(fā)中常見的數(shù)據(jù)庫異常,通常由 SQL 語法錯(cuò)誤、數(shù)據(jù)類型不匹配或約束沖突引起。通過本文的分析和解決方案,希望讀者能夠更高效地定位和修復(fù)類似問題。

關(guān)鍵點(diǎn)回顧:

  1. SQL 語法檢查:確保 UPDATE/DELETE 語句有正確的 WHERE 條件。
  2. 數(shù)據(jù)類型匹配:確保 Java 代碼傳入的值與數(shù)據(jù)庫列類型一致。
  3. 約束校驗(yàn):避免插入 NULL、超長或不符合 ENUM 的值。

以上就是SpringBoot數(shù)據(jù)庫常見錯(cuò)誤DataIntegrityViolationException的原因及解決方案的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot數(shù)據(jù)庫錯(cuò)誤DataIntegrityViolationException的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 使用自定義注解和@Aspect實(shí)現(xiàn)責(zé)任鏈模式的組件增強(qiáng)的詳細(xì)代碼

    使用自定義注解和@Aspect實(shí)現(xiàn)責(zé)任鏈模式的組件增強(qiáng)的詳細(xì)代碼

    責(zé)任鏈模式是一種行為設(shè)計(jì)模式,其作用是將請求的發(fā)送者和接收者解耦,從而可以靈活地組織和處理請求,本文講給大家介紹如何使用自定義注解和@Aspect實(shí)現(xiàn)責(zé)任鏈模式的組件增強(qiáng),文中有詳細(xì)的代碼示例供大家參考,感興趣的同學(xué)可以借鑒一下
    2023-05-05
  • springAOP完整實(shí)現(xiàn)過程

    springAOP完整實(shí)現(xiàn)過程

    當(dāng)你調(diào)用SimpleService類的doSomething方法時(shí),上述的PerformanceAspect會自動攔截此調(diào)用,并且記錄該方法的執(zhí)行時(shí)間,這樣你就完成了一個(gè)針對Spring的AOP入門級案例,感興趣的朋友一起看看吧
    2024-02-02
  • Java?DelayQueue實(shí)現(xiàn)延時(shí)任務(wù)的示例詳解

    Java?DelayQueue實(shí)現(xiàn)延時(shí)任務(wù)的示例詳解

    DelayQueue是一個(gè)無界的BlockingQueue的實(shí)現(xiàn)類,用于放置實(shí)現(xiàn)了Delayed接口的對象,其中的對象只能在其到期時(shí)才能從隊(duì)列中取走。本文就來利用DelayQueue實(shí)現(xiàn)延時(shí)任務(wù),感興趣的可以了解一下
    2022-08-08
  • 關(guān)于SpringBoot中事務(wù)失效的幾種情況

    關(guān)于SpringBoot中事務(wù)失效的幾種情況

    這篇文章主要介紹了關(guān)于SpringBoot中事務(wù)失效的幾種情況,Spring AOP默認(rèn)使用動態(tài)代理,會給被代理的類生成一個(gè)代理類,事務(wù)相關(guān)的操作都通過代理來完成,使用內(nèi)部方法調(diào)用時(shí),使用的是實(shí)例調(diào)用,沒有通過代理類調(diào)用方法,因此事務(wù)不會檢測到失敗,需要的朋友可以參考下
    2023-08-08
  • 用java在web環(huán)境下上傳和下載文件的技巧

    用java在web環(huán)境下上傳和下載文件的技巧

    這篇文章主要介紹了用java在web環(huán)境下上傳和下載文件的技巧的相關(guān)資料
    2016-01-01
  • springboot中spring.profiles.include的妙用分享

    springboot中spring.profiles.include的妙用分享

    這篇文章主要介紹了springboot中spring.profiles.include的妙用,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • IDEA集成Sonar的完整流程

    IDEA集成Sonar的完整流程

    這篇文章主要介紹了IDEA集成Sonar的完整流程,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Netty分布式行解碼器邏輯源碼解析

    Netty分布式行解碼器邏輯源碼解析

    這篇文章主要為大家介紹了Netty分布式行解碼器邏輯源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • Mybatis-plus中的@EnumValue注解使用詳解

    Mybatis-plus中的@EnumValue注解使用詳解

    這篇文章主要介紹了Mybatis-plus中的@EnumValue注解使用詳解,在PO類中,如果我們直接使用枚舉類型去映射數(shù)據(jù)庫的對應(yīng)字段保存時(shí),往往就會因?yàn)轭愋筒黄ヅ鋵?dǎo)致映射失敗,Mybatis-plus提供了一種解決辦法,就是使用@EnumValue注解,需要的朋友可以參考下
    2024-02-02
  • Java集合框架之Set的實(shí)現(xiàn)類與實(shí)戰(zhàn)使用詳解

    Java集合框架之Set的實(shí)現(xiàn)類與實(shí)戰(zhàn)使用詳解

    本文深入解析Java集合框架中的Set接口及其實(shí)現(xiàn)類,重點(diǎn)內(nèi)容包括Set接口不可重復(fù)性和無序性的設(shè)計(jì)理念,HashSet基于哈希表的底層實(shí)現(xiàn)與去重機(jī)制,LinkedHashSet維護(hù)插入順序的原理等,需要的朋友可以參考下
    2026-02-02

最新評論

商丘市| 湛江市| 恩平市| 都兰县| 六安市| 宁武县| 斗六市| 海盐县| 长丰县| 微博| 丰都县| 达拉特旗| 石渠县| 龙里县| 榆社县| 通山县| 怀化市| 济源市| 平顺县| 乌海市| 凤山县| 南城县| 永顺县| 广平县| 夏河县| 陆川县| 永安市| 荃湾区| 诏安县| 孝昌县| 中方县| 宁晋县| 华容县| 涞源县| 乐山市| 中牟县| 无棣县| 年辖:市辖区| 泗水县| 襄垣县| 文水县|