首頁»Java WEB»JDBC常見面試題集錦(二)

JDBC常見面試題集錦(二)

來源:deepinmind 發布時間:2014-03-19 閱讀次數:

  JDBC的保存點(Savepoint)是什么,如何使用?

  有時候事務包含了一組語句,而我們希望回滾到這個事務的某個特定的點。JDBC的保存點可以用來生成事務的一個檢查點,使得事務可以回滾到這個檢查點。

  一旦事務提交或者回滾了,它生成的任何保存點都會自動釋放并失效。回滾事務到某個特定的保存點后,這個保存點后所有其它的保存點會自動釋放并且失效。可以讀下這個了解更多關于JDBC Savepoint的信息。

  JDBC的DataSource是什么,有什么好處?

  DataSource即數據源,它是定義在javax.sql中的一個接口,跟DriverManager相比,它的功能要更強大。我們可以用它來創建數據庫連接,當然驅動的實現類會實際去完成這個工作。除了能創建連接外,它還提供了如下的特性:

  • 緩存PreparedStatement以便更快的執行
  • 可以設置連接超時時間
  • 提供日志記錄的功能
  • ResultSet大小的最大閾值設置
  • 通過JNDI的支持,可以為servlet容器提供連接池的功能

  關于JDBC數據源的示例請看下這里

  如何通過JDBC的DataSource和Apache Tomcat的JNDI來創建連接池?

  對部署在servlet容器中的WEB程序而言,創建數據庫連接池非常簡單,僅需要以下幾步。

  • 在容器的配置文件中創建JDBC的JNDI資源,通常在server.xml或者context.xml里面。像這樣:
    <Resource name="jdbc/MyDB"
          global="jdbc/MyDB"
          auth="Container"
          type="javax.sql.DataSource"
          driverClassName="com.mysql.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/UserDB"
          username="pankaj"
          password="pankaj123"
          maxActive="100"
          maxIdle="20"
          minIdle="5"
          maxWait="10000"/>
    
    <ResourceLink name="jdbc/MyLocalDB"
                    global="jdbc/MyDB"
                    auth="Container"
                    type="javax.sql.DataSource" />
    
  • 在WEB應用程序中,先用InitialContext來查找JNDI資源,然后獲取連接。
    Context ctx = new InitialContext();
    DataSource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/MyLocalDB");
    
    完整的示例請看這里

  Apache的DBCP是什么?

  如果用DataSource來獲取連接的話,通常獲取連接的代碼和驅動特定的DataSource是緊耦合的。另外,除了選擇DataSource的實現類,剩下的代碼基本都是一樣的。

  Apache的DBCP就是用來解決這些問題的,它提供的DataSource實現成為了應用程序和不同JDBC驅動間的一個抽象層。Apache的DBCP庫依賴commons-pool庫,所以要確保它們都在部署路徑下。

  完整的使用示例請看這里

  什么是數據庫的隔離級別?

  當我們為了數據的一致性使用事務時,數據庫系統用鎖來防止別人訪問事務中用到的數據。數據庫通過鎖來防止臟讀,不可重復讀(Non-Repeatable Reads)及幻讀(Phantom-Read)的問題。

  數據庫使用JDBC設置的隔離級別來決定它使用何種鎖機制,我們可以通過Connection的getTransactionIsolation和setTransactionIsolation方法來獲取和設置數據庫的隔離級別。

隔離級別 事務 臟讀 不可重復讀 幻讀
TRANSACTION_NONE 不支持 不可用 不可用 不可用
TRANSACTION_READ_COMMITTED 支持 阻止 允許 允許
TRANSACTION_READ_UNCOMMITTED 支持 允許 允許 允許
TRANSACTION_REPEATABLE_READ 支持 阻止 阻止 允許
TRANSACTION_SERIALIZABLE 支持 阻止 阻止 阻止

  JDBC的RowSet是什么,有哪些不同的RowSet?

  RowSet用于存儲查詢的數據結果,和ResultSet相比,它更具靈活性。RowSet繼承自ResultSet,因此ResultSet能干的,它們也能,而ResultSet做不到的,它們還是可以。RowSet接口定義在javax.sql包里。

  RowSet提供的額外的特性有:

  • 提供了Java Bean的功能,可以通過settter和getter方法來設置和獲取屬性。RowSet使用了JavaBean的事件驅動模型,它可以給注冊的組件發送事件通知,比如游標的移動,行的增刪改,以及RowSet內容的修改等。
  • RowSet對象默認是可滾動,可更新的,因此如果數據庫系統不支持ResultSet實現類似的功能,可以使用RowSet來實現。

  RowSet分為兩大類:

  A. 連接型RowSet——這類對象與數據庫進行連接,和ResultSet很類似。JDBC接口只提供了一種連接型RowSet,javax.sql.rowset.JdbcRowSet,它的標準實現是com.sun.rowset.JdbcRowSetImpl。 B. 離線型RowSet——這類對象不需要和數據庫進行連接,因此它們更輕量級,更容易序列化。它們適用于在網絡間傳遞數據。有四種不同的離線型RowSet的實現。

  • CachedRowSet——可以通過他們獲取連接,執行查詢并讀取ResultSet的數據到RowSet里。我們可以在離線時對數據進行維護和更新,然后重新連接到數據庫里,并回寫改動的數據。
  • WebRowSet繼承自CachedRowSet——他可以讀寫XML文檔。
  • JoinRowSet繼承自WebRowSet——它不用連接數據庫就可以執行SQL的join操作。
  • FilteredRowSet繼承自WebRowSet——我們可以用它來設置過濾規則,這樣只有選中的數據才可見。

  RowSet和ResultSet的區別是什么?

  RowSet繼承自ResultSet,因此它有ResultSet的全部功能,同時它自己添加了些額外的特性。RowSet一個最大的好處是它可以是離線的,這樣使得它更輕量級,同時便于在網絡間進行傳輸。

  具體使用哪個取決于你的需求,不過如果你操作ResultSet對象的時間較長的話,最好選擇一個離線的RowSet,這樣可以釋放數據庫連接。

  常見的JDBC異常有哪些?

  有以下這些:

  • java.sql.SQLException——這是JDBC異常的基類。
  • java.sql.BatchUpdateException——當批處理操作執行失敗的時候可能會拋出這個異常。這取決于具體的JDBC驅動的實現,它也可能直接拋出基類異常java.sql.SQLException。
  • java.sql.SQLWarning——SQL操作出現的警告信息。
  • java.sql.DataTruncation——字段值由于某些非正常原因被截斷了(不是因為超過對應字段類型的長度限制)。

  JDBC里的CLOB和BLOB數據類型分別代表什么?

  CLOB意思是Character Large OBjects,字符大對象,它是由單字節字符組成的字符串數據,有自己專門的代碼頁。這種數據類型適用于存儲超長的文本信息,那些可能會超出標準的VARCHAR數據類型長度限制(上限是32KB)的文本。

  BLOB是Binary Larget OBject,它是二進制大對象,由二進制數據組成,沒有專門的代碼頁。它能用于存儲超過VARBINARY限制(32KB)的二進制數據。這種數據類型適合存儲圖片,聲音,圖形,或者其它業務程序特定的數據。

  JDBC的臟讀是什么?哪種數據庫隔離級別能防止臟讀?

  當我們使用事務時,有可能會出現這樣的情況,有一行數據剛更新,與此同時另一個查詢讀到了這個剛更新的值。這樣就導致了臟讀,因為更新的數據還沒有進行持久化,更新這行數據的業務可能會進行回滾,這樣這個數據就是無效的。

  數據庫的TRANSACTIONREADCOMMITTED,TRANSACTIONREPEATABLEREAD,和TRANSACTION_SERIALIZABLE隔離級別可以防止臟讀。

  什么是兩階段提交?

  當我們在分布式系統上同時使用多個數據庫時,這時候我們就需要用到兩階段提交協議。兩階段提交協議能保證是分布式系統提交的原子性。在第一個階段,事務管理器發所有的事務參與者發送提交的請求。如果所有的參與者都返回OK,它會向參與者正式提交該事務。如果有任何一個參與方返回了中止消息,事務管理器會回滾所有的修改動作。

  JDBC中存在哪些不同類型的鎖?

  從廣義上講,有兩種鎖機制來防止多個用戶同時操作引起的數據損壞。

  樂觀鎖——只有當更新數據的時候才會鎖定記錄。 悲觀鎖——從查詢到更新和提交整個過程都會對數據記錄進行加鎖。

  不僅如此,一些數據庫系統還提供了行鎖,表鎖等鎖機制。

  DDL和DML語句分別代表什么?

  DDL(數據定義語言,Data Definition Language)語句用來定義數據庫模式。Create,Alter, Drop, Truncate, Rename都屬于DDL語句,一般來說,它們是不返回結果的。

  DML(數據操作語言,Data Manipulation Language)語句用來操作數據庫中的數據。select, insert, update, delete, call等,都屬于DML語句。

  java.util.Date和java.sql.Date有什么區別?

  java.util.Date包含日期和時間,而java.sql.Date只包含日期信息,而沒有具體的時間信息。如果你想把時間信息存儲在數據庫里,可以考慮使用Timestamp或者DateTime字段。

  如何把圖片或者原始數據插入到數據庫中?

  可以使用BLOB類型將圖片或者原始的二進制數據存儲到數據庫里。

  什么是幻讀,哪種隔離級別可以防止幻讀?

  幻讀是指一個事務多次執行一條查詢返回的卻是不同的值。假設一個事務正根據某個條件進行數據查詢,然后另一個事務插入了一行滿足這個查詢條件的數據。之后這個事務再次執行了這條查詢,返回的結果集中會包含剛插入的那條新數據。這行新數據被稱為幻行,而這種現象就叫做幻讀。

  只有TRANSACTION_SERIALIZABLE隔離級別才能防止產生幻讀。

  SQLWarning是什么,在程序中如何獲取SQLWarning?

  SQLWarning是SQLException的子類,通過Connection, Statement, Result的getWarnings方法都可以獲取到它。 SQLWarning不會中斷查詢語句的執行,只是用來提示用戶存在相關的警告信息。

  如果Oracle的存儲過程的入參出參中包含數據庫對象,應該如何進行調用?

  如果Oracle的存儲過程的入參出參中包含數據庫對象,我們需要在程序創建一個同樣大小的對象數組,然后用它來生成Oracle的STRUCT對象。然后可以通過數據庫對象的setSTRUCT方法傳入這個struct對象,并對它進行使用。

  如果java.sql.SQLException: No suitable driver found該怎么辦?

  如果你的SQL URL串格式不正確的話,就會拋出這樣的異常。不管是使用DriverManager還是JNDI數據源來創建連接都有可能拋出這種異常。它的異常棧看起來會像下面這樣。

org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class 'com.mysql.jdbc.Driver' for connect URL ''jdbc:mysql://localhost:3306/UserDB'
    at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createConnectionFactory(BasicDataSource.java:1452)
    at org.apache.tomcat.dbcp.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1371)
    at org.apache.tomcat.dbcp.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
java.sql.SQLException: No suitable driver found for 'jdbc:mysql://localhost:3306/UserDB
    at java.sql.DriverManager.getConnection(DriverManager.java:604)
    at java.sql.DriverManager.getConnection(DriverManager.java:221)
    at com.journaldev.jdbc.DBConnection.getConnection(DBConnection.java:24)
    at com.journaldev.jdbc.DBConnectionTest.main(DBConnectionTest.java:15)
Exception in thread "main" java.lang.NullPointerException
    at com.journaldev.jdbc.DBConnectionTest.main(DBConnectionTest.java:16)

  解決這類問題的方法就是,檢查下日志文件,像上面的這個日志中,URL串是'jdbc:mysql://localhost:3306/UserDB,只要把它改成jdbc:mysql://localhost:3306/UserDB就好了。

  什么是JDBC的最佳實踐?

  下面列舉了其中的一些:

  • 數據庫資源是非常昂貴的,用完了應該盡快關閉它。Connection, Statement, ResultSet等JDBC對象都有close方法,調用它就好了。
  • 養成在代碼中顯式關閉掉ResultSet,Statement,Connection的習慣,如果你用的是連接池的話,連接用完后會放回池里,但是沒有關閉的ResultSet和Statement就會造成資源泄漏了。
  • 在finally塊中關閉資源,保證即便出了異常也能正常關閉。
  • 大量類似的查詢應當使用批處理完成。
  • 盡量使用PreparedStatement而不是Statement,以避免SQL注入,同時還能通過預編譯和緩存機制提升執行的效率。
  • 如果你要將大量數據讀入到ResultSet中,應該合理的設置fetchSize以便提升性能。
  • 你用的數據庫可能沒有支持所有的隔離級別,用之前先仔細確認下。
  • 數據庫隔離級別越高性能越差,確保你的數據庫連接設置的隔離級別是最優的。
  • 如果在WEB程序中創建數據庫連接,最好通過JNDI使用JDBC的數據源,這樣可以對連接進行重用。
  • 如果你需要長時間對ResultSet進行操作的話,盡量使用離線的RowSet。

  譯注:終于翻譯完了,希望能對你的面試有所幫助。拿個好offer!

  相關文檔:JDBC常見面試題集錦(一)

  英文來源:http://www.journaldev.com/2529/jdbc-interview-questions-and-answers

QQ群:WEB開發者官方群(515171538),驗證消息:10000
微信群:加小編微信 849023636 邀請您加入,驗證消息:10000
提示:更多精彩內容關注微信公眾號:全棧開發者中心(fsder-com)
網友評論(共1條評論) 正在載入評論......
理智評論文明上網,拒絕惡意謾罵 發表評論 / 共1條評論
登錄會員中心
分分中彩票app 彰武县| 巧家县| 嘉定区| 昭通市| 天柱县| 清苑县| 普宁市| 吉木乃县| 阳谷县| 建平县| 伊宁市| 科技| 宣化县| 柘城县| 上高县| 商丘市| 武义县| 太谷县| 贵港市| 昌黎县| 汝阳县| 五华县| 涪陵区| 宜章县| 湄潭县| 阿尔山市| 探索| 百色市| 惠东县| 新津县| 定结县| 尉氏县| 长子县| 溧阳市| 定日县| 昔阳县| 寻甸| 天全县|