java:JDBC詳解,javajdbc詳解
JDBC全稱為:Java DataBase Connectivity(java資料庫連接)。SUN公司為了簡化、統一對資料庫的操作,定義了一套Java操作資料庫的規範,稱之為JDBC。 簡單的說,JDBC的意義在於在Java程式中執行SQL語句。驅動程式的意義在於提供統一的介面並隱藏實現細節。驅動程式定義了資料庫能做什麼(what to do),比如上面提到的這四個步驟,資料庫的製造商(例如Oracle)提供符合這些介面的實現(how to do),我們在編寫Java程式中只需要調用驅動程式中的介面就可以操作資料庫,完成這四個步驟。同電腦硬體的驅動程式類似,JDBC的驅動實現了”做什麼“和”怎麼做“的分離。與使用SQLPlus訪問資料庫類似,在操作資料庫之前,需要先跟資料庫建立串連。串連是一個虛擬概念,並不一定對應著網路連接(例如一些小型的檔案資料庫),建立串連後,可以通過獲得的連線物件來調用SQL語句。 操作資料基本的含義是執行SQL語句,包括DML,DDL,DCL均可,還可以調用資料庫中已有的預存程序。釋放資源使用JDBC編程時,與資料庫建立的串連以及通過這個串連建立的語句對象,都有可能需要調用相應的close方法來釋放底層建立的網路連接,或者開啟的檔案。 載入資料庫驅動:DriverManager可用於載入驅動DriverManager.registerDriver(new Driver());import com.mysql.jdbc.Driver;必須匯入對應驅動的包,過於依賴。 注意:在實際開發中並不推薦採用registerDriver方法註冊驅動。原因有二:一、查看Driver的原始碼可以看到,如果採用此種方式,會導致驅動程式註冊兩次,也就是在記憶體中會有兩個Driver對象。二、程式依賴mysql的api,脫離mysql的jar包,程式將無法編譯,將來程式切換底層資料庫將會非常麻煩。 推薦方式:Class.forName(“com.mysql.jdbc.Driver”);//載入驅動時,並不是真正使用資料庫的驅動類,只是使用資料庫驅動類名的字串而已。這裡驅動類名是沒有規律的,想知道只需要查看該驅動的文檔即可。 採用此種方式不會導致驅動對象在記憶體中重複出現,並且採用此種方式,程式僅僅只需要一個字串,不需要依賴具體的驅動,使程式的靈活性更高。 DriverManager:用於管理JDBC驅動的服務類。程式中使用該類主要是獲得Connection對象。DriverManager.getConnection(url, user, password),擷取URL對應的資料庫的串連URL用於標識資料庫的位置,程式員通過URL地址告訴JDBC程式串連哪個資料庫,URL的寫法為:jdbc:mysql://localhost:3306/test ?key=value不同的資料庫URL寫法存在差異。如果想瞭解特定資料庫的url寫法,可以查閱該資料庫驅動的文檔。 常用屬性:useUnicode=true&characterEncoding=UTF-8 Jdbc程式中的Connection,它用於代表資料庫的連結,Connection是資料庫編程中最重要的一個對象,用戶端與資料庫所有互動都是通過connection對象完成的,這個對象的常用方法:createStatement():建立向資料庫發送sql的statement對象prepareStatement(sql) :建立向資料庫發送先行編譯sql的PrepareSatement對象prepareCall(sql):建立執行預存程序的callableStatement對象。--- 預存程序 setAutoCommit(boolean autoCommit):設定事務是否自動認可。 commit() :在連結上提交事務。 ---與事務相關!!rollback() :在此連結上復原事務。 //注意我們使用JDBC介面規範,我們雖然在項目中載入了對應的資料庫驅動實現包,但是在編程時,不需要引入import com.mysql.jdbc.Connection;因為這樣雖然對程式沒有影響,但是過去依賴驅動包。我們在JDBC編程時,直接參考JDKAPI文檔即可。
import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;public class JDBCDemo { public static void main(String[] args) throws SQLException, ClassNotFoundException { Class.forName("com.mysql.jdbc.Driver"); Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","123"); Statement stmt = connection.createStatement(); ResultSet rs = stmt.executeQuery("SELECT A_NAME FROM A"); while (rs.next()) { String name = rs.getString("A_NAME"); System.out.println("name is:"+ name); } rs.close(); stmt.close(); connection.close(); }}
Jdbc程式中的Statement對象用於向資料庫發送SQL語句, Statement對象常用方法:executeQuery(String sql) :用於向資料發送查詢語句。executeUpdate(String sql):用於向資料庫發送insert、update或delete語句execute(String sql):用於向資料庫發送任意sql語句 addBatch(String sql) :把多條sql語句放到一個批處理中。executeBatch():向資料庫發送一批sql語句執行。 Jdbc程式中的ResultSet用於代表Sql語句的執行結果。Resultset封裝執行結果時,採用的類似於表格的方式。ResultSet 對象維護了一個指向表格式資料行的遊標cursor,初始的時候,遊標在第一行之前,調用ResultSet.next() 方法,可以使遊標指向具體的資料行,進而調用方法擷取該行的資料。ResultSet既然用於封裝執行結果的,所以該對象提供的大部分方法都是用於擷取資料的get方法:擷取任意類型的資料getObject(int index)getObject(string columnName)擷取指定類型的資料,例如:getString(int index)getString(String columnName)提問:資料庫中列的類型是varchar,擷取該列的資料調用什麼方法?Int類型呢?bigInt類型呢?Boolean類型? 預設得到的ResultSet它只能向下遍曆(next()),對於ResultSet它可以設定成是滾動的,可以向上遍曆, 或者直接定位到一個指定的物理行號. 問題:怎樣得到一個滾動結果集?
Statement st=con.createStatement();ResultSet rs=st.executeQuery(sql);
這是一個預設結果集:只能向下執行,並且只能迭代一次。
Statement stmt = con.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);ResultSet rs = stmt.executeQuery(sql);
這個就可以建立滾動結果集. 簡單說,就是在建立Statement對象時,不使用createStatement(); 而使用帶參數的createStatement(int,int)
Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
resultSetType - 結果集類型,它是 ResultSet.TYPE_FORWARD_ONLY、ResultSet.TYPE_SCROLL_INSENSITIVE 或 ResultSet.TYPE_SCROLL_SENSITIVE 之一 resultSetConcurrency - 並發類型;它是 ResultSet.CONCUR_READ_ONLY 或 ResultSet.CONCUR_UPDATABLE 之一 第一個參數值 ResultSet.TYPE_FORWARD_ONLY 該常量指示游標只能向前移動的 ResultSet 對象的類型。 ResultSet.TYPE_SCROLL_INSENSITIVE 該常量指示可滾動但通常不受 ResultSet 底層資料更改影響的 ResultSet 對象的類型。 ResultSet.TYPE_SCROLL_SENSITIVE 該常量指示可滾動並且通常受 ResultSet 底層資料更改影響的 ResultSet 對象的類型。 第二個參數值 ResultSet.CONCUR_READ_ONLY 該常量指示不可以更新的 ResultSet 對象的併發模式。 ResultSet.CONCUR_UPDATABLE 該常量指示可以更新的 ResultSet 對象的併發模式。 以上五個值,可以有三種搭配方式 ResultSet.TYPE_FORWARD_ONLY ResultSet.CONCUR_READ_ONLY 預設 ResultSet.TYPE_SCROLL_INSENSITIVE ResultSet.CONCUR_READ_ONLY ResultSet.TYPE_SCROLL_SENSITIVE ResultSet.CONCUR_UPDATABLE 常用API next():移動到下一行 previous():移動到前一行 absolute(int row):移動到指定行 beforeFirst():移動resultSet的最前面 afterLast() :移動到resultSet的最後面 updateRow() :更新行資料ResultSet還提供了對結果集進行滾動和更新的方法Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);next():移動到下一行previous():移動到前一行absolute(int row):移動到指定行beforeFirst():移動resultSet的最前面afterLast() :移動到resultSet的最後面updateRow() :更新行資料 Jdbc程式運行完後,切記要釋放程式在運行過程中,建立的那些與資料庫進行互動的對象,這些對象通常是ResultSet, Statement和Connection對象。 特別是Connection對象,它是非常稀有的資源,用完後必須馬上釋放,如果Connection不能及時、正確的關閉,極易導致系統宕機。Connection的使用原則是盡量晚建立,盡量早的釋放。 為確保資源釋放代碼能運行,資源釋放代碼也一定要放在finally語句中。 PreparedStatement是Statement的子介面,它的執行個體對象可以通過調用Connection.preparedStatement(sql)方法獲得,相對於Statement對象而言:PreperedStatement可以避免SQL注入的問題。Statement會使資料庫頻繁編譯SQL,可能造成資料庫緩衝區溢位。PreparedStatement 可對SQL進行先行編譯,從而提高資料庫的執行效率。並且PreperedStatement對於sql中的參數,允許使用預留位置的形式進行替換,簡化sql語句的編寫。