首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JDBC 常見問題權威 FAQ(Sun 論壇精選):驅動、連接、ResultSet、性能與故障排查

     編輯:Java 相關知識

JDBC 核心知識庫:21 個高頻問題深度解析

源自 Sun 官方論壇的 JDBC FAQ,涵蓋 JDBC 3.0 特性、驅動分類、連接建立、ResultSet 操作、異常診斷、性能調優、Applet 部署等全方位實戰問題。本文按主題重組,補充代碼示例與最佳實踐。

驅動與版本篇

Q1: 什麼是 JDBC 3.0 API?

JDBC 3.0 是 JDBC 規範重大更新(JSR 54),核心新特性:

  • 可滾動/可更新 ResultSet(TYPE_SCROLL_INSENSITIVE、CONCUR_UPDATABLE)
  • SQL:1999 新數據類型:BOOLEAN、BLOB、CLOB、ARRAY、STRUCT、REF、DATALINK
  • 保存點(Savepoint)事務細粒度控制
  • 參數元數據(ParameterMetaData)、自動生成鍵獲取
  • 連接池標準化(ConnectionPoolDataSource、PooledConnection)

Q2: JDBC-ODBC Bridge 是否支持 JDBC 3.0 新特性?

僅提供有限子集,不支持可滾動 ResultSet、Savepoint 等高級特性。生產環境強烈建議使用純 Java 驅動(Type 3/4)。

Q3: 有哪些類型的 JDBC 驅動?

類型架構代表優/缺點
Type 1JDBC-ODBC BridgeSun Bridge需 ODBC 驅動,平台相關,僅測試用
Type 2Native APIOracle OCI需客戶端庫,性能較好,部署複雜
Type 3Net ProtocolIDA Server中間件轉發,純 Java,支持防火牆
Type 4Thin DriverMySQL Connector/J、Oracle Thin純 Java、直連數據庫、部署最簡、首選

查詢最新驅動列表:Sun JDBC Drivers Page

連接與異常篇

Q4: 「No suitable driver」錯誤成因?

  1. 驅動類未加載:Class.forName("com.mysql.jdbc.Driver") 缺失或拼寫錯誤
  2. JDBC URL 格式錯誤:不被任何已註冊驅動識別(如 jdbc:mysql://localhost:3306/db vs jdbc:mysql//localhost/db)
  3. Bridge 模式下共享庫未正確加載(Windows DLL 路徑問題)

Q5: 為什麼找不到 java.sql.DriverManager?

JDK 1.0.2(Netscape 3.0 等舊瀏覽器)不包含 JDBC API。解決方案:驅動廠商提供重命名包 jdbc.sql.*,Applet 中 import jdbc.sql.* 替代 java.sql.*,隨 Applet 下載。現代環境(JDK 1.1+)無此問題。

Q6: ODBC 驅動管理器報「Data source name not found」?

客戶機未配置系統 DSN(控制面板 → 管理工具 → 數據源 ODBC)。Bridge 僅作 ODBC 客戶端,**必須在客戶機配置 DSN**,不能指望讀取服務器端 DSN。

ResultSet 與性能篇

Q7: 如何一次取整行而非逐列 getXXX?

JDBC API 無整行獲取方法。getObject(int columnIndex) 仍按列訪問。性能瓶頸通常不在列獲取,而在網絡往返、獲取行數、大對象流式讀取。建議:

  • 使用 fetchSize 減少網絡交互
  • 大字段用 getBinaryStream/getCharacterStream 流式讀取
  • 避免 SELECT *,顯式列出所需列

Q8: 如何獲取結果集行數?

無直接 getRowCount()。三種方案:

  1. 可滾動 ResultSet:rs.last(); int count = rs.getRow(); rs.beforeFirst();
  2. 不可滾動:遍歷計數 while(rs.next()) count++;
  3. 最優:SELECT COUNT(*) FROM ... 獨立查詢,利用數據庫優化器

Q9: String/對象頻繁創建導致 GC 壓力如何緩解?

JDBC 規範每次 getString 返回新對象。緩解策略:

  • 用 getBytes() + 字節數組池/緩存(需驅動支持)
  • 升級驅動:部分驅動實現內部緩存
  • 架構層面:引入二級緩存(Ehcache/Redis)減少重複查詢

Applet 與部署篇

Q10: JDBC-ODBC Bridge 能用於 Applet 嗎?

**不受信任 Applet 禁止使用**(安全限制:ODBC 是本地代碼,繞過沙箱)。受信任 Applet(簽名/企業內網)可用,但強烈建議改用 Type 4 純 Java 驅動,無需客戶端配置、可自動下載。

Q11: JDK 自帶 JDBC 驅動嗎?

僅自帶 JDBC-ODBC Bridge。其他驅動需單獨下載安裝。JDK 6+ 引入 java.sql.Driver SPI 機制,驅動 JAR 放入 classpath 自動註冊,無需 Class.forName。

Bridge 限制篇

Q12: Bridge 是多線程的嗎?

**不是**。同步方法序列化所有 ODBC 調用,多線程無併發優勢,且可能因數據庫鎖與 Bridge 信號量產生死鎖。

Q13: Bridge 支持每連接多併發 Statement 嗎?

**不支持**。每連接僅允許一個打開的 Statement。

Q14: 為什麼可滾動 ResultSet 的 afterLast/beforeFirst 不工作?

驅動僅實現 JDBC 1.0/2.0 核心,未實現可滾動 ResultSet。需升級 JDBC 3.0+ 驅動,且確認 DBMS 支持游標滾動,代碼創建 TYPE_SCROLL_INSENSITIVE 結果集。

調試與最佳實踐

Q15: 如何啟用 JDBC 追蹤調試?


// DriverManager 方式
DriverManager.setLogWriter(new PrintWriter(System.out));
// DataSource 方式
dataSource.setLogWriter(new PrintWriter(System.out));
// 連接池/分布式事務
poolDataSource.setLogWriter(...);
xaDataSource.setLogWriter(...);

輸出含連接建立、SQL 執行、參數綁定、結果集遍歷等完整鏈路,極利於排查 SQL 錯誤、參數類型不匹配、事務邊界問題。

Q16: 連接數據庫的完整清單

  1. JDK/JRE 安裝
  2. 獲取目標數據庫 Type 4 驅動 JAR,放入 classpath / WEB-INF/lib
  3. 配置連接參數:URL、用戶、密碼、驅動類名
  4. (可選)配置連接池:DBCP/HikariCP/Tomcat JDBC Pool
  5. (可選)僅原型/測試階段使用 JDBC-ODBC Bridge,生產禁用
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved