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語句的編寫。