<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                轉載請注明出處:[http://blog.csdn.net/xiaojimanman/article/details/43272993](http://blog.csdn.net/xiaojimanman/article/details/43272993) 通過java程序去連接數據庫時,使用的協議是TCP/IP協議,TCP/IP協議需要進行3次握手。如果每一次數據庫操作都需要創建一個新的連接,都要進行3次握手,這是十分浪費資源的,程序的效率也不是很高。為了解決這個問題,我們想可不可以自己維護一些數據庫連接,需要數據庫操作的時候,直接使用這其中的一個連接,用完了,在還給它,這樣的話就不需要每次數據庫操作都創建一個新的連接了。這種思維模式就是今天的博客主題數據庫連接池。 ? ? ?? **基本原理** 連接池技術的核心思想是:連接復用,通過建立一個數據庫連接池以及一套連接使用、分配、管理策略,使得該連接池中的連接可以得到高效、安全的復用,避免了數據庫連接頻繁建立、關閉的開銷。另外,由于對JDBC中的原始連接進行了封裝,從而方便了數據庫應用對于連接的使用(特別是對于事務處理),提高了開發效率,也正是因為這個封裝層的存在,隔離了應用的本身的處理邏輯和具體數據庫訪問邏輯,使應用本身的復用成為可能。連接池主要由三部分組成(如下圖所示):連接池的建立、連接池中連接的使用管理、連接池的關閉。 ![](https://box.kancloud.cn/2016-02-22_56ca7bef73740.jpg) ? ? ?? **連接池實現** 這里的介紹的連接池是proxool,這里對其做了進一步的封裝,使數據庫操作更加簡單。 **DBPool** DBPool類用于指定數據庫連接池的配置文件,源程序如下: ~~~ /** *@Description: 數據庫連接池配置 */ package com.lulei.db.manager; import org.apache.log4j.Logger; import com.lulei.util.ClassUtil; public class DBPool { private static DBPool dbPool = null; private String poolPath; private static Logger log = Logger.getLogger(DBPool.class); private static String path = ClassUtil.getClassRootPath(DBPool.class); public static DBPool getDBPool(){ if (dbPool == null){ synchronized(DBPool.class){ if (dbPool == null){ dbPool = new DBPool(); } } } return dbPool; } private DBPool(){ } /** * @param poolPath * @Author: lulei * @Description: 設置數據庫連接池配置文件路徑 */ public void setPoolPath(String poolPath){ this.poolPath = poolPath; } /** * @return * @Author: lulei * @Description: 返回數據庫連接池配置文件路徑 */ protected String getPoolPath(){ //如果沒有指定配置文件,則使用默認配置文件 if (poolPath == null){ poolPath = path + "proxool.xml"; log.info("Database's poolpath is null, use default path:" + poolPath); } return poolPath; } } ~~~ 在配置文件中,參數介紹如下: fatal-sql-exception: 它是一個逗號分割的信息片段.當一個SQL異常發生時,他的異常信息將與這個信息片段進行比較.如果在片段中存在,那么這個異常將被認為是個致命錯誤(Fatal SQL Exception ).這種情況下,數據庫連接將要被放棄.無論發生什么,這個異常將會被重擲以提供給消費者.用戶最好自己配置一個不同的異常來拋出. fatal-sql-exception-wrapper-class:正如上面所說,你最好配置一個不同的異常來重擲.利用這個屬性,用戶可以包裝SQLException,使他變成另外一個異常.這個異常或者繼承SQLException或者繼承字RuntimeException.proxool自帶了2個實現:'org.logicalcobwebs.proxool.FatalSQLException' 和'org.logicalcobwebs.proxool.FatalRuntimeException' .后者更合適. house-keeping-sleep-time: house keeper 保留線程處于睡眠狀態的最長時間,house keeper 的職責就是檢查各個連接的狀態,并判斷是否需要銷毀或者創建. house-keeping-test-sql: ?如果發現了空閑的數據庫連接.house keeper 將會用這個語句來測試.這個語句最好非常快的被執行.如果沒有定義,測試過程將會被忽略。 injectable-connection-interface: 允許proxool實現被代理的connection對象的方法. injectable-statement-interface: 允許proxool實現被代理的Statement 對象方法. injectable-prepared-statement-interface: 允許proxool實現被代理的PreparedStatement 對象方法. injectable-callable-statement-interface: 允許proxool實現被代理的CallableStatement 對象方法. jmx: 略 jmx-agent-id: 略 jndi-name: 數據源的名稱 maximum-active-time: 如果housekeeper 檢測到某個線程的活動時間大于這個數值.它將會殺掉這個線程.所以確認一下你的服務器的帶寬.然后定一個合適的值.默認是5分鐘. maximum-connection-count: 最大的數據庫連接數. maximum-connection-lifetime: 一個線程的最大壽命. minimum-connection-count: 最小的數據庫連接數 overload-without-refusal-lifetime: 略 prototype-count: 連接池中可用的連接數量.如果當前的連接池中的連接少于這個數值.新的連接將被建立(假設沒有超過最大可用數).例如.我們有3個活動連接2個可用連接,而我們的prototype-count是4,那么數據庫連接池將試圖建立另外2個連接.這和 minimum-connection-count不同. minimum-connection-count把活動的連接也計算在內.prototype-count 是spare connections 的數量. recently-started-threshold: ?略 simultaneous-build-throttle: ?略 statistics: ?連接池使用狀況統計。 參數“10s,1m,1d” statistics-log-level: ?日志統計跟蹤類型。 參數“ERROR”或 “INFO” test-before-use: 略 test-after-use: 略 trace: 如果為true,那么每個被執行的SQL語句將會在執行期被log記錄(DEBUG LEVEL).你也可以注冊一個ConnectionListener (參看ProxoolFacade)得到這些信息. verbose: 詳細信息設置。 參數 bool 值 在本例中數據庫連接池配置文件如下: ~~~ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <proxool-config> <proxool> <alias>novelSelect</alias> <driver-url><![CDATA[jdbc:mysql://172.20.37.73:3306/novel?characterEncoding=utf-8]]></driver-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <driver-properties> <property name="user" value="root"/> <property name="password" value="root"/> </driver-properties> <house-keeping-sleep-time>900000</house-keeping-sleep-time> <maximum-active-time>500000</maximum-active-time> <maximum-connection-count>40</maximum-connection-count> <minimum-connection-count>4</minimum-connection-count> <house-keeping-test-sql>select 1</house-keeping-test-sql> <prop key="hibernate.connection.release_mode">after_transaction</prop> </proxool> <proxool> <alias>novelEdit</alias> <driver-url><![CDATA[jdbc:mysql://172.20.37.73:3306/novel?characterEncoding=utf-8]]></driver-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <driver-properties> <property name="user" value="root"/> <property name="password" value="root"/> </driver-properties> <house-keeping-sleep-time>900000</house-keeping-sleep-time> <maximum-active-time>500000</maximum-active-time> <maximum-connection-count>10</maximum-connection-count> <minimum-connection-count>4</minimum-connection-count> <house-keeping-test-sql>select 1</house-keeping-test-sql> <prop key="hibernate.connection.release_mode">after_transaction</prop> </proxool> </proxool-config> ~~~ **DBManager** ? ? ? DBManager在系統中是單例模式,在初始化只需要簡單的兩句代碼: ~~~ JAXPConfigurator.configure(DBPool.getDBPool().getPoolPath(), false); Class.forName("org.logicalcobwebs.proxool.ProxoolDriver"); ~~~ ? ? ? 獲取數據庫連接也只是簡單的一句代碼: ~~~ return DriverManager.getConnection(poolName); ~~~ ? ? ? DBManager源代碼如下: ~~~ /** *@Description: 數據庫連接池管理 */ package com.lulei.db.manager; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import org.logicalcobwebs.proxool.configuration.JAXPConfigurator; public class DBManager { private static DBManager dBManager = null; private DBManager(){ try { JAXPConfigurator.configure(DBPool.getDBPool().getPoolPath(), false); Class.forName("org.logicalcobwebs.proxool.ProxoolDriver"); } catch (Exception e){ e.printStackTrace(); } } /** * @return DBManager * @Author: lulei * @Description: 獲取數據庫連接池管理對象 */ protected static DBManager getDBManager(){ if (dBManager == null){ synchronized(DBManager.class){ if (dBManager == null){ dBManager = new DBManager(); } } } return dBManager; } /** * @param poolName * @return Connection * @throws SQLException * @Author: lulei * @Description: 獲取數據庫鏈接 */ protected Connection getConnection(String poolName) throws SQLException{ return DriverManager.getConnection(poolName); } } ~~~ **DBOperation** 為了簡化數據庫的操作,對數據庫操作進行再一次封裝成DBOperation類。在setPres方法中,這里只做了幾種簡單的數據類型,關于其他復雜的數據類型可以根據項目需要添加。源代碼如下: ~~~ /** *@Description: 數據庫操作 */ package com.lulei.db.manager; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.HashMap; import org.apache.log4j.Logger; public class DBOperation { private static Logger log = Logger.getLogger(DBOperation.class); private Connection conn = null; private String poolName; /** * @param poolName */ public DBOperation(String poolName){ this.poolName = poolName; } /** * @throws SQLException * @Author: lulei * @Description: 獲取Connection */ private void open() throws SQLException{ this.conn = DBManager.getDBManager().getConnection(poolName); } /** * @Author: lulei * @Description: 關閉Connection */ public void close() { try { if (this.conn != null) { this.conn.close(); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * @param sql組裝的sql字符串 * @param params傳入的參數 * @throws SQLException * @throws ClassNotFoundException * @Author: lulei * @Description: 組裝PreparedStatement */ private PreparedStatement setPres(String sql, HashMap<Integer, Object> params) throws SQLException, ClassNotFoundException{ if (null != params) { if (0 < params.size()){ PreparedStatement pres = this.conn.prepareStatement(sql); for (int i = 1; i <= params.size(); i++){ if (params.get(i).getClass() == Class.forName("java.lang.String")){ pres.setString(i, params.get(i).toString()); } else if (params.get(i).getClass() == Class.forName("java.lang.Integer")){ pres.setInt(i, (Integer) params.get(i)); } else if (params.get(i).getClass() == Class.forName("java.lang.Boolean")){ pres.setBoolean(i, (Boolean) params.get(i)); } else if (params.get(i).getClass() == Class.forName("java.lang.Float")){ pres.setFloat(i, (Float) params.get(i)); } else if (params.get(i).getClass() == Class.forName("java.lang.Double")){ pres.setDouble(i, (Double) params.get(i)); } else if (params.get(i).getClass() == Class.forName("java.lang.Long")){ pres.setLong(i, (Long) params.get(i)); } else if (params.get(i).getClass() == Class.forName("java.sql.Date")){ pres.setDate(i, java.sql.Date.valueOf(params.get(i).toString())); } else { log.info("not found class : " + params.get(i).getClass().toString()); return null; } } return pres; } } return null; } /** * @param sql * @return int * @throws SQLException * @Author: lulei * @Description: executeUpdate */ protected int executeUpdate(String sql) throws SQLException{ this.open(); Statement state = this.conn.createStatement(); int re = state.executeUpdate(sql); return re; } /** * executeUpdate * @param sql * @param params * @return int * @throws SQLException * @throws ClassNotFoundException * @Author: lulei * @Description: */ protected int executeUpdate(String sql, HashMap<Integer, Object> params) throws SQLException, ClassNotFoundException{ this.open(); PreparedStatement pres = setPres(sql, params); int re = 0; if (null != pres) { re = pres.executeUpdate(); } return re; } /** * getGeneratedKeys * @param sql * @return ResultSet * @throws SQLException * @Author: lulei * @Description: */ protected ResultSet getGeneratedKeys(String sql) throws SQLException{ this.open(); Statement state = this.conn.createStatement(); state.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS); ResultSet re = state.getGeneratedKeys(); return re; } /** * getGeneratedKeys * @param sql * @param params * @return ResultSet * @throws SQLException * @throws ClassNotFoundException * @Author: lulei * @Description: */ protected ResultSet getGeneratedKeys(String sql, HashMap<Integer, Object> params) throws SQLException, ClassNotFoundException{ this.open(); PreparedStatement pres = setPres(sql, params); if (null != pres) { pres.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS); ResultSet re = pres.getGeneratedKeys(); return re; } return null; } /** * @param sql * @return ResultSet * @throws SQLException * @Author: lulei * @Description: executeQuery */ protected ResultSet executeQuery(String sql) throws SQLException{ this.open(); Statement state = this.conn.createStatement(); ResultSet re = state.executeQuery(sql); return re; } /** * @param sql * @param params * @return ResultSet * @throws SQLException * @throws ClassNotFoundException * @Author: lulei * @Description: executeQuery */ protected ResultSet executeQuery(String sql, HashMap<Integer, Object> params) throws SQLException, ClassNotFoundException{ this.open(); PreparedStatement pres = setPres(sql, params); if (null != pres) { ResultSet re = pres.executeQuery(); return re; } return null; } } ~~~ **DBServer** DBServer對數據庫的增刪該查操作進行進一步的細化,源代碼如下: ~~~ /** *@Description: 增刪改查四個數據庫操作接口 */ package com.lulei.db.manager; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; public class DBServer { private DBOperation dBOperation; /** * @param poolName * @Description: 在使用該類之前,請保證函數DBPool.getDBPool().setPoolPath()已經運行 */ public DBServer(String poolName){ dBOperation = new DBOperation(poolName); } /** * @Author: lulei * @Description: 釋放鏈接,在執行完數據庫操作,必須執行此命令 */ public void close(){ dBOperation.close(); } /** * @param table * @param columns * @param params * @return int * @throws SQLException * @throws ClassNotFoundException * @Author: lulei * @Description: insert 執行完此命令后,執行close()操作 */ public int insert(String table, String columns, HashMap<Integer, Object> params) throws SQLException, ClassNotFoundException{ String sql = insertSql(columns, table); return dBOperation.executeUpdate(sql, params); } /** * @param sql * @return int * @throws SQLException * @Author: lulei * @Description: insert 執行完此命令后,執行close()操作 */ public int insert(String sql) throws SQLException { return dBOperation.executeUpdate(sql); } /** * @param table * @param columns * @param params * @return ResultSet * @throws SQLException * @throws ClassNotFoundException * @Author: lulei * @Description: insertGetGeneratedKeys 執行完此命令后,執行close()操作 */ public ResultSet insertGetGeneratedKeys(String table, String columns, HashMap<Integer, Object> params) throws SQLException, ClassNotFoundException{ String sql = insertSql(columns, table); return dBOperation.getGeneratedKeys(sql, params); } /** * @param sql * @return ResultSet * @throws SQLException * @Author: lulei * @Description: insertGetGeneratedKeys 執行完此命令后,執行close()操作 */ public ResultSet insertGetGeneratedKeys(String sql) throws SQLException{ return dBOperation.getGeneratedKeys(sql); } /** * @param table * @param condition * @return int * @throws SQLException * @Author: lulei * @Description: delete 執行完此命令后,執行close()操作 */ public int delete(String table, String condition) throws SQLException{ if(null == table){ return 0; } String sql = "delete from " + table + " " + condition; return dBOperation.executeUpdate(sql); } /** * @param sql * @return int * @throws SQLException * @Author: lulei * @Description: delete 執行完此命令后,執行close()操作 */ public int delete(String sql) throws SQLException{ return dBOperation.executeUpdate(sql); } /** * @param columns * @param table * @param condition * @return ResultSet * @throws SQLException * @Author: lulei * @Description: select 執行完此命令后,執行close()操作 */ public ResultSet select(String columns, String table, String condition) throws SQLException { String sql = "select " + columns + " from " + table + " " + condition; return dBOperation.executeQuery(sql); } /** * @param sql * @return ResultSet * @throws SQLException * @Author: lulei * @Description: select 執行完此命令后,執行close()操作 */ public ResultSet select(String sql) throws SQLException{ return dBOperation.executeQuery(sql); } /** * @param table * @param columns * @param condition * @param params * @return int * @throws SQLException * @throws ClassNotFoundException * @Author: lulei * @Description: update 執行完此命令后,執行close()操作 */ public int update(String table, String columns, String condition, HashMap<Integer, Object> params) throws SQLException, ClassNotFoundException{ String sql = updateString(table, columns, condition); return dBOperation.executeUpdate(sql, params); } /** * @param sql * @return int * @throws SQLException * @Author: lulei * @Description: update 執行完此命令后,執行close()操作 */ public int update(String sql) throws SQLException{ return dBOperation.executeUpdate(sql); } /** * @param table * @param columns * @param condition * @return String * @Author: lulei * @Description: 組裝updateString */ private String updateString(String table, String columns, String condition) { if (null == columns || null == table) { return ""; } String[] column = columns.split(","); StringBuilder stringBuilder = new StringBuilder("update "); stringBuilder.append(table); stringBuilder.append(" set "); stringBuilder.append(column[0]); stringBuilder.append("=?"); for (int i = 1; i < column.length; i++){ stringBuilder.append(", "); stringBuilder.append(column[i]); stringBuilder.append("=?"); } stringBuilder.append(" "); stringBuilder.append(condition); return stringBuilder.toString(); } /** * @param columns * @param table * @return String * @Author: lulei * @Description: 組裝insertSql */ private String insertSql(String columns, String table){ if (null == columns || null == table) { return ""; } int colNum = columns.split(",").length; StringBuilder stringBuilder = new StringBuilder("insert into "); stringBuilder.append(table); stringBuilder.append(" ("); stringBuilder.append(columns); stringBuilder.append(") values (?"); for (int i = 1; i < colNum; i++) { stringBuilder.append(",?"); } stringBuilder.append(")"); return stringBuilder.toString(); } } ~~~ 下面是的使用事例是其他項目中的一個例子,這里可以簡單的看下,代碼如下: ~~~ public boolean support(String docNo){ DBServer dbServer = new DBServer(dbPoolName); String editTime = System.currentTimeMillis() + ""; String sql = "update " + SolutionTable.tableName + " set " + SolutionTable.support + "=" + SolutionTable.support + "+1, " + SolutionTable.editTime + "='"+ editTime+"' where " +SolutionTable.docNo + "='" + docNo + "'"; try { return dbServer.update(sql) > 0; } catch (SQLException e) { e.printStackTrace(); } finally { dbServer.close(); } return false; } ~~~ ps:最近發現其他網站可能會對博客轉載,上面并沒有源鏈接,如想查看更多關于 [基于lucene的案例開發](http://blog.csdn.net/xiaojimanman/article/category/2841877) 請[點擊這里](http://blog.csdn.net/xiaojimanman/article/category/2841877)。或訪問網址http://blog.csdn.net/xiaojimanman/article/category/2841877
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看