一尸昧、開源數(shù)據(jù)庫(kù)連接池
現(xiàn)在很多web服務(wù)器都提供了DataSource的實(shí)現(xiàn),即連接池的實(shí)現(xiàn)旷偿。通常我們把DataSource的實(shí)現(xiàn)按其英文含義稱為數(shù)據(jù)源烹俗,數(shù)據(jù)源中都包含了數(shù)據(jù)庫(kù)連接池的實(shí)現(xiàn)。
也有一些開源組織提供了數(shù)據(jù)源的獨(dú)立實(shí)現(xiàn):
DBCP數(shù)據(jù)庫(kù)連接池
C3P0數(shù)據(jù)庫(kù)連接池
使用tomcat數(shù)據(jù)源實(shí)際應(yīng)用時(shí)不需要編寫連接數(shù)據(jù)庫(kù)代碼狸捅,直接從數(shù)據(jù)源獲得數(shù)據(jù)庫(kù)的連接。程序員編寫時(shí)也盡量使用這些數(shù)據(jù)源的實(shí)現(xiàn)累提,以提升程序的數(shù)據(jù)庫(kù)訪問(wèn)性能尘喝。
二、DBCP數(shù)據(jù)源(工程day16
)
DBCP是Apache軟件基金組織下的開源連接池實(shí)現(xiàn)斋陪,使用DBCP數(shù)據(jù)源朽褪,應(yīng)用程序應(yīng)在系統(tǒng)中增加如下兩個(gè)jar文件:
commons-dbcp.jar
:連接池的實(shí)現(xiàn)
commons-pool.jar
:連接池實(shí)現(xiàn)的依賴庫(kù)tomcat的連接池正式采用該連接池來(lái)實(shí)現(xiàn)的。該數(shù)據(jù)庫(kù)連接池既可以與應(yīng)用服務(wù)器整合使用无虚,也可由應(yīng)用程序獨(dú)立使用缔赠。
使用此數(shù)據(jù)源需要一個(gè)配置文件:
dbcpconfig.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3305/day15
username=root
password=walp1314
#<!-- 初始化連接 -->
initialSize=10
#最大連接數(shù)量
maxActive=50
#<!-- 最大空閑連接 -->
maxIdle=20
#<!-- 最小空閑連接 -->
minIdle=5
#<!-- 超時(shí)等待時(shí)間以毫秒為單位 6000毫秒/1000等于60秒 -->
maxWait=60000
#JDBC驅(qū)動(dòng)建立連接時(shí)附帶的連接屬性屬性的格式必須為這樣:[屬性名=property;]
#注意:"user" 與 "password" 兩個(gè)屬性會(huì)被明確地傳遞,因此這里不需要包含他們友题。
connectionProperties=useUnicode=true;characterEncoding=UTF8
#指定由連接池所創(chuàng)建的連接的自動(dòng)提交(auto-commit)狀態(tài)嗤堰。
defaultAutoCommit=true
#driver default 指定由連接池所創(chuàng)建的連接的只讀(read-only)狀態(tài)。
#如果沒有設(shè)置該值度宦,則“setReadOnly”方法將不被調(diào)用踢匣。(某些驅(qū)動(dòng)并不支持只讀模式,如:Informix)
defaultReadOnly=
#driver default 指定由連接池所創(chuàng)建的連接的事務(wù)級(jí)別(TransactionIsolation)戈抄。
#可用值為下列之一:(詳情可以看文檔)NONE,READ_UNCOMMITED,READ_COMMITED,REPEATABLE_READ,SERIALIZABLE
#但是注意:以上是mysql的隔離級(jí)別离唬,Oracle有些不同,Oracle最低要求READ_COMMITED
defaultTransactionIsolation=READ_UNCOMMITED
JdbcUtils_DBCP.java
package cn.itcast.utils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
public class JdbcUtils_DBCP {
private static DataSource ds = null;
static{
try{
InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties properties = new Properties();
properties.load(in);
//先new一個(gè)工廠
BasicDataSourceFactory factory = new BasicDataSourceFactory();
//使用工廠生成數(shù)據(jù)源
ds = factory.createDataSource(properties);
System.out.println(ds);
}catch(Exception e){
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
public static void release(Connection conn, Statement ps , ResultSet result){
if(result != null){
try {
result.close();
} catch (Exception e) {
e.printStackTrace();
}
result = null;
}
if(ps != null){
try {
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
ps = null;
}
if(conn != null){
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
conn = null;
}
}
}
說(shuō)明:這里我們可以使用之前的例子(如Demo1.java
)進(jìn)行測(cè)試划鸽,但是當(dāng)我們使用的DBCP是版本1输莺,那么是可以測(cè)試成功的,但是如果用DBCP的版本2裸诽,那么會(huì)出現(xiàn)異常嫂用,此時(shí)我們需要再導(dǎo)入一個(gè)jar包:commons-logging-1.2.jar
。這樣才能測(cè)試成功丈冬。
C3P0數(shù)據(jù)源(工程day16
)
首先需要導(dǎo)入相關(guān)的jar包:
c3p0-0.9.5.1.jar
mchange-commons-java-0.2.10.jar
使用此數(shù)據(jù)源需要的配置文件是:
c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 如果在new的時(shí)候不指定使用哪個(gè)配置則使用下面缺省的配置 -->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3305/day16</property>
<property name="user">root</property>
<property name="password">walp1314</property>
<!-- 池里面的鏈接數(shù)量不夠的時(shí)候可以再找數(shù)據(jù)庫(kù)要多少個(gè) -->
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
<!-- This app is massive! -->
<named-config name="mysql">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property>
<property name="user">root</property>
<property name="password">walp1314</property>
<property name="acquireIncrement">5</property><!--池里面的鏈接數(shù)量不夠的時(shí)候可以再找數(shù)據(jù)庫(kù)要多少個(gè) -->
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
<!-- intergalactoApp adopts a different approach to configuring statement caching -->
<!-- <property name="maxStatements">0</property>
<property name="maxStatementsPerConnection">5</property> -->
</named-config>
<named-config name="oracle">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property>
<property name="user">root</property>
<property name="password">walp1314</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</named-config>
</c3p0-config>
說(shuō)明:如果我們?cè)诤竺娉绦蛑腥绻恢付ㄊ褂媚膫€(gè)數(shù)據(jù)庫(kù)配置尸折,那么就使用默認(rèn)的配置。
JdbcUtils_C3P0.java
package cn.itcast.utils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class JdbcUtils_C3P0 {
private static ComboPooledDataSource ds = null;
static{
try{
//使用配置文件時(shí)殷蛇,配置文件必須放在src下实夹,同時(shí)配置文件名不要改橄浓,如果不指定配置文件名,則使用默認(rèn)的配置
ds = new ComboPooledDataSource("mysql");
}catch(Exception e){
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
public static void release(Connection conn, Statement ps , ResultSet result){
if(result != null){
try {
result.close();
} catch (Exception e) {
e.printStackTrace();
}
result = null;
}
if(ps != null){
try {
ps.close();
} catch (Exception e) {
e.printStackTrace();
}
ps = null;
}
if(conn != null){
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
conn = null;
}
}
}
說(shuō)明:我們也可以直接在程序中對(duì)其驅(qū)動(dòng)等信息進(jìn)行設(shè)置亮航,但是那樣太麻煩荸实,這里我們使用配置文件,如果不具體指定使用哪個(gè)配置缴淋,那就使用默認(rèn)配置准给。同樣我們可以使用之前的程序進(jìn)行測(cè)試。
四重抖、使用tomcat數(shù)據(jù)源(工程day16_web
)
我們可以在tomcat服務(wù)器中配置一個(gè)數(shù)據(jù)源露氮,這個(gè)數(shù)據(jù)源使用的JNDI技術(shù)。
所謂JNDI:
- JNDI(
java Naming and Directory Interface
),java命名和目錄接口钟沛,它對(duì)應(yīng)于J2SE中的javax.naming
包畔规。這套API的主要作用在于:它可以把java對(duì)象放在一個(gè)容器中(JNDI容器),并為容器中的java對(duì)象取一個(gè)名稱恨统,以后程序想獲得java對(duì)象叁扫,只需通過(guò)名稱檢索即可。 - 其核心API為context畜埋,它代表JNDI容器莫绣,其lookup方法為檢索容器中對(duì)應(yīng)名稱的對(duì)象。
首先我們需要配置tomcat的Context悠鞍,配置Context可以有多種方式对室,這里我們使用一個(gè)配置文件放在META-INF/context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/EmployeeDB"
auth="Container"
type="javax.sql.DataSource"
username="root"
password="walp1314"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3305/day16"
maxTotal="8"
maxIdle="4"/>
</Context>
ServletDemo1.java
package cn.itcast.web.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.dao.BaseDao;
//記得mysql的驅(qū)動(dòng)一定要加到tomcat的lib中
public class ServletDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
BaseDao dao = new BaseDao();
dao.add();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
BaseDao.java
package cn.itcast.dao;
import java.sql.Connection;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
public class BaseDao {
public void add() {
try {
// 此時(shí)我們所有的程序都是在服務(wù)器中,在一般的類中我們也可以拿到數(shù)據(jù)庫(kù)鏈接
Context initCtx = new InitialContext();// 初始化JNDI
Context envCtx = (Context) initCtx.lookup("java:comp/env");// 得到JNDI容器
DataSource ds = (DataSource) envCtx.lookup("jdbc/EmployeeDB");// 從容器中檢索一個(gè)鏈接池
Connection conn = ds.getConnection();// 獲取到一個(gè)鏈接
System.out.println(conn);
} catch (Exception e) {
e.printStackTrace();
}
}
}
說(shuō)明:這里一定注意要將mysql的jdbc驅(qū)動(dòng)放在tomcat的lib目錄中咖祭。
最后:其實(shí)還有一些開源的數(shù)據(jù)源可以使用软驰,比如阿里巴巴的數(shù)據(jù)源druid-1.0.19.jar
,在以后的項(xiàng)目中可以使用心肪,而且其功能強(qiáng)大锭亏。