目標:l 掌握如何共用串連資料庫的代碼;l 掌握PrepareSatement的使用;l 掌握資料庫連接池的配置和使用;主要內容:l 通過對資料庫的訪問過程進行分析,把資料庫訪問過程封裝成DBBean;l 修改User.java中的根據頁碼查詢使用者的方法,使用DBBean完成對資料庫的操作;l 修改User.java中的添加使用者資訊的方法,使用DBBean完成對資料庫的操作;l 設定資料庫串連池;l 修改DBBean中串連資料庫的代碼,使用串連池完成串連1、 DBBean的編寫在前面的幾講中,有多個方法串連資料庫對資料庫進行操作,並且我們編寫代碼的過程中存在很多複製和粘貼,這意味著在各個方法中有很多代碼可以共用。那麼在串連資料庫的代碼中有過程是可以共用的?對資料庫操作的基本過程如下:l 載入驅動程式;l 建立串連;l 編寫SQL語句;l 建立語句對象;l 執行SQL語句;l 對結果進行處理;l 關閉相關對象。在上面的過程中,很多操作都是相同的,不同的方麵包括:不同的功能需要編寫不同的SQL語句,對結果的處理。對這個過程進行封裝,得到下面的代碼(封裝的方式有很多種):package javabean; import java.sql.*;import java.util.*;public class DBBean { private Connection con; private PreparedStatement stmt; private ResultSet rs; // 擷取連線物件 public Connection getConnection() throws Exception{ if(con == null){ // 指出串連資料庫所需要的驅動程式 Class.forName("oracle.jdbc.driver.OracleDriver"); // 建立與資料庫之間的串連 con = DriverManager.getConnection( "jdbc:oracle:thin:@192.168.0.170:1521:fhdn", "scott", "tiger"); } return con; } // 建立語句對象 public PreparedStatement getStatement(String sql) throws Exception{ con = getConnection(); stmt = con.prepareStatement(sql); return stmt; } // 執行有結果集的查詢 public ResultSet executeQuery(String sql,ArrayList paras) throws Exception{ stmt = getStatement(sql); if (paras != null) { Object o[] = paras.toArray(); for (int i = 0; i < o.length; i++) { if (o[i] instanceof String) { stmt.setString(i + 1, (String) o[i]); } } } return stmt.executeQuery(); } // 執行沒有結果集的查詢 public int executeUpdate(String sql,ArrayList paras) throws Exception{ stmt = getStatement(sql); if (paras != null) { Object o[] = paras.toArray(); for (int i = 0; i < o.length; i++) { if (o[i] instanceof String) { stmt.setString(i + 1, (String) o[i]); } } } return stmt.executeUpdate(); } // 關閉對象 public void close(){ try{ rs.close(); }catch(Exception e){} try{ stmt.close(); }catch(Exception e){} try{ con.close(); }catch(Exception e){} }}注意:因為採用先行編譯的語句對象,所以在執行SQL語句的時候需要提供參數,因為參數的個數不定,所以採用ArrayList對象進行封裝,而代碼中只對String類型的參數進行了處理,如果使用其它類型的參數,需要再編寫支援代碼。2、 修改getUserByPage方法使用DBBean中方法的基本過程如下:l 建立DBBean的對象;l 編寫SQL語句;l 封裝SQL語句需要的參數;l 執行SQL語句;l 關閉對象。 public ArrayList getUserByPage(int pageNo) { int number = 10; // 每一頁顯示的記錄數 int begin = (pageNo * number) - 9; int end = pageNo * number; int index = 1; DBBean db = new DBBean(); // 要返回的結果對象 ArrayList users = new ArrayList(); String sql = "select * from usertable"; ResultSet rs; try{ rs = db.executeQuery(sql,null); while (rs.next()) { // 在begin之前的記錄是不顯示的 if (index < begin) { index++; continue; } // 在end之後的記錄也不顯示 if (index > end) break; index++; String username = rs.getString(1); String userpass = rs.getString(2); // java.util.Date birthday = rs.getDate(3); // int age = rs.getInt(4); User user = new User(); user.setUsername(username); user.setUserpass(userpass); users.add(user); } }catch(Exception e){ e.printStackTrace(); }finally{ db.close(); } return users; }3、 修改addUser方法以addUser方法為例介紹具有參數的SQL語句的執行。基本訪問過程與2中介紹的相同,修改後的addUser方法的代碼如下:public boolean addUser() { DBBean db = new DBBean(); String sql = "insert into usertable values(?,?)"; ArrayList<String> paras = new ArrayList<String>(); paras.add(username); paras.add(userpass); int n=0; try{ n = db.executeUpdate(sql,paras); }catch(Exception e){ System.out.println(e.toString()); } db.close(); boolean b; // 表示添加成功與否 if (n > 0) b = true; else b = false; return b;}4、 使用串連池的好處在前面的例子中,對於每個使用者的每次訪問都要先建立資料庫連接,使用完之後釋放串連。如果能夠讓使用者多次訪問之間共用資料庫串連,則可以大幅度提供訪問的效率。可以使用資料庫連接處完成串連的共用,在伺服器啟動的時候,建立多個串連,如果使用者需要訪問資料庫,直接從串連池中得到一個串連使用,使用完之後直接放回串連池。使用串連池的另外一個好處是,如果用戶端太多,串連池可以通過控制串連的數量來保護資料庫伺服器,不會讓資料庫的響應變得非常緩慢,從而影響伺服器的效能。5、 Tomcat中串連池的配置串連池的配置包括3個部分:l 把資料庫JDBC驅動程式放到Tomcat安裝目錄的lib下面。有些版本的Tomcat應該放在安裝目錄的common/lib下面。l 配置安裝目錄下的conf/server.xml開啟server.xml檔案,在</host>之前添加如下代碼:<Context path="/ch10" docBase="ch10" debug="5" reloadable="true" crossContext="true"> <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="scott" password="tiger" driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@myserver:1521:mydb"/>path是應用的訪問路徑,docBase是應用的根目錄,Resource其他紅色部分分別是使用者名稱、口令、驅動程式和url。</Context>l 配置工程的web.xml檔案在web.xml中添加如下代碼。注意:元素res-ref-name的值應該和前面配置的Resource的名字相同。 <resource-ref> <description>DB Connection</description> <res-ref-name>jdbc/TestDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>6、 在Java代碼中使用串連池修改DBBean.java中的getConnection方法,修改後的代碼如下:public Connection getConnection() throws Exception{ if (con == null) { Context initContext = new InitialContext(); Context envContext = (Context) initContext.lookup("java:/comp/env"); DataSource ds = (DataSource) envContext.lookup("jdbc/TestDB"); con = ds.getConnection(); } return con;}注意:在類頭需要引入javax.sql包和javax.naming包。7、運行代碼進行測試。
參考教材:《Java Web程式設計基礎教程》