zoukankan      html  css  js  c++  java
  • 开源数据库连接池的使用

    上篇博客刚刚说完如何去自定义一个数据库连接池,当然,这个自定义的数据库连接池是十分简易的,凭借自己的能力也无法写出优秀的连接池。但是,不用担心,我们可以使用开源的数据库连接池,开源的优势体现于此。

    在Java中有三种开源数据库连接池提供了数据源的独立实现:

    • DBCP 数据库连接池
    • C3P0 数据库连接池
    • Apache Tomcat内置的连接池(apache dbcp)
    1、DBCP数据库连接池

    DBCP是Apache软件基金组织下的开源连接池实现,使用DBCP数据源,应用程序应在系统中增加如下两个jar文件:

    • commons-dbcp.jar
    • commons-pool.jar

    今天的jar包资源我也放在了网盘上。链接:https://pan.baidu.com/s/1-Rj4TQLI_5DGLdfb45N62g
    提取码:ba3a
    复制这段内容后打开百度网盘手机App,操作更方便哦
    jar包准备好了,那么我们来使用一下。
    新建一个Java项目。
    然后新建测试类DBCPTest,编写测试代码

    @Test
    public void demo1(){
    	//首先使用BasicDataSource创建连接池
    	BasicDataSource basicDataSource = new BasicDataSource();
    	try {
    		//从连接池中获取连接
    		Connection connection = basicDataSource.getConnection();
    		String sql = "select * from account";
    		PreparedStatement stmt = connection.prepareStatement(sql);
    		ResultSet set = stmt.executeQuery();
    		while(set.next()){
    			System.out.println(set.getString("name"));
    		}
    		//释放资源
    		JDBCUtils.release(stmt, connection);
    	} catch (SQLException e) {
    		e.printStackTrace();
    	}
    }
    

    现在运行测试代码,能查询出表数据吗?
    很显然,连数据库参数都没给,这段测试代码肯定会报错。
    那现在就来设置一下参数,修改测试代码

    @Test
    public void demo1(){
    	//首先使用BasicDataSource创建连接池
    	BasicDataSource basicDataSource = new BasicDataSource();
    	//创建连接需要四个参数
    	basicDataSource.setDriverClassName("com.mysql.jdbc.Driver");
    	basicDataSource.setUrl("jdbc:mysql:///test");
    	basicDataSource.setUsername("root");
    	basicDataSource.setPassword("123456");
    	try {
    		//从连接池中获取连接
    		Connection connection = basicDataSource.getConnection();
    		String sql = "select * from account";
    		PreparedStatement stmt = connection.prepareStatement(sql);
    		ResultSet set = stmt.executeQuery();
    		while(set.next()){
    			System.out.println(set.getString("name"));
    		}
    		//释放资源
    		JDBCUtils.release(stmt, connection);
    	} catch (SQLException e) {
    		e.printStackTrace();
    	}
    }
    

    现在运行测试代码
    在这里插入图片描述
    成功查询到表数据。但是这样写具有局限性,应该把数据库参数写成配置文件,以适应灵活多变的用户需求。
    在src目录下新建配置文件dbcp.properties

    driverClassName = com.mysql.jdbc.Driver
    url = jdbc:mysql:///test
    username = root
    password =123456
    

    编写测试代码

    @Test
    public void demo2() throws Exception{
    	//读取dbcp.properties
    	Properties properties = new Properties();
    	properties.load(new FileInputStream(this.getClass().getResource("/dbcp.properties").getFile()));
    	DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);
    	//从连接池中获取连接
    	Connection connection = dataSource.getConnection();
    	String sql = "select * from account";
    	PreparedStatement stmt = connection.prepareStatement(sql);
    	ResultSet set = stmt.executeQuery();
    	while(set.next()){
    		System.out.println(set.getString("name"));
    	}
    	//释放资源
    	JDBCUtils.release(stmt, connection);
    }
    

    然后运行
    在这里插入图片描述
    运行成功。
    附上一个比较全面的配置文件。

    #连接设置
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/jdbc
    username=root
    password=
    
    #<!-- 初始化连接 -->
    initialSize=10
    
    #最大连接数量
    maxActive=50
    
    #<!-- 最大空闲连接 -->
    maxIdle=20
    
    #<!-- 最小空闲连接 -->
    minIdle=5
    
    #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
    maxWait=60000
    
    
    #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] 
    #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
    connectionProperties=useUnicode=true;characterEncoding=gbk
    
    #指定由连接池所创建的连接的自动提交(auto-commit)状态。
    defaultAutoCommit=true
    
    #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
    #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
    defaultTransactionIsolation=READ_UNCOMMITTED
    
    2、C3P0数据库连接池

    jar包下载地址:https://sourceforge.net/projects/c3p0/
    官网地址:https://www.mchange.com/projects/c3p0/
    官网里面也有下载入口,和数据库连接池的使用教程。
    官网的文档教程十分详细,所以也就不过多赘述了。
    直接上案例。
    编写测试代码

    @Test
    public void demo1() throws Exception{
    	//创建一个连接池
    	ComboPooledDataSource dataSource = new ComboPooledDataSource();
    	//设置四个参数
    	dataSource.setDriverClass("com.mysql.jdbc.Driver");
    	dataSource.setJdbcUrl("jdbc:mysql:///test");
    	dataSource.setUser("root");
    	dataSource.setPassword("123456");
    	
    	Connection connection = dataSource.getConnection();
    	String sql = "select * from account";
    	PreparedStatement stmt = connection.prepareStatement(sql);
    	ResultSet set = stmt.executeQuery();
    	while(set.next()){
    		System.out.println(set.getString("name"));
    	}
    	JDBCUtils.release(stmt, connection);
    }
    

    需要注意的是,如果运行时报ClassNotFoundExecption异常,说明你的jar包版本是c3p0-0.9.2之后的,该版本之后的版本还需要添加一个辅助包,mchange-commons-java-0.2.3.4.jar。
    这是jar包的下载地址。链接:https://pan.baidu.com/s/17o0s92Us-UPQPJFeJjpOzQ
    提取码:lt2v
    复制这段内容后打开百度网盘手机App,操作更方便哦

    同样地,用配置文件实现一下。
    在src目录新建文件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:///test</property>
    		<property name="user">root</property>
    		<property name="password">123456</property>
    		
    		<property name="automaticTestTable">con_test</property>
    		<property name="checkoutTimeout">30000</property>
    		<property name="idleConnectionTestPeriod">30</property>
    		<property name="initialPoolSize">10</property>
    		<property name="maxIdleTime">30</property>
    		<property name="maxPoolSize">100</property>
    		<property name="minPoolSize">10</property>
    		<property name="maxStatements">200</property>
    
    		<user-overrides user="test-user">
    			<property name="maxPoolSize">10</property>
    			<property name="minPoolSize">1</property>
    			<property name="maxStatements">0</property>
    		</user-overrides>
    
    	</default-config>
    
    	<!-- This app is massive! -->
    	<named-config name="intergalactoApp">
    		<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>
    
    		<!-- he's important, but there's only one of him -->
    		<user-overrides user="master-of-the-universe">
    			<property name="acquireIncrement">1</property>
    			<property name="initialPoolSize">1</property>
    			<property name="minPoolSize">1</property>
    			<property name="maxPoolSize">5</property>
    			<property name="maxStatementsPerConnection">50</property>
    		</user-overrides>
    	</named-config>
    </c3p0-config>
    

    这是直接从官方文档上复制下来的。然后加上了数据库配置所需要的四个参数。
    然后编写测试代码

    @Test
    public void demo2() throws Exception{
    	//使用c3p0配置文件
    	ComboPooledDataSource dataSource = new ComboPooledDataSource();
    	Connection connection = dataSource.getConnection();
    	String sql = "select * from account";
    	PreparedStatement stmt = connection.prepareStatement(sql);
    	ResultSet set = stmt.executeQuery();
    	while(set.next()){
    		System.out.println(set.getString("name"));
    	}
    	JDBCUtils.release(stmt, connection);
    }
    

    注意,c3p0数据库连接池是不需要自己手动加载配置文件的,c3p0非常的人性化,这一步已经被封装好了。创建ComboPooledDataSource对象后直接调用getConnection()方法即可获得连接。前提是你的配置文件名字必须为c3p0-config.xml,且该文件必须放在src目录下。至于其它的一些配置信息,在文档都有讲解,大家可以自行阅读学习。

    创建ComboPooledDataSource 对象有两种方法,调用无参构造使用的是配置文件中默认的配置,而如果调用有参构造,将配置文件中标签的name属性值传入,将会使用该标签内的配置信息。

    3、Tomcat内置的连接池

    需要知道的是,Tomcat内容连接池就是DBCP。
    我们知道,将web工程部署到Tomcat有三种方式:

    • 配置server.xml,添加标签
    • 配置独立的xml文件,添加标签
    • 直接将网站目录复制到Tomcat的webapps目录下

    任何工程要能够在Tomcat运行,都需要一个虚拟目录。虚拟目录指的是什么?指的就是Context元素。当我们需要使用连接池时,就需要对Context作如下配置

    <Context path="/DBTest" docBase="DBTest"
            debug="5" reloadable="true" crossContext="true">
    
        <!-- maxActive: Maximum number of dB connections in pool. Make sure you
             configure your mysqld max_connections large enough to handle
             all of your db connections. Set to -1 for no limit.
             -->
    
        <!-- maxIdle: Maximum number of idle dB connections to retain in pool.
             Set to -1 for no limit.  See also the DBCP documentation on this
             and the minEvictableIdleTimeMillis configuration parameter.
             -->
    
        <!-- maxWait: Maximum time to wait for a dB connection to become available
             in ms, in this example 10 seconds. An Exception is thrown if
             this timeout is exceeded.  Set to -1 to wait indefinitely.
             -->
    
        <!-- username and password: MySQL dB username and password for dB connections  -->
    
        <!-- driverClassName: Class name for the old mm.mysql JDBC driver is
             org.gjt.mm.mysql.Driver - we recommend using Connector/J though.
             Class name for the official MySQL Connector/J driver is com.mysql.jdbc.Driver.
             -->
        
        <!-- url: The JDBC connection url for connecting to your MySQL dB.
             -->
    
      <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
                   maxActive="100" maxIdle="30" maxWait="10000"
                   username="javauser" password="javadude" driverClassName="com.mysql.jdbc.Driver"
                   url="jdbc:mysql://localhost:3306/javatest"/>
    
    </Context>
    

    这是从官网上复制下来的。
    那么该在哪里配置Context元素呢?
    配置Context元素的三个位置:

    • Tomcat安装目录/conf/context.xml(如果将连接池配置到了该文件,就会对当前Tomcat内部所有的虚拟主机中的任何工程都有效)
    • Tomcat安装目录/conf/Catalina/虚拟主机目录/context.xml(如果将连接池配置到了该文件,就会对当前虚拟主机的任何工程都有效)
    • web工程的根目录/META-INF/context.xml(如果将连接池配置到了该文件,将只对当前工程有效)

    接下来演示一下第三种配置方式
    在WebRoot下的META-INF文件夹中新建一个文件context.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <Context path="/DBTest" docBase="DBTest" debug="5" reloadable="true"
    	crossContext="true">
    
    	<Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"
    		maxActive="100" maxIdle="30" maxWait="10000" username="root"
    		password="123456" driverClassName="com.mysql.jdbc.Driver"
    		url="jdbc:mysql://localhost:3306/test" />
    
    </Context>
    

    context.xml文件编写完成后,在启动Tomcat服务器的时候,Tomcat会去自动加载该文件,并创建数据库连接池,存放在Tomcat容器中。此时我们将可以使用JNDI技术去访问数据库连接池。
    不了解JNDI技术的童鞋,我们可以在这里略微提一下

    JNDI(Java Naming and Directory Interface),Java命名和目录接口,它对应于J2SE中的javax.naming包,
    这套API的主要作用在于:它可以把Java对象放在一个容器中(支持JNDI容器 Tomcat),并为容器中的java对象取一个名称,以后程序想获得Java对象,只需通过名称检索即可。
    其核心API为Context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。

    注意事项:
    Tomcat创建连接池,与数据库连接需要数据库驱动,要将mysql.jar复制到Tomcat目录下的lib文件夹中。
    Java程序要想通过JNDI访问对象,就必须运行在同一个JNDI容器中。也就是说,该Java程序必须运行在Tomcat内部,所以使用JNDI的程序一般是Servlet或JSP。

    演示一下。
    在项目中新建一个Servlet文件为TomcatServlet

    /**
     * 在该程序中,通过JNDI访问Tomcat内部的连接池
     * @author Administrator
     *
     */
    public class TomcatServlet extends HttpServlet {
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		try {
    			//创建一个检索的对象
    			Context initCtx = new InitialContext();
    			//默认查找顶级的Java名称串	这是固定的:java:comp/env
    			Context envCtx = (Context) initCtx.lookup("java:comp/env");
    			//根据设置名称查找连接池对象
    			DataSource ds = (DataSource) envCtx.lookup("jdbc/TestDB");
    			//获得连接池中的一个连接
    			Connection conn = ds.getConnection();
    			String sql = "select * from account";
    			PreparedStatement stmt = conn.prepareStatement(sql);
    			ResultSet set = stmt.executeQuery();
    			while(set.next()){
    				System.out.println(set.getString("name"));
    			}
    			JDBCUtils.release(stmt, conn);
    		} catch (NamingException e) {
    			e.printStackTrace();
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		doGet(request, response);
    	}
    
    }
    

    千万别忘了数据库驱动,将mysql-connector-java-5.1.47-bin.jar复制到Tomcat安装目录下的lib文件夹中,然后在MyEclipse中部署项目并运行。接着在浏览器中访问Servlet程序
    在这里插入图片描述
    说明查询成功。

  • 相关阅读:
    rqnoj71 拔河比赛
    NOI2002 洛谷 P1196 银河英雄传说
    sdibt 1244 烦人的幻灯片
    POJ 1273 Drainage Ditches -dinic
    NOIP2005提高组 过河
    OpenJudge 7627 鸡蛋的硬度
    Openjudge 8782 乘积最大
    OpenJudge 7624 山区建小学
    UVa 1328 Period
    UVa 11384 Help is needed for Dexter
  • 原文地址:https://www.cnblogs.com/blizzawang/p/11411383.html
Copyright © 2011-2022 走看看