javaweb數據庫連接池簡介入門
一、應用場景
web應用中,用戶每次請求都需要向數據庫獲得鏈接,而數據庫創建連接通常需要消耗相對較大的資源,創建時間也較長。假設網站一天10萬訪問量,數據庫服務器就需要創建10萬次連接,極大的浪費數據庫的資源,并且極易造成數據庫服務器內存溢出、拓機。所以這里使用數據庫連接池來避免這種問題。
簡單的理解其原理:
1、連接池里面已經有了很多和數據庫的連接,用戶訪問的時候,直接在池子中拿連接就好了,服務器就不需要創建連接了
2、內部維護一個list,當用戶調用conn.close()的時候,這個conn對象是不被銷毀,而是放入到list中的,為了達到這種效果,我們 需要自定義一個連接池(數據源)。
在這個數據源中,getConnection就是從list中拿到一個連接close就是將連接放回list中
二、編寫數據庫連接池
DataSource sun定義的標準的數據源
編寫連接池需實現javax.sql.DataSource接口。DataSource接口中定義了兩個重載的getConnection方法:
Connection getConnection()
Connection getConnection(String username, String password)
實現DataSource接口,并實現連接池功能的步驟:
1、在DataSource構造函數中批量創建與數據庫的連接,并把創建的連接加入LinkedList對象中。
2、實現getConnection方法,讓getConnection方法每次調用時,從LinkedList中取一個Connection返回給用戶。
3、當用戶使用完Connection,調用Connection.close()方法時,Collection對象應保證將自己返回到LinkedList中,而不要把conn還給數據庫。
Connection保證將自己返回到LinkedList中是此處編程的難點。
三、開源數據源簡介
DBCP:Apache commons 。
核心類BasicDataSourceFactory與BasicDataSource類
通過BasicDataSourceFactory.createDataSource(props)可得到BasicDataSource對象。
DBCP依賴的2個jar包
Commons-dbcp.jar:連接池的實現
Commons-pool.jar:連接池實現的依賴庫
使用步驟:
a、寫配置文件(properties中要存unicode編碼,可用jdk bin中native2ascii.exe)
在配置文件中寫一些基本參數,比如連接哪個數據庫等
b、寫工具類(見代碼DbcpUtil.java)
c、測試一下(DBCPDemo1.java)
C3P0:一個開源組織弄出來的優秀的數據庫連接池框架。核心類是ComboPooledDataSource類。此類實現了javax.sql.DataSource接口的且還可以直接new出來,只需要在類根路徑下有c3p0-config.xml文件即可自動的讀取相關的配置信息。
使用C3P0你需要拷貝3個jar包,其中一個是oracle數據庫的。
c3p0.jar、c3p0-jdk1.3.jar及c3p0-oracle-thin-extras.jar
可以使用多種文件作為配置文件(作為配置文件有命名要求,也有存放要求,閱讀doc文檔)
一個配置文件可以配置多個連接池,可以應付不同的開發階段(開發階段,使用階段),見xml文件
四、管理數據源
Tomcat管理數據源(訪問tomcat服務器,看tomcat幫助文檔)
1、先把數據庫的驅動拷貝的Tomcat目錄\lib目錄中(mysql-connector-java-5.0.8.jar)。其實內部是用dbcp數據庫來實現的,所以不需要拷貝數據源依賴的jar包。Tomcat lib默認就帶著這些jar包。
JNDI:Java Naming and Directrory Interface Java命名與目錄服務
把JNDI想成一個大的Map<String,Object>容器。JNDI容器。從容器中取對象需要用到JNDI的API 。JNDI的API在JDK的javax.naming.*包中
2、在應用的META-INF目錄下建立一個名字為context.xml的配置文件。
- <?xml version="1.0" encoding="UTF-8"?>
- <Context>
- <Resource name="jdbc/datasource" auth="Container" type="javax.sql.DataSource"
- maxActive="100" maxIdle="30" maxWait="10000"
- username="root" password="sorry" driverClassName="com.mysql.jdbc.Driver"
- url="jdbc:mysql://localhost:3306/test"/>
- </Context>
3、在應用中使用JNDI的API獲取名字叫做jdbc/datasource的資源
- Context ctxt = new InitialContext();
- DataSource ds = (DataSource)ctxt.lookup("java:/comp/env/jdbc/datasource");
- Connection conn = ds.getConnection();
- System.out.print(conn);
附:dbcp數據池,dbcpconfig.properties配置文件,需要用流讀取此配置文件load到properties對象中,然后BasicDataSourceFactory.createDataSource(props)就可創建數據源了。
dbcpconfig.properties內容如下:
- #連接設置
- driverClassName=com.mysql.jdbc.Driver
- url=jdbc:mysql://localhost:3306/test
- username=root
- password=chen
- #<!-- 初始化連接 -->
- initialSize=10
- #最大連接數量
- maxActive=50
- #<!-- 最大空閑連接 -->
- maxIdle=20
- #<!-- 最小空閑連接 -->
- minIdle=5
- #<!-- 超時等待時間以毫秒為單位 6000毫秒/1000等于60秒 -->
- maxWait=60000
- #JDBC驅動建立連接時附帶的連接屬性屬性的格式必須為這樣:[屬性名=property;]
- #注意:"user" 與 "password" 兩個屬性會被明確地傳遞,因此這里不需要包含他們。
- connectionProperties=useUnicode=true;characterEncoding=utf8
- #指定由連接池所創建的連接的自動提交(auto-commit)狀態。
- defaultAutoCommit=true
- #driver default 指定由連接池所創建的連接的只讀(read-only)狀態。
- #如果沒有設置該值,則“setReadOnly”方法將不被調用。(某些驅動并不支持只讀模式,如:Informix)
- defaultReadOnly=
- #driver default 指定由連接池所創建的連接的事務級別(TransactionIsolation)。
- #可用值為下列之一:(詳情可見javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
- defaultTransactionIsolation=REPEATABLE_READ
c3p0的配置文件c3p0-config.xml內容如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <c3p0-config>
- <default-config>
- <property name="driverClass">com.mysql.jdbc.Driver</property>
- <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/test</property>
- <property name="user">root</property>
- <property name="password">chen</property>
- <property name="initialPoolSize">10</property>
- <property name="maxIdleTime">30</property>
- <property name="maxPoolSize">40</property>
- <property name="minPoolSize">10</property>
- <property name="maxStatements">200</property>
- </default-config> <!-- This app is massive! -->
- <named-config name="day14">
- <property name="driverClass">com.mysql.jdbc.Driver</property>
- <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/test</property>
- <property name="user">root</property>
- <property name="password">chen</property>
- <property name="initialPoolSize">10</property>
- <property name="maxIdleTime">30</property>
- <property name="maxPoolSize">40</property>
- <property name="minPoolSize">10</property>
- <property name="maxStatements">200</property>
- </named-config>
- </c3p0-config>