数据库-连接池技术

纲要:

1.数据库连接池 概念
2.连接池技术分类、
3.具体用法
	a.C3P0连接池技术
	b.Druid连接池技术

数据库连接池

一:

1)概念:

a.其实就是一个容器(集合),存放数据库连接的容器。
b.当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。

2) 原理:

连接池基本的思想是在系统初始化的时候,将数据库连作为对象存储在内存中,
当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。
使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,
以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。
同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。
也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。

3) 实现:

标准接口:DataSource   javax.sql包下的
方法:
	* 获取连接:getConnection()
	* 归还连接:Connection.close()
	(如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接)



二:

分类

1)C3P0:

是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate [2]  一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。

2)Druid:

Druid不仅是一个数据库连接池,还包含一个ProxyDriver、一系列内置的JDBC组件库、一个SQL Parser。支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等。
Druid针对Oracle和MySql做了特别优化,
比如:
Oracle的PS Cache内存占用优化
MySql的ping检测优化
Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。
简单SQL语句用时10微秒以内,复杂SQL用时30微秒。
通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter,就是通过Druid的SQL Parser分析语义实现的

3)Proxool:

是一个Java SQL Driver驱动程序,提供了对选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中,完全可配置,快速、成熟、健壮。可以透明地为现存的JDBC驱动程序增加连接池功能。

4)Jakarta DBCP:

DBCP是一个依赖Jakartacommons-pool对象池机制的数据库连接池。DBCP可以直接的在应用程序中使用。

5)DDConnectionBroker:

是一个简单、轻量级的数据库连接池。

6)DBPool:

是一个高效、易配置的数据库连接池。它除了支持连接池应有的功能之外,还包括了一个对象池,使用户能够开发一个满足自己需求的数据库连接池。

7)XAPool:

是一个XA数据库连接池。它实现了javax.sql.XADataSource并提供了连接池工具。

8)Primrose:

是一个Java开发的数据库连接池。当前支持的容器包括Tomcat4&5、Resin3与JBoss3。它同样也有一个独立的版本,可以在应用程序中使用而不必运行在容器中。Primrose通过一个WEB接口来控制SQL处理的追踪、配置,以及动态池管理。在重负荷的情况下可进行连接请求队列处理。

9)SmartPool:

是一个连接池组件,它模仿应用服务器对象池的特性。SmartPool能够解决一些临界问题如连接泄漏(connection leaks)、连接阻塞、打开的JDBC对象(如Statements、PreparedStatements)等。SmartPool的特性包括:
支持多个pool、自动关闭相关联的JDBC对象、在所设定time-outs之后察觉连接泄漏、追踪连接使用情况、强制启用最近最少用到的连接、把SmartPool“包装”成现存的一个pool

10)MiniConnectionPoolManager:

是一个轻量级JDBC数据库连接池。它只需要Java1.5(或更高)并且没有依赖第三方包。

11)BoneCP:

是一个快速、开源的数据库连接池。帮用户管理数据连接,让应用程序能更快速地访问数据库。比C3P0/DBCP连接池速度快25倍。

三:

具体用法 1:C3P0连接池技术

	* 步骤:
		1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
			* 不要忘记导入数据库驱动jar包
		2. 定义配置文件:
			* 名称: c3p0.properties 或者 c3p0-config.xml
			* 路径:直接将文件放在src目录下即可。

		3. 创建核心对象 数据库连接池对象 ComboPooledDataSource
		4. 获取连接: getConnectionJDBCUtils

1)导入配置文件

使用c3p0所需要的配置文件:c3p0-config.xml【配置文件一定放在src路径下 ,其中的“问号”为根据个人配置必须修改的内容】

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/???</property>
    <property name="user">???</property>
    <property name="password">???</property>
    <!-- 其他设置 -->
    <!-- 连接超时设置30秒 -->   
    <property name="checkoutTimeout">3000</property>  
    <!-- 30秒检查一次connection的空闲 -->  
    <property name="idleConnectionTestPeriod">30</property>  
    <!--初始化的池大小 -->   
    <property name="initialPoolSize">2</property>  
    <!-- 最多的一个connection空闲时间 -->    
    <property name="maxIdleTime">30</property>  
    <!-- 最多可以有多少个连接connection -->  
    <property name="maxPoolSize">5</property>  
    <!-- 最少的池中有几个连接 -->  
    <property name="minPoolSize">2</property>  
    <!-- 批处理的语句 -->  
    <property name="maxStatements">50</property>  
    <!-- 每次增长几个连接 -->  
    <property name="acquireIncrement">3</property>  
  </default-config>

</c3p0-config>

2):导入JDBCUtils工具类

package com.itheima.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JdbcUtils {
    private static DataSource ds = new ComboPooledDataSource();

    /**
     * 获取连接
     * @return
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    /**
     * 获取数据库连接池
     * @return
     */
    public static DataSource getDataSource(){
        return ds;
    }

    /**
     * 释放资源
     *
     * @param stmt
     * @param conn
     */
    public static void close(ResultSet rs, Statement stmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

3):项目中代码实现示例

其中个别内容需根据个人项目情况进行修改

@Test
 public void test1() throws SQLException {
         //1. 创建连接池对象 --- 会自动的加载配置文件 c3p0-config.xml
         ComboPooledDataSource ds = new ComboPooledDataSource();
         //2. 获取连接
         Connection connection = ds.getConnection();
         //3.定义sql语句
         String sql = "select * from student ";
         //4.获取执行sql的对象 Statement
         Statement stmt = connection.createStatement();
         //5.执行sql
         ResultSet rs = stmt.executeQuery(sql);
         //6.处理结果
         while(rs.next()){
                 System.out.println(rs.getObject("name")+" "+rs.getObject("age"));
         }
         //7.释放资源
         JdbcUtils.close(rs,stmt,connection);
 }

具体用法 2:Druid连接池技术

	* 步骤:
		1. 导入jar包 druid-1.0.9.jar
		2. 定义配置文件:
			* 是properties形式的
			* 可以叫任意名称,可以放在任意目录下
		3. 加载配置文件。Properties
		4. 获取数据库连接池对象:通过工厂来来获取  DruidDataSourceFactory
		5. 获取连接:getConnection

1):导入Druid配置文件

使用druid所需要的配置文件:druid.properties【配置文件一定放在src路径下 ,其中的“问号”为根据个人配置必须修改的内容】

# 连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/???
username=???
password=???

# 初始化连接
initialSize=10

#最大连接数量
maxActive=50

# 最大空闲连接
maxIdle=20

# 最小空闲连接
minIdle=5

# 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒
maxWait=60000

2):导入JDBCUtils工具类

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/*
	1. 声明静态数据源成员变量
	2. 创建连接池对象
	3. 定义公有的得到数据源的方法
	4. 定义得到连接对象的方法
	5. 定义关闭资源的方法
 */
public class JDBCUtils {
    // 1.	声明静态数据源成员变量
    private static DataSource ds;

    // 2. 创建连接池对象
    static {
        // 加载配置文件中的数据
        InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
        Properties pp = new Properties();
        try {
            pp.load(is);
            // 创建连接池,使用配置文件中的参数
            ds = DruidDataSourceFactory.createDataSource(pp);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 3. 定义公有的得到数据源的方法
    public static DataSource getDataSource() {
        return ds;
    }

    // 4. 定义得到连接对象的方法
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    // 5.定义关闭资源的方法
    public static void close(Connection conn, Statement stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {}
        }

        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {}
        }

        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {}
        }
    }

    // 6.重载关闭方法
    public static void close(Connection conn, Statement stmt) {
        close(conn, stmt, null);
    }
}

3):项目中代码实现示例

其中个别内容需根据个人项目情况进行修改

@Test
public void test1() throws Exception {
     //1. 加载配置文件
     Properties properties = new Properties();
     properties.load(DruidDataSourceTest.class.getClassLoader().getResourceAsStream("druid.properties"));
     // 2. 创建数据库连接池
     DataSource ds = DruidDataSourceFactory.createDataSource(properties);
     //3. 获取连接
     Connection connection = ds.getConnection();
     //4.定义sql语句
     String sql = "select * from student ";
     //4.获取执行sql的对象 Statement
     Statement stmt = connection.createStatement();
     //5.执行sql
     ResultSet rs = stmt.executeQuery(sql);
     //6.处理结果
     while(rs.next()){
             System.out.println(rs.getObject("name")+" "+rs.getObject("age"));
     }
     //7.释放资源
     JdbcUtils.close(rs,stmt,connection);
}

猜你喜欢

转载自blog.csdn.net/weixin_43095615/article/details/82830217