一、簡介
JDBC是java語言提供的一套訪問關系數據的接口。關系數據不僅僅是關系型數據庫,也可以是一些關系型文件,只要相應的數據源提供實現JDBC接口的驅動。在java編寫的應用中,可以利用JDBC接口可以執行SQL語句、檢索執行結果以及把對數據的修改寫回底層數據源。
JDBC與ODBC都是基於X/Open SQL CLI。JDBC提供了從java語言到X/Open SQL CLI以及SQL標准的映射,這種映射比較自然且易於使用。
JDBC是java平台的一部分,在java SE與java EE版本中都有JDBC的接口。JDBC API主要包含在java.sql與javax.sql這兩個包中。
二、概述
JDBC API為java程序提供了一個訪問一個或多個數據源的方式。在大多數情況下,這些數據源都是關系型數據庫管理系統,請求是通過SQL對數據進行訪問。 但是,也可以在其他數據源上實現支持JDBC API的驅動程序,比如在遺留文件系統和面向對象系統上實現JDBC API。
2.1、創建連接
在JDBC中,定義一個Connection接口來代表 一個底層數據源的鏈接。在典型場景中,JDBC應用程序將使用以下兩種機制之一連接到目標數據源:
(1)DriverManager—這個完全實現的類是在最初的JDBC1.0API中引入的。當應用程序首次嘗試通過指定URL連接到數據源時,DriverManager將自動加載在類路徑中找到的任何JDBC驅動程序(在JDBC4.0之前,任何驅動程序都必須被應用程序顯示的加載)
(2)DataSource—這個接口是在JDBC2.0可選包API中引入的。它優於DriverManager,因為它允許底層數據源的詳細信息對應用程序透明。一個被賦值了的DataSource對象就代表一個特定的數據源。當調用DataSource對象的getConnection方法時,DataSource實例將返回到該數據源的連接。只需更改DataSource對象的屬性即可將應用程序定向到不同的數據源;無需更改應用程序代碼。同樣,可以更改DataSource的實現,而無需更改使用它的應用程序代碼。
JDBC API還定義了支持企業應用程序的DataSource的兩個重要擴展。這些擴展包括以下兩個接口:
(1)ConnectionPoolDataSource—支持緩存與重用物理連接,從而提高應用程序性能和可伸縮性
(2)XADataSource—提供可以參與分布式事務的連接
2.2、SQL執行與結果處理
一旦建立了連接,使用JDBC API的應用程序就可以對目標數據源執行查詢和更新。JDBC API提供對SQL:2003的最常用實現功能的訪問。由於不同的供應商對這些特性的支持程度不同,所以JDBC API提供了DatabaseMetadata接口。應用程序可以使用DatabaseMetadata接口來確定所使用的數據源是否支持某個特定的功能。
應用程序使用Connection接口中的方法指定事務屬性並創建Statement,PreparedStatement或CallableStatement對象。 這些語句對象被用來行SQL語句並檢索結果。 ResultSet接口封裝了SQL查詢的結果。語句也可能是批處理的,從而允許應用程序向數據源提交多個更新作為單個執行單元。
JDBC API用RowSet接口擴展了ResultSet接口,從而為表格數據提供了一個比標准結果集更通用的容器。RowSet對象是JavaBeans組件,它可以在不連接其數據源的情況下運行。 例如,RowSet實現可以是可序列化的,因此可以通過網絡發送,這對於希望在不影響JDBC驅動程序和數據源連接開銷的情況下對表格數據進行操作的小型客戶端特別有用。 RowSet實現的另一個功能是它可以包括一個自定義閱讀器,用於訪問表格格式的任何數據,而不僅僅是關系數據庫中的數據。 此外,當RowSet對象與數據源斷開連接時,它可以更新其行,並且其實現可以包括一個自定義寫入器,該寫入器將這些更新寫回到基礎數據源。
支持SQL高級數據類型
JDBC API定義了標准映射,以將SQL數據類型轉換為JDBC數據類型並轉換回JDBC數據類型。 這包括對SQL:2003高級數據類型的支持,例如BLOB,CLOB,ARRAY,REF,STRUCT,XML和DISTINCT。 JDBC驅動程序還可以為用戶定義類型(user-defined types UDT)實現一個或多個自定義類型映射,其中UDT映射為Java編程語言中的類。 JDBC API還提供對外部管理數據的支持,例如,數據源外部文件中的數據。
2.3、兩層模型
兩層模型將功能划分為客戶端層和服務器層,如下圖所示:
客戶端層包括一個或多個應用程序以及一個或多個JDBC驅動程序,其中應用程序負責處理以下職責范圍:
- 表達邏輯
- 業務邏輯
- 對包含多條語句的事務或者分布式事務的事務管理
- 資源的管理
在此模型中,應用程序直接與JDBC驅動程序交互,包括建立和管理物理連接以及處理特定底層數據源實現的詳細信息。 該應用程序可以利用其對特定實現的了解來利用非標准功能或進行性能調整。
該模型的一些缺點包括:
- 將表示和業務邏輯與基礎結構和系統級功能相結合。這給使用定義良好的體系結構生成可維護代碼帶來了障礙。
- 使應用程序的可移植性降低,因為應用程序被調整到特定的數據庫實現。需要連接到多個數據庫的應用程序必須了解不同供應商實現之間的差異
- 限制了可擴展性。 Typically, the application will hold onto one or more physical database connections until it terminates, limiting the number of concurrent applications that can be supported. In this model, issues of performance, scalability and availability are handled by the JDBC driver and the corresponding underlying data source. If an application deals with multiple drivers, it may also need to be aware of the different ways in which each driver/data source pair resolves these issues.
2.4、三層模型
三層模型引入了一個中間層服務器,以容納業務邏輯和基礎架構,如下圖所示:
此體系結構旨在為企業應用程序提供改進的性能、可擴展性和可用性。各層的功能划分如下:
-
客戶端:用來表示人機交互的表現層。Java程序、web瀏覽器和 PDAs都是典型的客戶端層的實現。客戶端與中間層應用程序交互,客戶端層不需要知道任何的底層架構以及底層數據源。
-
中間層服務器:一個中間層,其中包括:
1、應用程序:應用程序與客戶機交互並實現業務邏輯。如果應用程序包含與數據源的交互,應用程序只會在更高級別的抽象層進行處理,例如DataSource對象和Connection對象,而不是較低級別的驅動程序API。
2、應用程序服務器:為各種應用程序提供支持基礎設施服務。這些服務包括物理連接的管理與池化、事務管理以及屏蔽不同JDBC驅動程序之間差異。因為應用程序服務器提供的這些基礎服務,使得編寫可移植的程序更加的容易。應用服務器角色可以由javaEE服務器實現。應用程序使用的那些高層次抽象的操作都由應用程序服務器來實現,並且應用程序服務器直接與JDBC驅動程序交互。
3、JDBC驅動程序:提供與底層數據源的連接。每個驅動程序在其底層數據源支持的任何特性之上實現標准JDBC API。
-
底層數據源:數據所在的一層。它可以包括關系式DBMS、遺留文件系統、面向對象的DBMS、數據倉庫、電子表格或其他打包和呈現數據的方法。唯一的要求是一個支持J的相應的驅動程序
三、類和接口
以下類和接口構成了JDBC API。
3.1、java.sql包
核心JDBC API包含在程序包java.sql中。下面列出了java.sql中的枚舉、類和接口。枚舉數和類為粗體類型,接口為標准類型。
java.sql.Array
java.sql.BatchUpdateException
java.sql.Blob
java.sql.CallableStatement
java.sql.Clob
java.sql.ClientinfoStatus
java.sql.Connection
java.sql.ConnectionBuilder
java.sql.DataTruncation
java.sql.DatabaseMetaData
java.sql.Date
java.sql.Driver
java.sql.DriverAction
java.sql.DriverManager
java.sql.DriverPropertyInfo
java.sql.JDBCType
java.sql.NClob
java.sql.ParameterMetaData
java.sql.PreparedStatement
java.sql.PseudoColumnUsage
java.sql.Ref
java.sql.ResultSet
java.sql.ResultSetMetaData
java.sql.RowId
java.sql.RowIdLifeTime
java.sql.Savepoint
java.sql.ShardingKey
java.sql.ShardingKeyBuilder
java.sql.SQLClientInfoException
java.sql.SQLData
java.sql.SQLDataException
java.sql.SQLException
java.sql.SQLFeatureNotSupportedException
java.sql.SQLInput
java.sql.SQLIntegrityConstraintViolationException
java.sql.SQLInvalidAuthorizationSpecException
java.sql.SQLNonTransientConnectionException
java.sql.SQLNonTransientException
java.sql.SQLOutput
java.sql.SQLPermission
java.sql.SQLSyntaxErrorException
java.sql.SQLTimeoutException
java.sql.SQLTransactionRollbackException
java.sql.SQLTransientConnectionException
java.sql.SQLTransientException
java.sql.SQLType
java.sql.SQLXML
java.sql.SQLWarning
java.sql.Statement
java.sql.Struct
java.sql.Time
java.sql.Timestamp
java.sql.Types
java.sql.Wrapper
以下類和接口是JDBC4.3API中新的,也是更新的。新的類和接口將以粗體突出顯示。
java.sql.CallableStatement
java.sql.Connection
java.sql.ConnectionBuilder
java.sql.DatabaseMetaData
java.sql.Date
java.sql.DriverManager
java.sql.PreparedStatement
java.sql.ResultSet
java.sql.ShardingKey
java.sql.ShardkingKeyBuilder
java.sql.Statement
java.sql.Timestamp
javax.sql.CommonDataSource
javax.sql.ConnectionPoolDataSource
javax.sql.DataSource
javax.sql.PooledConnection
javax.sql.PooledConnectionBuilder
javax.sql.XAConnectionBuilder
javax.sql.XADataSource
下圖展示了java.sql軟件包中的關鍵類和接口之間的交互和他們之間的關系。還顯示了創建語句、設置參數和檢索結果所涉及的方法
3.2、 javax.sql包
以下列表包含javax.sql程序包中所包含的類和接口。類以粗體突出顯示,接口為正常類型。
javax.sql.CommonDataSource
javax.sql.ConnectionEvent
javax.sql.ConnectionEventListener
javax.sql.ConnectionPoolDataSource
javax.sql.DataSource
javax.sql.PooledConnection
javax.sql.PooledConnectionBuilder
javax.sql.RowSet
javax.sql.RowSetEvent
javax.sql.RowSetInternal
javax.sql.RowSetListener
javax.sql.RowSetMetaData
javax.sql.RowSetReader
javax.sql.RowSetWriter
javax.sql.StatementEvent
javax.sql.StatementEventListener
javax.sql.XAConnection
javax.sql.XAConnectionBuilder
javax.sql.XADataSource
3.3、關鍵類關系圖
數據源與連接關系圖
連接池關系圖
分布式事務關系圖
行結果集關系圖
四、Database Metadata
DatabaseMetaData接口由JDBC驅動程序實現,用來提供有關其底層數據源的信息。它主要被應用程序服務器和工具使用來確定如何與給定的數據源進行交互。應用程序也可以使用DatabaseMetaData方法來獲取有關數據源的信息,但這中情況不經常出現。
DatabaseMetaData接口包括150多種方法,可根據它們提供的信息類型進行分類:
- 有關數據源的一般信息
- 數據源是否支持給定的功能或功能
- 數據源的限制
- 數據源包含的SQL對象以及這些對象的屬性
- 由數據源提供的事務處理支持
DatabaseMetaData接口還包含40多個字段,這些字段是用作各種DatabaseMetaData方法的返回值的常量。
4.1、創建DatabaseMetaData對象
可以使用Connection接口的getMetaData()方法來創建DababaseMetaData對象。DababaseMetaData對象被創建后,它可以用於動態發現有關底層數據源的信息。代碼示例創建一個DababaseMetaData對象,並使用它來確定數據庫中表的命名允許的最大字符數。
// con is a Connection object
DatabaseMetaData dbmd = con.getMetadata();
int maxLen = dbmd.getMaxTableNameLength();
4.2、檢索一般信息
DababaseMetaData接口中提供一些用於獲取底層數據源信息或者這些驅動實現細節的一些方法。
■ getURL
■ getUserName
■ getDatabaseProductVersion, getDriverMajorVersion and getDriverMinorVersion
■ getSchemaTerm, getCatalogTerm and getProcedureTerm
■ nullsAreSortedHigh and nullsAreSortedLow
■ usesLocalFiles and usesLocalFilePerTable
■ getSQLKeywords
4.3、判斷是否支持某種特性
DatabaseMetaData中有大量的方法是用來判斷某個給定的特性或者一組特性是否被當前驅動或者底層數據源支持。除此之外,其中一些方法還描述了所提供的支持級別。
一些描述對單個特征的支持的方法是:
■ supportsAlterTableWithDropColumn
■ supportsBatchUpdates
■ supportsTableCorrelationNames
■ supportsPositionedDelete
■ supportsFullOuterJoins
■ supportsStoredProcedures
■ supportsMixedCaseQuotedIdentifiers
描述功能支持級別的方法包括:
■ supportsANSI92EntryLevelSQL
■ supportsCoreSQLGrammar
4.4、數據源限制
DatabaseMetaData中還有一部分方法用來提供當前數據源有哪些限制。這一類方法中的一些方法包括:
■ getMaxRowSize
■ getMaxStatementLength
■ getMaxTablesInSelect
■ getMaxConnections
■ getMaxCharLiteralLength
■ getMaxColumnsInTable
此組中的方法將限制作為int形式返回。返回值為零表示沒有限制或限制未知
4.5、SQL對象與其屬性
DatabaseMetaData中的一些方法提供有關填充給定數據源的SQL對象的信息。
■ getSchemas
■ getCatalogs
■ getTables
■ getPrimaryKeys
■ getProcedures
■ getProcedureColumns
■ getUDTs
■ getFunctions
■ getFunctionColumns
4.6、事務支持
一小組方法提供有關數據源支持的事務語義的信息。
supportsMultipleTransactions
getDefaultTransactionIsolation