使用 @restcontrolleradvice 结合 @exceptionhandler 可以捕获数据源异常。针对 spring boot,核心做法是拦截 dataaccessexception 或其子类(如 badsqlgrammarexception),在处理器方法中返回统一的 json 响应。这样能确保数据库连接失败或 sql 语法错误时,应用不会崩溃,而是向客户端返回明确的错误信息。

如何区分并处理具体的 SQL 语法错误?
通过检查异常类型是否为 BadSqlGrammarException 来区分语法错误。当捕获到该特定异常时,可以提取其原始 SQL 语句和错误代码,构建包含详细调试信息的错误对象返回给前端。这有助于开发阶段快速定位 SQL 拼写或结构问题。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class DataSourceExceptionHandlerApplication {
public static void main(String[] args) {
SpringApplication.run(DataSourceExceptionHandlerApplication.class, args);
}
}
@RestController
public class TestController {
@GetMapping("/test")
public String test() {
// 模拟触发 BadSqlGrammarException
throw new org.springframework.jdbc.BadSqlGrammarException(
"SELECT * FROM nonexistent_table",
null,
new java.sql.SQLSyntaxErrorException("Table 'db.nonexistent_table' doesn't exist")
);
}
}
如何处理通用的数据库连接或执行异常?
对于非语法类的通用异常,如连接超时或事务失败,应捕获更广泛的 DataAccessException。这类异常通常由底层 JDBC 驱动抛出,表明数据库通信或执行层面出现问题。在此类情况下,返回标准的业务错误码和通用提示语,避免将敏感的堆栈信息泄露给客户端。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.BadSqlGrammarException;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BadSqlGrammarException.class)
public ResponseEntity<map object>> handleBadSqlGrammar(BadSqlGrammarException ex) {
Map<string object> error = new HashMap();
error.put("code", 5001);
error.put("message", "SQL Syntax Error: " + ex.getOriginalMessage());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
@ExceptionHandler(DataAccessException.class)
public ResponseEntity<map object>> handleDataAccess(DataAccessException ex) {
Map<string object> error = new HashMap();
error.put("code", 5000);
error.put("message", "Database Access Error");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
}
}</string></map></string></map>
如果异常发生在事务管理器中会怎样?
当数据源异常发生在事务边界内时,TransactionSystemException 可能会包裹原始的 DataAccessException。此时直接捕获 DataAccessException 可能无法命中,需要额外添加对 TransactionSystemException 的处理逻辑,或者依赖 Spring 的默认回滚机制后由全局处理器捕获根因异常。在实际编码中,建议优先捕获最具体的异常类型以确保精确控制。











