现在很多WEB服务器(Weblogic,WebSphere,Tomcat)都提供了DataSource的实现(连接池的实现),我们把DataSource的实现,按其英文含义称之为数据源,数据源中包含了数据库连接池的实现。
也有一些开源组织提供了数据源的独立实现:
- DBCP 数据库连接池
- C3P0 数据库连接池
- Tomcat内置的连接池(DBCP)
DBCP数据源
使用DBCP数据源,应用程序应在系统中增加如下两个jar文件:
commons-dbcp.jar:连接池的实现
commons-pool.jar:连接池实现的依赖库
Tomcat的连接池正式采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。
dbcpConfig.properties 配置文件
#连接设置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/testbatch
username=root
password=root
#oracle
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@localhost:1521:orcl
#username=system
#password=itcast
#初始化连接
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=false
#如果没有设置该值,则"setReadOnly"方法将不被调用。(某些驱动并不支持只读模式,如:Infomix)
defaultReadOnly
#driver default 指定由连接池所创建连接的事务级别(TransactionIsolation)
#可用值:NONE,READ_UNCOMMITTED,READ_COMMITTED,REPEATABLE_READ,SERIALIZABLE
defalutTransactionIsolation=READ_COMMITTED
JdbcUtils_dbcp 连接池
package cn.itcast.utils;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
public class JdbcUtils {
private static DataSource ds = null;
static {
try {
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpConfig.properties");
Properties prop = new Properties();
prop.load(in);
BasicDataSourceFactory factory = new BasicDataSourceFactory();
//创建数据库连接池
ds = factory.createDataSource(prop);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws Exception {
return ds.getConnection();//不会把sql真正的connection返回
}
public static void release(Connection conn, Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close(); //throw new
} catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if (st != null) {
try {
st.close();
} catch (Exception e) {
e.printStackTrace();
}
st = null;
}
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
结果测试
@Test
public void TestDataSource() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
System.out.println(conn);
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn, ps, rs);
}
}
结果:jdbc:mysql://localhost:3306/testbatch, UserName=root@localhost, MySQL Connector Java
C3P0数据源
Spring里面内置的数据源也是C3P0。
所需要的jar文件:
c3p0-0.9.5.2.jar
mchange-commons-java-0.2.11.jar
package cn.itcast.utils;
/**
* Created by yvettee on 2017/9/28.
*/
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
public class JdbcUtils_c3p0 {
private static ComboPooledDataSource cpds = null;
static {
try {
cpds = new ComboPooledDataSource();
cpds.setDriverClass("com.mysql.jdbc.Driver");
cpds.setJdbcUrl("jdbc:mysql://localhost:3306/testbatch");
cpds.setUser("root");
cpds.setPassword("root");
cpds.setMaxPoolSize(30);
cpds.setMinPoolSize(5);
cpds.setInitialPoolSize(10);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws Exception {
return cpds.getConnection();//不会把sql真正的connection返回
}
public static void release(Connection conn, Statement st, ResultSet rs) {
if (rs != null) {
try {
rs.close(); //throw new
} catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if (st != null) {
try {
st.close();
} catch (Exception e) {
e.printStackTrace();
}
st = null;
}
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
结果测试
@Test
public void TestDataSource() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JdbcUtils_c3p0.getConnection();
System.out.println(conn.getClass().getName());
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils_dbcp.release(conn, ps, rs);
}
}
结果:里面包含日志信息和打印出来的东西
1.png如图所示:写进配置文件里,根据C3P0提供的方法新建一个配置文件c3p0-config.xml
,这个配置文件名必须是c3p0-config.xml,因为在new ComboPooledDataSource("mysql");
,它会自动搜索名为c3p0-config.xml的配置文件。
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/testbatch</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">20</property>
<property name="minPoolSize">5</property>
<property name="maxStatements">200</property>
</default-config>
<!--在new ComboPooledDataSource();时将named-config中name值传进去,如果没传值,就使用<default-config>的配置-->
<named-config name="mysql">
<property name="acquireIncrement">50</property>
<property name="initialPoolSize">100</property>
<property name="minPoolSize">50</property>
<property name="maxPoolSize">1000
</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="acquireIncrement">50</property>
<property name="initialPoolSize">100</property>
<property name="minPoolSize">50</property>
<property name="maxPoolSize">1000
</property><!-- intergalactoApp adopts a different approach to configuring statement caching -->
<property name="maxStatements">0</property>
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>
修改之前的代码
static {
try {
cpds = new ComboPooledDataSource();
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
配置Tomcat数据源
配置方法在官方文档里都有写的:
配置方法在这里,提示一下,Tomcat配置数据源的方式必须将用到的jar文件(包括驱动jar)都要放进Tomcat安装目录的lib目录下。
1. 在Tomcat安装目录下的conf文件夹的server.xml文件里配置
2. 在Tomcat安装目录下的Catalina文件下的localhost文件夹里新建XML文件配置
当Tomcat启动时,就会为web应用创建连接池,并且Tomcat会把创建的这个连接池以JNDI的方式绑定到name="jdbc/datasource"
,用的时候只需要检索这个name的值就可以拿到连接池了。
在server.xml
的</Host>
前面添加下面的信息:
Context:当前web应用
name:项目名
docBase:指定Web应用的文件路径,可以给定绝对路径,也可以给定相对于<Host>的appBase属性的相对路径,如果Web应用采用开放目录结构,则指定Web应用的根目录,如果Web应用是个war文件,则指定war文件的路径。(指定项目所在地址)
<Context name="/DataSource" docBase="DataSource">
<Resource name="jdbc/datasource" auth="container"
type="javax.sql.DataSource" username="root" password="root"
driverClassName="com.mysql.jdbc.driver"
url="jdbc:mysql://localhost:3306/jdbc"
maxActive="8" maxIdle="4"/>
</Context>
到这里,就已经成功创建好一个连接池了。
Context initCtx = new InitialContext();
Context envCtx = (Context)initCtx.lookup("java:comp/env");
dataSource = (DataSource)envCtx.lookup("jdbc/datasource");
特别提醒:此种配置下,驱动jar文件需放置在tomcat
的lib
下。
3. 在WEB应用的META-INF下新建context.cml文件进行配置
我这里用到的是IDEA
开发工具
context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource name="jdbc/DataSource" auth="container"
type="javax.sql.DataSource"
username="root"
password="root"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/testbatch"
initialSize="30"
maxActive="10" maxIdle="4"/>
</Context>
然后还要在web.xml中进行如下配置:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- DB Connection Start -->
<description>MySQL Test App</description>
<resource-ref>
<description>DB COnnection</description>
<res-ref-name>jdbc/DataSource</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
在JDBCUtils工具类里获取连接
package cn.itcast.utils;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
/**
* Created by yvettee on 2017/9/29.
*/
public class JdbcUtils {
private static DataSource ds = null;
static {
try {
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
ds = (DataSource) envCtx.lookup("jdbc/DataSource");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
}
在dao层进行实现
package cn.itcast.dao;
import cn.itcast.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.SQLException;
public class DaoData {
public void add() {
Connection conn = null;
try {
conn = JdbcUtils.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
System.out.println(conn.getClass().getName());
}
}
servlet里测试结果
package cn.itcast.web;
import cn.itcast.dao.DaoData;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* Created by yvettee on 2017/9/29.
*/
@WebServlet(name = "DataSourceServlet", urlPatterns = "/DataSourceServlet")
public class DataSourceServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
DaoData dao = new DaoData();
dao.add();
}
}
网友评论