天天看點

jdbc的相關知識

如何通過jdbc通路資料庫?

java資料庫連接配接(java Database Connectivity,jdbc)是一種用于實作java程式中資料庫操作功能。它提供了執行sql語句,通路各種資料庫的方法,并為個各種不同的資料庫提供了相同的操作接口。java.sql中包含了所有資料庫操作的類。通過jdbc操作資料庫主要有以下幾步:

(1)加載驅動器,将資料庫的驅動加載到classpath中,在基于javaee的web開發中,一般将資料庫驅動拷貝到WEB—INF/lib下。

(2)加載驅動,将資料庫驅動注冊到Drivermanager中,通過反射class.forname(String drivename)。

(3)建立資料庫連接配接,獲得connection對象,一般使用DriverManager.getConnection(url,username,passwd)。其中url是連接配接資料庫的字元串,username是資料庫的使用者名,passwd是資料庫的密碼。

(4)建立statement對象或者PreparedStatement對象。

(5)執行sql語句。

(6)獲得結果集resultSet對象。

(7)依次關閉resultSet、statement、PreparedStatement、Connection對象,釋放所占用的資源。

jdbc處理事務采用哪種方法?

一個事務是由一條或多條sql語句組成的不可分割的工作單元,隻有當事務中的所有sql語句都正常執行完畢,事務才能被送出給資料庫。在jdbc中,一般通過commit()或者rollback()方法結束事務的操作。其中,commit()指的是事務中的送出,rollback指的是事務的復原,多用于在事務處理的過程中發生異常的情況。這兩種方法都位于java.sql.connection()類中。一般而言,程式預設自動送出,即操作成功後,程式自動調用commit(),否則調用rollback()。

當然,在jdbc中也可以調用setAutoCommit(false)方法來關掉自動送出,将多個資料庫操作的表達式作為一個事務,當操作完成後調用commit()整體送出,如果其中一個資料庫的操作出現問題,就會抛出異常而不會調用commit(),在這種情況下就可以在異常捕獲代碼段中加入rollback()實作事務的復原。采用此種方法可以在資料庫多次操作後,資料仍保持一緻性。

java有哪些事務隔離級别?

為了解決與多線程同時請求同一個資源的相關問題,事務之間通過鎖互相隔離開。如今,多數主流的資料庫都支援不同類型的鎖,是以,javaAPI支援不同類型的事務,它們由connection對象指派或确定,在jdbc中,事務的隔離級别主要分為以下5種:

(1)TRANSACTION_NONE_JDB不支援事務

(2)TRANSACTION_READ_UNCOMMIT 未送出讀,一個事務可以讀取另一個事務未送出的資料,并且不可重複讀和虛讀都是允許的。

(3)TRANSACTION_READ_COMMIT 已送出讀,一個事務不能讀取"髒"資料,但是允許不可重複讀和虛讀。

(4)TRANSACTION_REPEATABLE_READ 可重複讀,一個事務能重複讀取已經讀過的資料,不允許髒讀,還可以虛讀。

(5)TRANSACTION_SERIALIZETABLE 可序列化,事務的最高隔離級别,不允許髒讀,不可重複讀,虛讀的發生。

(髒讀,一個事務讀取另一個事務未送出的資料,可重複讀,一個事務的操作導緻另一個事務前後兩次讀取的資料不同,虛讀,一個事務的操作導緻另一個事務前後兩次查詢的結果資料量不同)

事務的隔離級别越高,為了躲避重複耗費的精力更多。在jdbc中,可以通過Connection對象的conn.setTRANSACTIONlevel()方法來設定事務隔離級别,也可以通過conn.getTRANSACTIONIsolation()方法來檢視事務的隔離級别。

class.forname()的作用是什麼?

在java語言中,任何類隻有被裝載到JVM上才能運作。class.forname()的作用就是把類裝載到JVM中,它會傳回一個與帶有給定字元串的類名的類或接口相關聯的一個class對象,并且jvm會加載這個類,同時JVM會加載該類的靜态代碼段。

在使用jdbc連接配接資料庫之前,一般都會調用class.forname("com.mysql.jdbc.driver")來加載資料庫驅動,那麼是否一定要使用這種方法呢?如果是,為什麼?其實,不一定非要使用這種方法來加載資料庫,也可以使用其他的方法來加載資料庫,例如:Test t = (test)Class.forname().newinstance()語句和Test t = new Test()就具有相同的效果,是以使用new也可以,但二者的差別也非常明顯:建立對象的方式不同。前者使用的是類加載機制,後者使用的是建立新的類。使用第一種方式會使程式具有更好的擴充性。例如:一個軟體在開發出來後會被多個公司使用,每家的公司處理流程大緻相同,隻有個别公司的業務邏輯不通,這時,完全可以把不同的地方抽象出來定義成一個接口BussinessInterface,針對每個公司不同的業務邏輯可以建立不同的實作類sub1,sub2,sub3等。通過建立不同的子類就可以實作不同的需求。為了達到良好的可擴充性,可以把子類采用配置檔案的方式放入XML,然後在采用BussinessInterface b = (bussinessInterface)Class.forname(classname).newInstance()建立執行個體即可提高開發人員的開發效率。當以後再有新的需求時,即使開發了新的子類,也不需要修改建立執行個體的代碼,隻需要修改配置檔案即可,進而提高了程式的可擴充性。

JDBC規範中要求Driver類在使用前必須向DriverManager注冊自己,是以,當執行Class.forname("com.mysql.jdbc.Driver")時,JVM會加載名字為"com.mysql.jdbc.Driver"對應的Driver類,而com.mysql.Driver類的實作如下:

。。。。。。

try{

}

catch(){

在調用class.forname()時,driver類被加載了,由于該類的靜态代碼也被執行了,是以Drive也被注冊到了DriverManager()中。

statement和preparedstatement與callablestatement有什麼差別?

statement用來執行不帶參數的簡單的sql語句,每次執行sql語句時,資料庫都要編譯sql語句,一個最簡單的sql語句如下:

statement stmt = conn.getStatement();

stmt.executeUpdate("insert into client values('aa','aaaa')");

prepardStatement表示預編譯的sql語句的對象,用于執行不帶參數的預編譯sql語句。

callableStatement則提供了用來執行資料庫調取存儲過程的方法。如果有輸出參數注冊,就說明是輸出參數。

雖然statement和preparedStatement能夠實作相同的功能,但相比之下,preparedstatement具有以下優點:

(1)效率更高。使用preparedstatement對象執行sql指令,該指令會被資料庫進行解析和編譯,然後放到指令緩沖區中。然後,當再次處理同一個對象的同一個指令時,由于在緩沖區中能夠發現預編譯的指令,隻需要解析一次,不需要再次編譯了,是可以重複使用的,能夠有效提高系統性能,是以,如果要執行插入、更新、删除等操作時,最好使用preparedStatement即可。鑒于此,preparedStatement适用于存在大量使用者的企業級應用軟體中。

(2)代碼可讀性和可維護性更好。以下是使用statement和preparedstatement來實作的sql指令,明顯可以看出preparedstatement的可讀性更好。

①stmt.executeUpdate("insert into t(coll,col2) colls values('"+var1+"','"+var2+"'')");

②perstmt=com.prepareStatement("insert into tb_name(coll,col2) values(?,?)");

perstmt.setString(1,var1);

perstmt.setString(2,var2);

(3)安全性更好。使用preparedstatement能夠有效預防sql注入問題,所謂sql注入是指把sql指令插入到web表單遞交或輸入域名或頁面請求的查詢字元串中,最終達到欺騙伺服器,達到執行惡意sql指令的目的。注入隻對sql指令的編譯過程有破壞作用,在執行階段隻是把輸入串作為資料處理,不會對sql語句進行解析,是以可以有效避免sql注入問題。

callablestatement是由prepareCall()方法建立的,它為所有的DBMS(DataBase Management

System)資料庫管理系統提供一種标準的資料庫調用存儲過程的方法。其對存儲過程的調用有兩種方式,一種是帶結果參數的,一種是不帶結果參數的,結果參數是輸出參數,是存儲過程的傳回值。這兩種方式都可以帶有數量不同的輸入參數(IN參數)、輸出參數(Out參數)和輸入輸出參數(INOut參數)。

getString方法和getObject方法有什麼差別?

jdbc提供了getString,getInt,getData等方法從resultset中擷取資料,當結果集傳回的資料量很小時,使用這些方法完全能夠滿足需求,但是當從結果集中傳回的資料量非常多時,使用這些方法就會抛出異常:ORACLE Exception

ORA-0100 miximum opencursors execeeded(在ORACLE資料中),使用getObject就可以解決這些問題。

getString(),getin()等方法被調用時,程式會一次性将資料讀取到記憶體中,然後通過調用resultset的next()或getString()等方法來擷取資料,當資料量大到記憶體中放不下時,就會抛出異常,而使用getObject方法就不會發生這種問題,因為getobject方法不會一次性将資料讀取到記憶體中,每次使用時都會去資料庫中擷取資料,是以不會發生資料量過大的問題。

 使用jdbc需要注意哪些問題?

使用jdbc程式設計時,首先要建立資料庫的連接配接,才能完成對資料庫的通路,由于與資料庫的連接配接是非常重要的資源。jdbc連接配接池提供了jdbc連接配接定義和數量有限的連接配接,如果連接配接數量不夠,就需要長時間的等待,錯誤的關閉和釋放jdbc會等待回收無效的jdbc,隻有正确的關閉和釋放jdbc連接配接,jdbc資源才能快速的重複使用,進而能夠提高系統的性能。是以在程式設計時,應該保證釋放不在使用的連接配接。

一般來講,在使用jdbc通路資料庫時,createStatement和preparedStatement最好放在循環的外面,而且使用了這些statement之後需要及時關閉。最好是在使用ececuteQuery或executeUpdata之後,如果不需要再使用結果集中的資料,最好馬上釋放statemnet,因為每次調用conn.createstatement()或者conn.preparedStatement()時,相當于再資料庫中建立了一個(遊标)cursor,如果把這兩方法放到循環中就會導緻不停的建立curtor,如果不能及時釋放,就會導緻抛出異常。

什麼是JDO?

java data object(java資料對象)是一個用于存取某種資料倉庫對象的标準化API,它使開發人員能夠間接的通路資料庫。

JDO是JDBC的一個補充,它提供了一個透明的存儲對象。對于開發人員來說,資料存儲對象不需要額外的代碼(例如:jdbc API),它把這些繁瑣的任務轉移到了JDO産品提供商身上,使開發人員解脫出來,使精力和時間集中在業務邏輯上。另外,相較于jdbc,JDO更靈活,更通用,它提供了所有資料底層的存儲功能,使得應用可移植性更強。