欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java.sql.SQLException異常原因排查與解決

 更新時(shí)間:2025年09月29日 09:28:04   作者:網(wǎng)羅開發(fā)  
在日常開發(fā)中,大家應(yīng)該或多或少都遇到SQL 在本地跑得好好的,一放到服務(wù)里執(zhí)行就報(bào) java.sql.SQLException,本文將結(jié)合一個(gè)小 Demo,帶大家看一下 SQLException 的常見原因,以及如何一步步排查

前言

在日常開發(fā)中,大家應(yīng)該或多或少都遇到過這種情況:SQL 在本地跑得好好的,一放到服務(wù)里執(zhí)行就報(bào) java.sql.SQLException。很多同學(xué)看到這個(gè)異常時(shí),第一反應(yīng)就是“是不是數(shù)據(jù)庫掛了?”。其實(shí)絕大多數(shù)情況跟數(shù)據(jù)庫無關(guān),而是 SQL 拼接、參數(shù)綁定或者日志缺失導(dǎo)致的。

這篇文章我結(jié)合一個(gè)小 Demo,帶大家看一下 SQLException 的常見原因,以及如何一步步排查。

場景描述:常見的 SQLException 問題

假設(shè)我們有一張 users 表,結(jié)構(gòu)很簡單:

CREATE TABLE users (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    age INT
);

在 Java 項(xiàng)目里寫了一個(gè)最普通的查詢:

String sql = "SELECT * FROM users WHERE username = ? AND age = ?";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setString(1, "zhangfei");
ps.setInt(2, 18);

ResultSet rs = ps.executeQuery();

看似沒問題,但在真實(shí)項(xiàng)目里,很容易因?yàn)橄旅鎺讉€(gè)問題報(bào) SQLException

  • SQL 拼接錯(cuò)誤:比如忘了 AND,或者參數(shù)占位符數(shù)量不對。
  • 參數(shù)綁定異常:明明是數(shù)字,結(jié)果 setString();或者順序錯(cuò)了。
  • SQL 沒有打印日志:導(dǎo)致無法復(fù)現(xiàn)真實(shí)執(zhí)行的 SQL。

排查思路:怎么快速鎖定問題?

遇到 SQLException 時(shí),不要慌,通常從以下幾個(gè)角度來排查:

1.打印完整 SQL

很多時(shí)候,你以為你執(zhí)行的是 SELECT * FROM users WHERE username = 'zhangfei',實(shí)際上可能變成了 SELECT * FROM users WHERE username = 'null'

2.檢查參數(shù)綁定

確認(rèn)每個(gè) ? 是否都被正確賦值,并且類型匹配。

3.用日志記錄 SQL

不僅要打印原始 SQL,還要把 參數(shù)替換后的 SQL 打出來,方便直接拿去數(shù)據(jù)庫執(zhí)行。

Demo:帶日志的 SQL 執(zhí)行封裝

我們可以寫一個(gè)簡單的工具方法來封裝 SQL 執(zhí)行和日志打印。這樣每次執(zhí)行 SQL 時(shí),都能清晰看到完整的 SQL。

import java.sql.*;
import java.util.Arrays;

public class JdbcHelper {

    public static void executeQuery(Connection conn, String sql, Object... params) {
        try (PreparedStatement ps = conn.prepareStatement(sql)) {

            // 參數(shù)綁定
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }

            // 打印完整 SQL
            System.out.println("Executing SQL: " + buildFullSql(sql, params));

            try (ResultSet rs = ps.executeQuery()) {
                while (rs.next()) {
                    System.out.println("User: " + rs.getString("username") + ", Age: " + rs.getInt("age"));
                }
            }

        } catch (SQLException e) {
            System.err.println("SQL 執(zhí)行異常: " + e.getMessage());
            e.printStackTrace();
        }
    }

    // 將參數(shù)替換到 SQL 中(簡易版)
    private static String buildFullSql(String sql, Object... params) {
        String fullSql = sql;
        for (Object param : params) {
            String value = (param instanceof String) ? "'" + param + "'" : String.valueOf(param);
            fullSql = fullSql.replaceFirst("\\?", value);
        }
        return fullSql;
    }

    // Demo 入口
    public static void main(String[] args) throws Exception {
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/testdb", "root", "password");

        executeQuery(conn, "SELECT * FROM users WHERE username = ? AND age = ?", "zhangfei", 18);
    }
}

運(yùn)行效果:

Executing SQL: SELECT * FROM users WHERE username = 'zhangfei' AND age = 18
User: zhangfei, Age: 18

一旦 SQL 寫錯(cuò),比如參數(shù)缺失,就能立刻在日志里看到:

Executing SQL: SELECT * FROM users WHERE username = 'zhangfei' AND age = null
SQL 執(zhí)行異常: Unknown column 'null' in 'where clause'

是不是就一目了然了?

結(jié)合實(shí)際開發(fā)的應(yīng)用

在真實(shí)的業(yè)務(wù)開發(fā)中,SQLException 的定位通常會踩到幾個(gè)坑:

  • 多服務(wù)場景:調(diào)用鏈太長,不知道 SQL 是在哪個(gè)微服務(wù)里執(zhí)行的。
  • ORM 框架二次封裝:比如 MyBatis,把 SQL 隱藏在 XML 里,導(dǎo)致排查困難。
  • 日志打印不全:只打印了原始 SQL,沒有參數(shù),運(yùn)維無法復(fù)現(xiàn)。

因此,建議大家在項(xiàng)目里加一個(gè) SQL 攔截器,不論是 MyBatis 的 Interceptor,還是 JPA 的日志配置,都要確保能拿到 完整 SQL。

總結(jié)

java.sql.SQLException 本質(zhì)上不是“數(shù)據(jù)庫壞了”,而是代碼邏輯和 SQL 執(zhí)行之間的溝通問題。核心思路就是:

  • 先把完整 SQL 打印出來
  • 確認(rèn)參數(shù)綁定是否正確
  • 保證日志可復(fù)現(xiàn)

這樣基本上 90% 的 SQL 問題都能快速解決。

到此這篇關(guān)于java.sql.SQLException異常原因排查與解決的文章就介紹到這了,更多相關(guān)java.sql.SQLException解決內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 8中日期和時(shí)間的處理方法

    Java 8中日期和時(shí)間的處理方法

    Java 8新增了LocalDate和LocalTime接口,接下來通過本文給大家介紹Java 8中日期和時(shí)間的處理方法,非常不錯(cuò),感興趣的朋友一起看下吧
    2016-08-08
  • Java 8 新特性終極版指南詳解

    Java 8 新特性終極版指南詳解

    Java 8已經(jīng)公布有一段時(shí)間了,種種跡象表明Java 8是一個(gè)有重大改變的發(fā)行版。本文給大家介紹Java 8 新特性終極版指南詳解,需要的朋友參考下
    2016-03-03
  • 解決SpringBoot2.1.0+RocketMQ版本沖突問題

    解決SpringBoot2.1.0+RocketMQ版本沖突問題

    這篇文章主要介紹了解決SpringBoot2.1.0+RocketMQ版本沖突問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • 詳解springSecurity之java配置篇

    詳解springSecurity之java配置篇

    這篇文章主要介紹了詳解springSecurity之java配置篇,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 詳解SpringBoot文件上傳下載和多文件上傳(圖文)

    詳解SpringBoot文件上傳下載和多文件上傳(圖文)

    本篇文章主要介紹了詳解SpringBoot文件上傳下載和多文件上傳(圖文),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-02-02
  • Java聊天室之使用Socket實(shí)現(xiàn)傳遞圖片

    Java聊天室之使用Socket實(shí)現(xiàn)傳遞圖片

    這篇文章主要為大家詳細(xì)介紹了Java簡易聊天室之使用Socket實(shí)現(xiàn)傳遞圖片功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以了解一下
    2022-10-10
  • Java開發(fā)框架spring實(shí)現(xiàn)自定義緩存標(biāo)簽

    Java開發(fā)框架spring實(shí)現(xiàn)自定義緩存標(biāo)簽

    這篇文章主要介紹了Java開發(fā)框架spring實(shí)現(xiàn)自定義緩存標(biāo)簽的詳細(xì)代碼,感興趣的小伙伴們可以參考一下
    2015-12-12
  • Spring Boot 中集成 Lombok 和 MapStruct最佳實(shí)踐指南

    Spring Boot 中集成 Lombok 和 MapStruct最

    文章詳解SpringBoot項(xiàng)目中Lombok與MapStruct整合實(shí)踐,涵蓋版本兼容、IDE配置、代碼分層、映射配置、測試驗(yàn)證及性能優(yōu)化,重點(diǎn)解決注解沖突、依賴注入等常見問題,強(qiáng)調(diào)分層管理和組件掃描配置,提升開發(fā)效率與代碼簡潔性,本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2025-08-08
  • 使用idea搭建一個(gè)spring mvc項(xiàng)目的圖文教程

    使用idea搭建一個(gè)spring mvc項(xiàng)目的圖文教程

    這篇文章主要介紹了使用idea直接創(chuàng)建一個(gè)spring mvc項(xiàng)目的圖文教程,本文通過圖文并茂的方式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java實(shí)現(xiàn)HDFS文件上傳下載

    Java實(shí)現(xiàn)HDFS文件上傳下載

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)HDFS文件上傳下載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06

最新評論