什么是BoneCP
BoneCP 是一個快速、免費而且開源的java數據庫連接池(JDBC Pool)管理工具庫。如果你曾經使用過C3P0或者DBCP,那你肯定知道上面這句話的意思;如果你沒用過這些,那簡單的解釋一下,它是一個能為你的應用管理數據庫連接的工具。
官方網站:http://jolbox.com/
為什么要學習BoneCP
本着不重復發明輪子的原則,不應該在有了C3P0這種成熟的數據庫連接池管理工具后再搞個新的出來,但是傳說中BoneCP在快速這個特點上做到了極致,官方數據是C3P0等的25倍左右。不相信?其實我也不怎么信,正找時間自己寫測試類測試呢,你也可以去試試看, 在這里下載 (現在最新版本0.6.7.2,如果你有困難,下面會具體提到在項目中怎么配置)
好吧,先看一下官方給出的華麗數據:
1. 單線程(1,000,000獲得及釋放數據庫連接請求,連接池大小20-50)
2. 多線程(500線程分別獲取釋放100個鏈接,連接池大小50-200)
3. Prepared Statement (multi-threaded)(500個線程每個100次獲得/釋放,連接池大小20-500)
這里只應用了部分,還有其他比較多的測試數據,有興趣就去這里 瞧瞧吧。個人還是建議自己寫點代碼測試一下,那樣感受更深啊。
在介紹怎么使用之前,先來看看BoneCP的特性(Features ):
- 高度可擴展, 快速的連接池. 注:1)不用synchronized 關鍵字來處理多線程對資源的爭用,而是使用 java.util.concurrent 包中的鎖機制;2)首次使用分區機制來分開管理數據庫連接;或許還有其他原因.
- Callback (hook interceptor) mechanisms on a change of connection state.
- 利用分區技術提高性能
- 允許直接訪問一個連接或者語句
- 智能調整連接池大小
- SQL語句緩存支持
- 支持異步獲取數據庫連接 (通過返回Future<Connection>的形式)
- 通過釋放連接助理進程來釋放數據庫連接,提高性能.
- 通過initSQL參數在每次獲取連接的時候執行SQL
- 支持數據庫熱切換
- 自動重試失敗的數據庫操作(當數據庫或者網絡掛掉的時候)
- JMX support
- 延遲初始化能力(Lazy initialization capable)
- 自動檢測連接可用性 (keep-alives 等)
- 允許直接通過數據源而不是通過驅動來獲取一個新的數據庫連接(Allow obtaining of new connections via a datasource rather than via a Driver)
- Datasource/Hibernate support capable
- Debug支持准確地高亮那些已經得到但是還沒有關閉的鏈接(Debugging hooks to highlight the exact place where a connection was obtained but not closed)
- Debug支持展示那些被關閉兩次的鏈接地址堆棧信息(Debugging support to show stack locations of connections that were closed twice. )
- 支持自定義連接池名稱.
- 干凈的代碼結構,TestCase代碼覆蓋率達到100% (over 125 JUnit tests).
- 免費的,開源的而且都是用java干的,最重要的是有很完整的javadocs支持。(Free, open source and written in 100% pure Java with complete Javadocs).
本人鳥語有限,有些翻譯不是很好,請見諒
好了,廢話說的挺多的,看看到底怎么用吧。
怎么使用BoneCP
我是Maven的忠實擁護者,如果你也是,那就簡單了:
你可以在你的settings.xml文件里加上下面一段,聲明一個Maven倉庫,如果你不想影響其他項目,那也可以在你項目的pom.xml文件里面加。
- <repositories>
- <repository>
- <releases>
- <enabled>true</enabled>
- </releases>
- <id>bonecp-repo</id>
- <name>BoneCP Repository</name>
- <url>http://jolbox.com/bonecp/downloads/maven</url>
- </repository>
- </repositories>
然后你就可以像引用其他jar包一樣引用bonecp了,下面應該很熟悉
- <dependency>
- <groupId>com.jolbox</groupId>
- <artifactId>bonecp</artifactId>
- <version>0.6.7.2</version>
- </dependency>
如果你的項目直接用類似Hibernate的東東,沒有配置dataSource的話,你很牛,那就加上下面這個吧
- <dependency>
- <groupId>com.jolbox</groupId>
- <artifactId>bonecp-provider</artifactId>
- <version>0.6.7.2</version>
- </dependency>
如果這些都沒有滿足你,那參考這里 吧。
如果你不用Spring,那應該是這樣寫吧:
- Class.forName("org.hsqldb.jdbcDriver"); // load the DB driver
- BoneCPConfig config = new BoneCPConfig(); // create a new configuration object
- config.setJdbcUrl("jdbc:hsqldb:mem:test"); // set the JDBC url
- config.setUsername("sa"); // set the username
- config.setPassword(""); // set the password
- config.setXXXX(...); // (other config options here)
- BoneCP connectionPool = new BoneCP(config); // setup the connection pool
- Connection connection;
- connection = connectionPool.getConnection(); // fetch a connection
- ... do something with the connection here ...
- connection.close(); // close the connection
- connectionPool.shutdown(); // close the connection pool
BoneCP-Spring詳細配置
主要講一下在Spring下面怎么配置,其實更簡單,只要配置dataSrouce就可以搞定。如下,具體含義見注釋。
- <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"
- destroy-method="close">
- <!-- 數據庫驅動 -->
- <property name="driverClass" value="${aliLibrary.db.driverClass}" />
- <!-- 相應驅動的jdbcUrl,你懂的 -->
- <property name="jdbcUrl" value="${aliLibrary.db.jdbcUrl}" />
- <!-- 數據庫的用戶名 -->
- <property name="username" value="${aliLibrary.db.username}" />
- <!-- 數據庫的密碼 -->
- <property name="password" value="${aliLibrary.db.password}" />
- <!-- 檢查數據庫連接池中空閑連接的間隔時間,單位是分,默認值:240,如果要取消則設置為0 -->
- <property name="idleConnectionTestPeriod" value="${aliLibrary.db.idleConnectionTestPeriod}" />
- <!-- 連接池中未使用的鏈接最大存活時間,單位是分,默認值:60,如果要永遠存活設置為0 -->
- <property name="idleMaxAge" value="${aliLibrary.db.idleMaxAge}" />
- <!-- 每個分區最大的連接數 -->
- <property name="maxConnectionsPerPartition" value="${aliLibrary.db.maxConnectionsPerPartition}" />
- <!-- 每個分區最小的連接數 -->
- <property name="minConnectionsPerPartition" value="${aliLibrary.db.minConnectionsPerPartition}" />
- <!-- 分區數 ,默認值2,最小1,推薦3-4,視應用而定-->
- <property name="partitionCount" value="${aliLibrary.db.partitionCount}" />
- <!-- 每次去拿數據庫連接的時候一次性要拿幾個,默認值:2 -->
- <property name="acquireIncrement" value="${aliLibrary.db.acquireIncrement}" />
- <!-- 緩存prepared statements的大小,默認值:0 -->
- <property name="statementsCacheSize" value="${aliLibrary.db.statementsCacheSize}" />
- <!-- 每個分區釋放鏈接助理進程的數量,默認值:3,除非你的一個數據庫連接的時間內做了很多工作,不然過多的助理進程會影響你的性能 -->
- <property name="releaseHelperThreads" value="${aliLibrary.db.releaseHelperThreads}" />
- </bean>
其他還有些不是很常用的包括:
- connectionTestStatement:在做keep-alive的時候的SQL語句。
- statementsCachedPerConnection:No of statements that can be cached per connection,反正源碼中不推薦使用,就別用了.
- initSQL:在每次到數據庫取連接的時候執行的SQL語句,只執行一次。
- closeConnectionWatch:如果設置為true,則會增加一個線程監控關閉連接時的情況,如果關閉時出現異常,則打出錯誤日志,主要用於debug。上線后記得關掉。
- logStatementsEnabled:如果設置為true,就會打印執行的SQL語句,如果你用了其他能打印SQL語句的框架,那就不必了。
- acquireRetryDelay:在獲取連接失敗后,第二次參試前的延遲時間,默認為7000毫秒。
- acquireRetryAttempts:在獲取連接失敗后的重試次數,默認為5次。
- lazyInit:如果設置為true,那么連接池不會自動創建最小連接數的鏈接,而是保持為空,直到有需求要獲取連接。
- transactionRecoveryEnabled:如果設置為true,則會保存該鏈接上的所有活動,以備下次重試的時候使用,這里指的活動是數據庫操作。
- connectionHookClassName:Connection hook class name.沒看懂…
- poolName:上面特性中說到的自定義連接池名稱。
- disableJMX:控制JMX的支持開關。
- connectionTimeout:獲取連接的時候最大的等待時間,默認值為:Long.MAX_VALUE
Spring里面怎么用這個dataSource就不說了吧,今天重點在BoneCP。
最后跑一個TestCase,看看日志
初始化的時候打印出BoneCP的配置參數,很清楚,關閉的時候也有日志輸出。
- 2010-08-02 15:10:22,457 [BoneCPDataSource.java:121] [com.jolbox.bonecp.BoneCPDataSource] DEBUG com.jolbox.bonecp.BoneCPDataSource :: JDBC URL = jdbc:mysql://10.249.128.109:3306/ali_library, Username = root, partitions = 3, max (per partition) = 3, min (per partition) = 3, helper threads = 3, idle max age = 240 min, idle test period = 30 min
- 2010-08-02 15:10:22,457 [BoneCPDataSource.java:121] [com.jolbox.bonecp.BoneCPDataSource] DEBUG com.jolbox.bonecp.BoneCPDataSource :: JDBC URL = jdbc:mysql://10.249.128.109:3306/ali_library, Username = root, partitions = 3, max (per partition) = 3, min (per partition) = 3, helper threads = 3, idle max age = 240 min, idle test period = 30 min
- 2010-08-02 15:10:45,958 [BoneCP.java:129] [com.jolbox.bonecp.BoneCP] INFO com.jolbox.bonecp.BoneCP :: Shutting down connection pool...
- 2010-08-02 15:10:45,958 [BoneCP.java:129] [com.jolbox.bonecp.BoneCP] INFO com.jolbox.bonecp.BoneCP :: Shutting down connection pool...
- 2010-08-02 15:10:45,973 [BoneCP.java:145] [com.jolbox.bonecp.BoneCP] INFO com.jolbox.bonecp.BoneCP :: Connection pool has been shutdown.
- 2010-08-02 15:10:45,973 [BoneCP.java:145] [com.jolbox.bonecp.BoneCP] INFO com.jolbox.bonecp.BoneCP :: Connection pool has been shutdown.
接下去會寫點代碼橫向對比一下C3p0與BoneCP的相關點。