一、目錄

二、概述
簡述
JDBC是什么?JDBC英文名為:Java Data Base Connectivity(Java數據庫連接),官方解釋它是Java編程語言和廣泛的數據庫之間獨立於數據庫的連接標准的Java API,根本上說JDBC是一種規范,它提供的接口,一套完整的,允許便捷式訪問底層數據庫。可以用JAVA來寫不同類型的可執行文件:JAVA應用程序、JAVA Applets、Java Servlet、JSP等,不同的可執行文件都能通過JDBC訪問數據庫,又兼備存儲的優勢。簡單說它就是JAVA與數據庫的連接的橋梁或者插件,用JAVA代碼就能操作數據庫的增刪改查、存儲過程、事務等。
JDBC有什么用?我們用JAVA就能連接到數據庫;創建SQL或者MYSQL語句;執行SQL或MYSQL的查詢數據庫;查看和修改結果記錄。
我們思考一下?數據庫是由不同生產產商決定的,例如Mysql、Oracle、SQL Server,而如果JAVA JDK不可能說提供對不同數據庫的實現吧?還有,JAVA具備天生跨平台的優勢,它就提供了JDBC的接口API,具體的實現由不同的生產產商決定。這樣,數據庫生產產商都根據JAVA API去實現各自的應用驅動,這問題就迎刃而解了。
JDBC的工作原理是什么?我將在下一篇文章敘述JDBC運用的設計模式,以及部分JDK源碼。
工作原理圖(轉自百度百科)

常用接口
提供的接口包括:JAVA API:提供對JDBC的管理鏈接;JAVA Driver API:支持JDBC管理到驅動器連接。
DriverManager:這個類管理數據庫驅動程序的列表,查看加載的驅動是否符合JAVA Driver API的規范。
Connection:與數據庫中的所有的通信是通過唯一的連接對象。
Statement:把創建的SQL對象,轉而存儲到數據庫當中。
ResultSet:它是一個迭代器,用於檢索查詢數據。
三、快速入門
操作流程圖

數據類型圖
數字類型

時間日期類型

字符串類型

實例練習
1、Connection
public class JDBCUtil { //Driver類全名
public static String DRIVER="com.mysql.jdbc.Driver"; //jdbc協議:子協議://ip:端口號/數據庫名
public static String URL="jdbc:mysql://localhost:3306/test"; //數據庫用戶名
public static String USERNAME="root"; //數據庫密碼
public static String PASSWORD="root"; </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> Connection connection=<span style="color: #0000ff;">null</span><span style="color: #000000;">;
</span><span style="color: #008000;">/**</span><span style="color: #008000;">
* 獲取JDBC連接
* </span><span style="color: #808080;">@return</span>
<span style="color: #008000;">*/</span>
<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> Connection getConnection(){
</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
</span><span style="color: #008000;">//</span><span style="color: #008000;">加載驅動程序:它通過反射創建一個driver對象。</span>
Class.forName(DRIVER);
</span><span style="color: #008000;">//</span><span style="color: #008000;">獲得數據連接對象。
</span><span style="color: #008000;">//</span><span style="color: #008000;"> 在返回connection對象之前,DriverManager它內部會先校驗驅動對象driver信息對不對,我們只要知道內部過程即可。</span>
connection=<span style="color: #000000;"> DriverManager.getConnection(URL,USERNAME,PASSWORD);
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> connection;
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
e.printStackTrace();
}
</span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">;
}
</span><span style="color: #008000;">/**</span><span style="color: #008000;">
* 通過讀取文件連接
* </span><span style="color: #808080;">@param</span><span style="color: #008000;"> fileName
* </span><span style="color: #808080;">@return</span><span style="color: #008000;">
* </span><span style="color: #808080;">@throws</span><span style="color: #008000;"> SQLException
</span><span style="color: #008000;">*/</span>
<span style="color: #0000ff;">public</span> Connection getConnectionByLoadSettingFile(String fileName) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException {
</span><span style="color: #008000;">/*</span><span style="color: #008000;">
文件里面的內容:跟上面的常量一模一樣
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
</span><span style="color: #008000;">*/</span><span style="color: #000000;">
Properties props</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> Properties();
</span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
</span><span style="color: #008000;">//</span><span style="color: #008000;">我的properties文件是放在src根目錄下的</span>
InputStream in=DBUtil.<span style="color: #0000ff;">class</span>.getResourceAsStream("/"+<span style="color: #000000;">fileName);
</span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">null</span>==<span style="color: #000000;">in)
System.out.println(</span>"找不到文件:"+<span style="color: #000000;">fileName);
props.load(in);
} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
e.printStackTrace();
}
String driver</span>=props.getProperty("jdbc.driver"<span style="color: #000000;">);
</span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">null</span>!=<span style="color: #000000;">driver)
System.setProperty(</span>"jdbc.drivers"<span style="color: #000000;">,driver);
String url</span>=props.getProperty("jdbc.url"<span style="color: #000000;">);
String username</span>=props.getProperty("jdbc.username"<span style="color: #000000;">);
String password</span>=props.getProperty("jdbc.password"<span style="color: #000000;">);
connection</span>=<span style="color: #000000;">DriverManager.getConnection(url,username,password);
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> connection;
}
}
2、Statement
public class MyClient { public static void main(String [] args) throws SQLException { Connection connection=null; Statement statement=null; connection</span>=<span style="color: #000000;">JDBCUtil.getConnection();
statement</span>=<span style="color: #000000;">connection.createStatement();
</span><span style="color: #008000;">//</span><span style="color: #008000;">需要在自己的數據庫當中建立一張user表</span>
String sql="insert into user(loginName,userName,password,sex)values('tom123','tom','123456',1)"<span style="color: #000000;">;
statement.executeUpdate(sql);
}
}
3、PareparedStatement
public class MyClient { public static void main(String [] args) throws SQLException { Connection connection=null; PreparedStatement pStatement=null; connection</span>=<span style="color: #000000;">JDBCUtil.getConnection();
String sql</span>="insert into user(loginName,userName,password,sex)values(?,?,?,?)"<span style="color: #000000;">;
</span><span style="color: #008000;">//</span><span style="color: #008000;">預編譯</span>
pStatement=<span style="color: #000000;">connection.prepareStatement(sql);
</span><span style="color: #008000;">//</span><span style="color: #008000;">前面的索引對應上面的問號,傳遞參數。</span>
pStatement.setString(1,"tom123"<span style="color: #000000;">);
pStatement.setString(</span>2,"tom"<span style="color: #000000;">);
pStatement.setString(</span>3,"123456"<span style="color: #000000;">);
pStatement.setInt(</span>4,1<span style="color: #000000;">);
pStatement.executeUpdate();
}
}
4、ResultSet
public class MyClient { public static void main(String [] args) throws SQLException { Connection connection=null; Statement statement=null; ResultSet resultSet; connection</span>=<span style="color: #000000;">JDBCUtil.getConnection();
String sql</span>="select * from user"<span style="color: #000000;">;
statement</span>=<span style="color: #000000;">connection.createStatement();
</span><span style="color: #008000;">//</span><span style="color: #008000;">resultSet就是一個迭代器,里面的方法跟迭代器幾乎一致。</span>
resultSet=<span style="color: #000000;">statement.executeQuery(sql);
</span><span style="color: #0000ff;">while</span><span style="color: #000000;"> (resultSet.next()){
String loginName</span>=resultSet.getString("loginName"<span style="color: #000000;">);
String userName</span>=resultSet.getString("userName"<span style="color: #000000;">);
String password</span>=resultSet.getString("password"<span style="color: #000000;">);
</span><span style="color: #0000ff;">int</span> sex=resultSet.getInt("sex"<span style="color: #000000;">);
System.out.println(loginName</span>+"-"+userName+"-"+password+"-"+<span style="color: #000000;">sex);
}
}
}
四、可滾動和可更新的結果集
相關參數
//了解數據集可滾動更新:查看ResultSet接口的幾個參數
/** 結果集不能滾動(默認值)*/ int TYPE_FORWARD_ONLY = 1003;</span><span style="color: #008000;">/** 結果集可以滾動,但對數據庫變化不敏感</span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">int</span> TYPE_SCROLL_INSENSITIVE = 1004<span style="color: #000000;">; </span><span style="color: #008000;">/**結果集可以滾動,且對數據庫變化敏感</span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">int</span> TYPE_SCROLL_SENSITIVE = 1005<span style="color: #000000;">;
/**結果集不能用於更新數據庫(默認值)*/
int CONCUR_READ_ONLY = 1007;</span><span style="color: #008000;">/**結果集可以用於更新數據庫</span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">int</span> CONCUR_UPDATABLE = 1008<span style="color: #000000;">;
可滾動可更新
注意:可滾動簡單說就是設置結果集可更新resultSet目前的游標值。可更新就是可以更新結果集里面的增刪改查。可更新簡單說,就是獲取數據集ResultSet以后改動更加靈活。
public class Client { public static void main(String [] args){ Connection connection=null; PreparedStatement pStatement=null; Statement statement=null; ResultSet resultSet=null; try { connection=DBUtil.getInstance().getConnection(); //第一個參數設置是否可以滾動,第二個參數設置是否可更新 statement=connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE); String sql="select * from user"; ResultSet rs=statement.executeQuery(sql);</span><span style="color: #008000;">/**</span><span style="color: #008000;">可滾動的幾個方法 rs.previous(); rs.next(); rs.getRow(); rs.absolute(0); *</span><span style="color: #008000;">*/</span> <span style="color: #008000;">//</span><span style="color: #008000;">往數據集里面插入數據同時更新到數據:從表的最后開始插入。</span> rs.moveToInsertRow();<span style="color: #008000;">//</span><span style="color: #008000;">把游標移動到插入行,默認在最后一行。</span> rs.updateString("loginName","小白臉"<span style="color: #000000;">); rs.updateString(</span>"userName","大猩猩"<span style="color: #000000;">); rs.updateString(</span>"password","123"<span style="color: #000000;">); rs.updateInt(</span>"sex",100<span style="color: #000000;">); rs.insertRow(); rs.moveToCurrentRow();</span><span style="color: #008000;">//</span><span style="color: #008000;">把游標移動最后一個位置 </span><span style="color: #008000;">//</span><span style="color: #008000;">刪除第十行數據</span> rs.absolute(10<span style="color: #000000;">); rs.deleteRow(); </span><span style="color: #0000ff;">while</span><span style="color: #000000;">(rs.next()){ System.out.println(rs.getString(</span>2<span style="color: #000000;">)); </span><span style="color: #008000;">//</span><span style="color: #008000;">把數據集里的數據中的性別全部更新為0</span> rs.updateInt("sex",0<span style="color: #000000;">); rs.updateRow(); } } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (SQLException e) { e.printStackTrace(); } }}
五、事務
問題思考
事務是什么?我們將一組語句構成一個事務。當所有語句都是順利執行以后,事務可以被提交。否則,如果其中某個語句遇到錯誤,那么事務將被回滾,就好像任何語句都沒有被執行一樣。
實際用例。假設我們需要將錢從一個銀行賬號轉移到另外一個賬號。此時,一個非常重要的問題就是我們必須同時將錢從一個賬號取出並且存入另一個賬號。如果在將錢存入其他賬號之前系統發生崩潰,那么我們必須撤銷取款操作。
事務有什么特性或者說有什么作用?
- 原子性:最小的單元,如果一個是失敗了,則一切的操作將全部失敗。
- 一致性:如果事務出現錯誤,則回到最原始的狀態
- 隔離性:多個事務之間無法訪問,只有當事務完成后才可以看到結果
- 持久性:當一個系統崩潰時,一個事務依然可以提交,當事務完成后,操作結果保存在磁盤中,不會被回滾
保存點與批量更新
保存點與事務的接口源碼
public interface Connection extends Wrapper, AutoCloseable { /** 設置提交方式:自動還是手動*/ void setAutoCommit(boolean autoCommit) throws SQLException;</span><span style="color: #0000ff;">boolean</span> getAutoCommit() <span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException; </span><span style="color: #008000;">/**</span><span style="color: #008000;">提交事務</span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">void</span> commit() <span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException;/**事務回滾*/
void rollback() throws SQLException;</span><span style="color: #008000;">/**</span><span style="color: #008000;">設置保存點</span><span style="color: #008000;">*/</span><span style="color: #000000;"> Savepoint setSavepoint() </span><span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException; Savepoint setSavepoint(String name) </span><span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException; </span><span style="color: #008000;">/**</span><span style="color: #008000;">回滾到保存點</span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">void</span> rollback(Savepoint savepoint) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException; </span><span style="color: #008000;">/**</span><span style="color: #008000;">釋放保存點資源</span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">void</span> releaseSavepoint(Savepoint savepoint) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException;}
public interface Statement extends Wrapper, AutoCloseable {
/**加入到批量處理隊列*/
void addBatch( String sql ) throws SQLException;</span><span style="color: #0000ff;">void</span> clearBatch() <span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException; </span><span style="color: #008000;">/**</span><span style="color: #008000;">執行批量處理隊列</span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">int</span>[] executeBatch() <span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException;}
什么是保存點?使用保存點可以更細粒度地控制回滾操作,而不用每次都退回到初始點。
什么又是批量更新?批量更新包括批量增刪改,當我們一次性要插入很多條數據的時候,假設我們每次提交一次又獲取數據庫連接一次,然后又關閉數據庫連接,而且數據庫連接是一個耗時操作,這樣會大大降低性能,后續文章我會對這部分內容進行詳細敘述。而批量更新呢,則先把數據放入一個隊列里,並沒有真正存入數據庫中,當調用commit()方法的時候,隊列的數據的操作一次性收集和提交。
public class Client { public static void main(String [] args) throws SQLException { long time=System.currentTimeMillis(); Connection connection=null; PreparedStatement pStatement=null; boolean autoCommit=false; Savepoint savepoint=null; try { connection=JDBCUtil.getConnection(); autoCommit=connection.getAutoCommit(); connection.setAutoCommit(false); String sql="insert into user(loginName,userName,password,sex)values(?,?,?,?)"; pStatement=connection.prepareStatement(sql); //設置保存點 savepoint=connection.setSavepoint("savePoint"); for(int i=0;i<1000;i++){ pStatement.setString(1,"tony"+i); pStatement.setString(2,"user"+i); pStatement.setString(3,i+""); pStatement.setInt(4,i); //添加到隊列 pStatement.addBatch(); } //批量執行 pStatement.executeBatch(); connection.commit();} </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (SQLException e) { e.printStackTrace(); </span><span style="color: #008000;">//</span><span style="color: #008000;">回滾到保存點</span>connection.rollback(savepoint);
}finally {
//把事務提交設置為最初設置
connection.setAutoCommit(autoCommit);
}
long temp=System.currentTimeMillis()-time;
System.out.println(temp+"ms");
}
}
六、思考與總結
思考
- 問題一:我們都知道獲取JDBC連接是一個耗時操作。而我們查看教程的時候,提倡我們獲取數據庫連接,操作完畢以后要記得關閉,這樣固然是正確的。但是,如果一個簡單的操作就不停開啟連接斷開連接,這樣會對性能大打折扣。
- 問題二:JDBC的工作原理?還有它底部運用什么設計模式,讓它能夠自適應不同數據庫產商的驅動呢?
- 問題三:事務提交和普通提交的性能到底有多大的差別?
總結
解決一:有一個概念叫做連接池,就是數據庫連接這個耗時操作交個一個容器去管理。至於數據庫什么時候連接什么時候被關閉,有幾個數據庫連接對象?這些完全托管給連接池,而不需要客戶端去考慮,目前一個比較成熟的是c3p0的連接池。現在模擬一個單例的數據庫連接,比較單例數據庫連接與隨開隨關的性能比較。
工具類
public class DBUtil { public static String DRIVER="com.mysql.jdbc.Driver"; public static String URL="jdbc:mysql://localhost:3306/test"; public static String USERNAME="root"; public static String PASSWORD="root";</span><span style="color: #0000ff;">private</span> Connection connection=<span style="color: #0000ff;">null</span><span style="color: #000000;">; </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> DBUtil(){ } </span><span style="color: #008000;">/**</span><span style="color: #008000;"> * 獲得DB工具類的對象,這種獲取對象的方式慢慢被jdk推薦使用。 </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> DBUtil getInstance(){ </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> DBUtilClassInstance.dbUtil; } </span><span style="color: #008000;">/**</span><span style="color: #008000;"> * 采用內部類單例模式:天然線程安全,延遲加載,調用效率高。若不了解,參考我的文章設計模式-單例模式 </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> DBUtilClassInstance{ </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">static</span> DBUtil dbUtil= <span style="color: #0000ff;">new</span><span style="color: #000000;"> DBUtil(); } </span><span style="color: #008000;">/**</span><span style="color: #008000;"> * 獲取JDBC連接 * </span><span style="color: #808080;">@return</span> <span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span><span style="color: #000000;"> Connection getConnection(){ </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> { </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">null</span>!=connection && !<span style="color: #000000;">connection.isClosed()){ </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> connection; } Class.forName(DRIVER); System.out.println(</span>"驅動程序加載成功!"<span style="color: #000000;">); connection</span>=<span style="color: #000000;">DriverManager.getConnection(URL,USERNAME,PASSWORD); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> connection; } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) { System.out.println(</span>"未找到驅動程序!"<span style="color: #000000;">); e.printStackTrace(); } </span><span style="color: #0000ff;">return</span> <span style="color: #0000ff;">null</span><span style="color: #000000;">; } </span><span style="color: #008000;">/**</span><span style="color: #008000;"> * 通過讀取文件連接 * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> fileName * </span><span style="color: #808080;">@return</span><span style="color: #008000;"> * </span><span style="color: #808080;">@throws</span><span style="color: #008000;"> SQLException </span><span style="color: #008000;">*/</span> <span style="color: #0000ff;">public</span> Connection getConnectionByLoadSettingFile(String fileName) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> SQLException { </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">null</span>!=connection && !<span style="color: #000000;">connection.isClosed()){ </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> connection; } Properties props</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> Properties(); </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> { InputStream in</span>=DBUtil.<span style="color: #0000ff;">class</span>.getResourceAsStream("/"+<span style="color: #000000;">fileName); </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">null</span>==<span style="color: #000000;">in) System.out.println(</span>"找不到文件:"+<span style="color: #000000;">fileName); props.load(in); } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) { e.printStackTrace(); } String driver</span>=props.getProperty("jdbc.driver"<span style="color: #000000;">); </span><span style="color: #0000ff;">if</span>(<span style="color: #0000ff;">null</span>!=<span style="color: #000000;">driver) System.setProperty(</span>"jdbc.drivers"<span style="color: #000000;">,driver); String url</span>=props.getProperty("jdbc.url"<span style="color: #000000;">); String username</span>=props.getProperty("jdbc.username"<span style="color: #000000;">); String password</span>=props.getProperty("jdbc.password"<span style="color: #000000;">); connection</span>=<span style="color: #000000;">DriverManager.getConnection(url,username,password); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> connection; }<br /></span></pre>
性能比較
public class Client { public static void main(String [] args){ long time=System.currentTimeMillis(); for(int i=0;i<100;i++){ User user=new User("loginName"+i,"userName"+i,"password"+i,i); myThread thread=new myThread(user); thread.run(); } System.out.println(System.currentTimeMillis()-time+"ms"); } }class myThread implements Runnable{
</span><span style="color: #0000ff;">private</span><span style="color: #000000;"> User user; </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> myThread(User user){ </span><span style="color: #0000ff;">this</span>.user=<span style="color: #000000;">user; } </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() { PreparedStatement pStatement</span>=<span style="color: #0000ff;">null</span><span style="color: #000000;">; Connection connection</span>=<span style="color: #0000ff;">null</span><span style="color: #000000;">; </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> { connection</span>=DBUtil.getInstance().getConnectionByLoadSettingFile("db.properties"<span style="color: #000000;">); String sql</span>="insert into user(loginName,userName,password,sex)value(?,?,?,?)"<span style="color: #000000;">; pStatement</span>=<span style="color: #000000;">connection.prepareStatement(sql); pStatement.setString(</span>1<span style="color: #000000;">,user.getLoginName()); pStatement.setString(</span>2<span style="color: #000000;">,user.getUserName()); pStatement.setString(</span>3<span style="color: #000000;">,user.getPassword()); pStatement.setInt(</span>4<span style="color: #000000;">,user.getSex()); pStatement.executeUpdate(); } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) { e.printStackTrace(); }</span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> { </span><span style="color: #008000;">//</span><span style="color: #008000;">注釋掉這個方法就是代表數據庫連接用完就隨即關閉。</span>DBUtil.getInstance().closePreparedStatement(pStatement);
DBUtil.getInstance().closeConnection(connection);
}
}
}
測試結果
隨開隨關:7155ms。單例模式,最后一個數據庫操作完畢再關閉:6211ms。
連接池的原理參考:http://www.cnblogs.com/doudouxiaoye/p/5708854.html
解決二:在后續文章再介紹JDBC運用的設計模式以及部分源碼分析,敬請期待。
解決三:事務提交耗時測試(代碼參考事務批量處理部分,不再重復寫)。
測試結果:單例模式,最后一個數據操作完成關閉批量更新耗時:69863ms。事務方式批量更新耗時:682ms。
