`
waynezhangww
  • 浏览: 10982 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

连接池配置

阅读更多

JNDI 连接池

 

1.将数据库驱动包放到Tomcat相应的lib下;

2.在WEB项目里的META-INF目录下创建context.xml, 只对当前项目有效;

   也可以直接更改Tomcat\conf\context.xml, 对所有项目有效;

context.xml

<Context>
	<Resource
		name="jdbc/mysql"
		auth="Container"
		type="javax.sql.DataSource"
		driverClassName="com.mysql.jdbc.Driver"
		url="jdbc:mysql://127.0.0.1:3306/test"
		username="root"
		password="admin"
		maxActive="2"
		maxIdle="1"
		maxWait="-1"
	 />
	<!--name:DataSource的名称-->
	<!--auth:资源由谁来管理Container-->
	<!--type:数据源对应的java类型,一般设计为javax.sql.DataSource-->
	<!--driverClassName:指定数据库JDBC驱动程序-->
	<!--url:指定数据库的URL-->
	<!--username:数据库登陆名-->
	<!--password:数据库登陆密码-->
	<!--maxActive:连接池处于活动状态的数据库连接的最大数目,取0表示不受限制-->	 
	<!--maxIdle:连接池处于空闲状态的数据库连接的最大数目,取0表示不受限制-->
	<!--maxWait:连接池中数据库连接处于空闲状态的最长时间(以毫秒为单位),取-1|0表示无限制等待时间-->
</Context>

 

3.在web.xml中添加<resource-ref/>;

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	<resource-ref>
		<res-ref-name>jdbc/mysql</res-ref-name>
		<res-type>javax.sql.DataSource</res-type>
		<res-auth>Container</res-auth>
	</resource-ref>
	
	<!-- JDBC JNDI -->
	<servlet>
		<servlet-name>ConnPoolJDBCServlet</servlet-name>
		<servlet-class>test.ConnPoolJDBCServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>ConnPoolJDBCServlet</servlet-name>
		<url-pattern>/jdbc</url-pattern>
	</servlet-mapping>
	
	<!-- Hibernate JNDI -->
	<servlet>
		<servlet-name>ConnPoolHbnServlet</servlet-name>
		<servlet-class>test.ConnPoolHbnServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>ConnPoolHbnServlet</servlet-name>
		<url-pattern>/hbn</url-pattern>
	</servlet-mapping>
	
	<!-- Hibernate Proxool -->
	<servlet>
		<servlet-name>ConnPoolProxoolServlet</servlet-name>
		<servlet-class>test.ConnPoolProxoolServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>ConnPoolProxoolServlet</servlet-name>
		<url-pattern>/proxool</url-pattern>
	</servlet-mapping>
	
	<!-- Hibernate C3P0 -->
	<servlet>
		<servlet-name>ConnPoolC3P0Servlet</servlet-name>
		<servlet-class>test.ConnPoolC3P0Servlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>ConnPoolC3P0Servlet</servlet-name>
		<url-pattern>/c3p0</url-pattern>
	</servlet-mapping>
	
	<!-- DBCP -->
	<servlet>
		<servlet-name>ConnPoolDBCPServlet</servlet-name>
		<servlet-class>test.ConnPoolDBCPServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>ConnPoolDBCPServlet</servlet-name>
		<url-pattern>/dbcp</url-pattern>
	</servlet-mapping>
 </web-app>

 

4.用JDBC来获取连接;

ConnPoolJDBCServlet.java

package test;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

public class ConnPoolJDBCServlet extends HttpServlet
{
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		Connection conn = null;
		try
		{
			Context context = new InitialContext();
			DataSource ds = (DataSource) context.lookup("java:comp/env/jdbc/mysql");
			conn = ds.getConnection();
			resp.setContentType("text/html");
			PrintWriter out = resp.getWriter();
			out.println(conn);
			out.flush();
		} catch (Exception e)
		{
			e.printStackTrace();
		} finally
		{
			try
			{
				if (conn != null)
					conn.close();
			} catch (SQLException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

 

5.用Hibernate来获取连接, 先配置hibernate.cfg.xml;

hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<property name="connection.datasource">java:comp/env/jdbc/mysql</property>
		<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="current_session_context_class">thread</property>
	</session-factory>
</hibernate-configuration>

 

6.测试类;

ConnPoolHbnServlet.java

package test;

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 org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ConnPoolHbnServlet extends HttpServlet
{
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		// TODO Auto-generated method stub
		Configuration cfg = new Configuration().configure();
		SessionFactory sf = cfg.buildSessionFactory();
		Session session = sf.getCurrentSession();
		resp.setContentType("text/html");
		PrintWriter out = resp.getWriter();
		out.println(session);
		out.flush();
	}
}

 

7.访问http://127.0.0.1:8080/TestJNDI/jdcbhttp://127.0.0.1:8080/TestJNDI/hbn ;

   注: 必须通过web才能使用JNDI连接池, 不然无法加载Context

 

 

 

C3P0 连接池

 

1.将c3p0-0.9.0.jar添加到Tomcat相应的lib下;

2.配置hibernateC3P0.cfg.xml;

hibernateC3P0.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://127.0.0.1:3306/test</property>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="connection.username">root</property>
        <property name="connection.password">admin</property>
		<property name="current_session_context_class">thread</property>

		<property name="c3p0.max_size">2</property>
		<property name="c3p0.min_size">2</property>
		<property name="c3p0.timeout">5000</property>
		<property name="c3p0.idle_test_period">3000</property>
		<property name="c3p0.max_statements">100</property>
		<property name="c3p0.acquire_increment">2</property>
		
		<!--c3p0.max_size:最大连接数-->
		<!--c3p0.min_size:最小连接数-->
		<!--c3p0.timeout:等5秒还没有拿到连接,就放弃-->
		<!--c3p0.idle_test_period:每隔3秒测试连接有没有使用,长时间没有使用,则就收回-->
		<!--c3p0.max_statements:最多缓冲100条sql -->
		<!--c3p0.acquire_increment:连接不够用,可以增长连接,每次两个增长-->
		
	</session-factory>
   </hibernate-configuration>

 

3.获取连接;

ConnPoolC3P0Servlet.java

package test;

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 org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ConnPoolC3P0Servlet extends HttpServlet
{
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		// TODO Auto-generated method stub
		Configuration cfg = new Configuration().configure("hibernateC3P0.cfg.xml");
		SessionFactory sf = cfg.buildSessionFactory();
		Session session = sf.getCurrentSession();
		resp.setContentType("text/html");
		PrintWriter out = resp.getWriter();
		 out.println(session);
		 out.flush();
	 }
  }

 

4.访问http://127.0.0.1:8080/TestJNDI/c3p0 ;

 

 

Proxool 连接池

 

1.将proxool-0.8.3.jar和log4j-1.2.15.jar配置到Tomcat下的lib里;

2.在WEB项目的src目录下创建proxoolconf.xml;

proxoolconf.xml

<?xml version="1.0" encoding="UTF-8"?>
<proxool-config>
	<proxool>
		<alias>DBPool</alias>
		<driver-url>jdbc:mysql://127.0.0.1:3306/test</driver-url>
		<driver-class>com.mysql.jdbc.Driver</driver-class>
		<driver-properties>
			<property name="user" value="root" />
			<property name="password" value="admin" />
		</driver-properties>
		<house-keeping-sleep-time>90000</house-keeping-sleep-time>
		<maximum-connection-count>100</maximum-connection-count>
		<minimum-connection-count>10</minimum-connection-count>
		<maximum-new-connections>20</maximum-new-connections>
		<prototype-count>5</prototype-count>
	</proxool>
	<!--proxool只能管理由自己产生的连接-->
	<!--driver-url:驱动的url-->
	<!--house-keeping-sleep-time:proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁-->
	<!--maximum-new-connections:指因未有空闲连接可以分配而在队列中等候的最大请求数,超过这个请求数的用户连接就不会被接受-->
	<!--prototype-count:最少保持的空闲连接数-->
	<!--maximum-connection-count:允许最大连接数,超过了这个连接,再有请求时,就排在队列中等候,最大的等待请求数由maximum-new-connections决定-->
	<!--minimum-connection-count:最小连接数-->
</proxool-config>

 

3.配置hibernateProxool.cfg.xml;

hibernateProxool.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
	<session-factory>
		<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="current_session_context_class">thread</property>
		<property name="proxool.pool_alias">DBPool</property>
		<property name="proxool.xml">proxoolconf.xml</property>
		<property name="connection.provider_class">
			org.hibernate.connection.ProxoolConnectionProvider
		</property>
	</session-factory>
</hibernate-configuration>

 

4.获取连接;

ConnPoolProxoolServlet.java

package test;

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 org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class ConnPoolProxoolServlet extends HttpServlet
{
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		// TODO Auto-generated method stub
		Configuration cfg = new Configuration().configure("hibernateProxool.cfg.xml");
		SessionFactory sf = cfg.buildSessionFactory();
		Session session = sf.getCurrentSession();	
		resp.setContentType("text/html");
		PrintWriter out = resp.getWriter();
		out.println(session);
		out.flush();
	}
}

 

5.访问http://127.0.0.1:8080/TestJNDI/proxool ;

 

 

DBCP 连接池

 

1.将commons-dbcp-1.2.1.jar、commons-collections-3.2.jar和commons-pool.jar添加到Tomcat相应的lib下, 并且导入项目;

2.配置DBCP属性文件;

dbcp_config.properties

driver_class=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test
username=root
password=admin

 

3.获取连接;

ConnPoolDBCPServlet.java

package test;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDriver;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;

public class ConnPoolDBCPServlet extends HttpServlet
{
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		// TODO Auto-generated method stub
		InputStream stream = new FileInputStream(this.getClass().getClassLoader().getResource("").getPath()+"dbcp_config.properties");
		Properties props = new Properties();
		props.load(stream);
		String driver_class = props.getProperty("driver_class");
		String url= props.getProperty("url");
		String username = props.getProperty("username");
		String password = props.getProperty("password");
		try {
			Class.forName(driver_class);
			ObjectPool connectionPool = new GenericObjectPool(null);
            ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(url, username, password);     
            new PoolableConnectionFactory(connectionFactory, connectionPool, null, null, false, true);     
            Class.forName("org.apache.commons.dbcp.PoolingDriver");     
            PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");     
            driver.registerPool("dbpool", connectionPool); 
            Connection conn = DriverManager.getConnection("jdbc:apache:commons:dbcp:dbpool");
            resp.setContentType("text/html");
			PrintWriter out = resp.getWriter();
			out.println(conn);
			out.flush();
			conn.close();
			//driver.closePool("dbpool");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

 

4.访问http://127.0.0.1:8080/TestJNDI/dbcp ;

 

各式各样的ObjectPool
可口可乐公司的软饮料有可口可乐、雪碧和芬达等品种,百事可乐公司的软饮料有百事可乐、七喜和美年达等类型,而Pool组件提供的ObjectPool实现则有StackObjectPool、SoftReferenceObjectPool和GenericObjectPool等种类。

不同类型的软饮料各有各自的特点,分别适应不同消费者的口味;而不同类型的ObjectPool也各有各自的特色,分别适应不同的情况。

StackObjectPool
StackObjectPool利用一个java.util.Stack对象来保存对象池里的对象。这种对象池的特色是:

可以为对象池指定一个初始的参考大小(当空间不够时会自动增长)。
在对象池已空的时候,调用它的borrowObject方法,会自动返回新创建的实例。
可以为对象池指定一个可保存的对象数目的上限。达到这个上限之后,再向池里送回的对象会被自动送去回收。
StackObjectPool的构造方法共有六个,其中:

最简单的一个是StackObjectPool(),一切采用默认的设置,也不指明要用的PoolableObjectFactory实例。
最复杂的一个则是StackObjectPool(PoolableObjectFactory factory, int max, int init)。其中:

参数factory指明要与之配合使用的PoolableObjectFactory实例;
参数max设定可保存对象数目的上限;
参数init则指明初始的参考大小。
剩余的四个构造方法则是最复杂的构造方法在某方面的简化版本,可以根据需要选用。它们是:

StackObjectPool(int max)
StackObjectPool(int max, int init)
StackObjectPool(PoolableObjectFactory factory)
StackObjectPool(PoolableObjectFactory factory, int max)
用不带factory参数的构造方法构造的StackObjectPool实例,必须要在用它的setFactory(PoolableObjectFactory factory)方法与某一PoolableObjectFactory实例关联起来后才能正常使用。

这种对象池可以在没有Jakarta Commmons Collections组件支持的情况下正常运行。

SoftReferenceObjectPool
SoftReferenceObjectPool利用一个java.util.ArrayList对象来保存对象池里的对象。不过它并不在对象池里直接保存对象本身,而是保存它们的“软引用”(Soft Reference)。这种对象池的特色是:

可以保存任意多个对象,不会有容量已满的情况发生。
在对象池已空的时候,调用它的borrowObject方法,会自动返回新创建的实例。
可以在初始化同时,在池内预先创建一定量的对象。
当内存不足的时候,池中的对象可以被Java虚拟机回收。
SoftReferenceObjectPool的构造方法共有三个,其中:

最简单的是SoftReferenceObjectPool(),不预先在池内创建对象,也不指明要用的PoolableObjectFactory实例。
最复杂的一个则是SoftReferenceObjectPool(PoolableObjectFactory factory, int initSize)。其中:

参数factory指明要与之配合使用的PoolableObjectFactory实例
参数initSize则指明初始化时在池中创建多少个对象。
剩下的一个构造方法,则是最复杂的构造方法在某方面的简化版本,适合在大多数情况下使用。它是:

SoftReferenceObjectPool(PoolableObjectFactory factory)
用不带factory参数的构造方法构造的SoftReferenceObjectPool实例,也要在用它的setFactory(PoolableObjectFactory factory)方法与某一PoolableObjectFactory实例关联起来后才能正常使用。

这种对象池也可以在没有Jakarta Commmons Collections组件支持的情况下正常运行。

GenericObjectPool
GenericObjectPool利用一个org.apache.commons.collections.CursorableLinkedList对象来保存对象池里的对象。这种对象池的特色是:

可以设定最多能从池中借出多少个对象。
可以设定池中最多能保存多少个对象。
可以设定在池中已无对象可借的情况下,调用它的borrowObject方法时的行为,是等待、创建新的实例还是抛出异常。
可以分别设定对象借出和还回时,是否进行有效性检查。
可以设定是否使用一个单独的线程,对池内对象进行后台清理。
GenericObjectPool的构造方法共有七个,其中:

最简单的一个是GenericObjectPool(PoolableObjectFactory factory)。仅仅指明要用的PoolableObjectFactory实例,其它参数则采用默认值。
最复杂的一个是GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn, long timeBetweenEvictionRunsMillis, int numTestsPerEvictionRun, long minEvictableIdleTimeMillis, boolean testWhileIdle)。其中:

参数factory指明要与之配合使用的PoolableObjectFactory实例。
参数maxActive指明能从池中借出的对象的最大数目。如果这个值不是正数,表示没有限制。
参数whenExhaustedAction指定在池中借出对象的数目已达极限的情况下,调用它的borrowObject方法时的行为。可以选用的值有:
GenericObjectPool.WHEN_EXHAUSTED_BLOCK,表示等待;
GenericObjectPool.WHEN_EXHAUSTED_GROW,表示创建新的实例(不过这就使maxActive参数失去了意义);
GenericObjectPool.WHEN_EXHAUSTED_FAIL,表示抛出一个java.util.NoSuchElementException异常。
参数maxWait指明若在对象池空时调用borrowObject方法的行为被设定成等待,最多等待多少毫秒。如果等待时间超过了这个数值,则会抛出一个java.util.NoSuchElementException异常。如果这个值不是正数,表示无限期等待。
参数testOnBorrow设定在借出对象时是否进行有效性检查。
参数testOnBorrow设定在还回对象时是否进行有效性检查。
参数timeBetweenEvictionRunsMillis,设定间隔每过多少毫秒进行一次后台对象清理的行动。如果这个值不是正数,则实际上不会进行后台对象清理。
参数numTestsPerEvictionRun,设定在进行后台对象清理时,每次检查几个对象。如果这个值不是正数,则每次检查的对象数是检查时池内对象的总数乘以这个值的负倒数再向上取整的结果??也就是说,如果这个值是-2(-3、-4、-5……)的话,那么每次大约检查当时池内对象总数的1/2(1/3、1/4、1/5……)左右。
参数minEvictableIdleTimeMillis,设定在进行后台对象清理时,视休眠时间超过了多少毫秒的对象为过期。过期的对象将被回收。如果这个值不是正数,那么对休眠时间没有特别的约束。
参数testWhileIdle,则设定在进行后台对象清理时,是否还对没有过期的池内对象进行有效性检查。不能通过有效性检查的对象也将被回收。
另一个比较特别的构造方法是GenericObjectPool(PoolableObjectFactory factory, GenericObjectPool.Config config) 。其中:

参数factory指明要与之配合使用的PoolableObjectFactory实例;
参数config则指明一个包括了各个参数的预设值的对象(详见《GenericObjectPool.Config》一节)。
剩下的五个构造函数则是最复杂的构造方法在某方面的简化版本,可以根据情况选用。它们是:

GenericObjectPool(PoolableObjectFactory factory, int maxActive)
GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait)
GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, boolean testOnBorrow, boolean testOnReturn)
GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle)
GenericObjectPool(PoolableObjectFactory factory, int maxActive, byte whenExhaustedAction, long maxWait, int maxIdle, boolean testOnBorrow, boolean testOnReturn)
这种对象池不可以在没有Jakarta Commmons Collections组件支持的情况下运行。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics