数据库连接池(connection pool)
在昨天的练习中每一次练习都需要与数据库建立连接,完成时断开连接,然而当处理的数据量特别的时候,就很耗费时间、降低效率,今天我们学习使用连接池,将连接放在连接池中,需要使用的时候从中取出,使用完毕放回池中并不是断开连接。
数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。
数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。
为解决传统开发中的数据库连接问题,可以采用数据库连接池技术。
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。
DBCP连接池
首先我们使用DBCP连接池(一个免费开源的连接池),我们需要先将commons-dbcp-1.4.jar文件放置当前工程下,并配置环境(添加到Build Path)。下面通过一个程序了解如何使用DBCP连接池:
我们在这里和之前一样需要创建一个“dbcp.properties”文件,将必要的参数放入其中,其内容如下,(此文件放在当前工程下),DBCP连接池使用这个文件可以完成mysql、oracle的连接池的建立,但是每次只能建立一个,另一个需要注释起来。
driverClassName = com.mysql.jdbc.Driver
url = jdbc:mysql://127.0.0.1:3306/company
username = root
password = 123456
initialSize = 5
maxActive = 50
maxIdle = 10
#driverClassName = oracle.jdbc.driver.OracleDriver
#url = jdbc:oracle:thin:@127.0.0.1:1521:orcl
#username = scott
#password = tiger
- package com.atguigu.jdbc;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.sql.Connection;import java.sql.SQLException;import java.util.Properties;import javax.sql.DataSource;import org.apache.commons.dbcp.BasicDataSource;import org.apache.commons.dbcp.BasicDataSourceFactory;import org.junit.Test;public class DBCPTest {@Testpublic void test2() throws Exception {Properties properties = new Properties();properties.load(new FileInputStream("dbcp.properties"));DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);System.out.println("inital:" + ((BasicDataSource)dataSource).getInitialSize());System.out.println("getMaxActive:" + ((BasicDataSource)dataSource).getMaxActive());System.out.println("getMaxIdle:" + ((BasicDataSource)dataSource).getMaxIdle());Connection connection = dataSource.getConnection();System.out.println(connection);connection.close();}}
登录后复制
C3P0连接池
下面我们学习一个功能更加强大的连接池,C3P0(仍然是一个免费开源的连接池),如上我们需要先将commons-dbcp-1.4.jar文件放置当前工程下,并配置环境(添加到Build Path)。
这里通过一个程序了解如何使用DBCP连接池:
如同DBCP连接池,我们需要创建一个“c3p0-config.xml”文件,将必要的参数放入其中,其内容如下,(此文件放在当工程的src目录)
com.mysql.jdbc.Driver
jdbc:mysql://127.0.0.1:3306/school
root
123456
5
5
5
50
0
5
oracle.jdbc.driver.OracleDriver
jdbc:mysql://127.0.0.1:3306/school
root
123456
DBCP连接池使用这个文件可以完成mysql、oracle的连接池的建立,每次只能建立一个,但是另一个需要注释起来。因为我们是根据 名建立连接,
- package com.atguigu.jdbc;import java.beans.PropertyVetoException;import java.sql.Connection;import java.sql.SQLException;import javax.sql.DataSource;import org.junit.Test;import com.mchange.v2.c3p0.*;public class C3P0Test {@Testpublic void test1() throws PropertyVetoException, SQLException {DataSource dataSource = new ComboPooledDataSource("mysql-config"); // 它会默认自动去读取文件System.out.println(dataSource);Connection connection = dataSource.getConnection();System.out.println(connection);connection.close();// 把连接归还给连接池DataSources.destroy(dataSource);// 完全释放池中所有连接,并销毁连接池!!}@Testpublic void test2() throws PropertyVetoException, SQLException {DataSource dataSource = new ComboPooledDataSource("oracle-config"); // 它会默认自动去读取文件System.out.println(dataSource);Connection connection = dataSource.getConnection();System.out.println(connection);connection.close();// 把连接归还给连接池DataSources.destroy(dataSource);// 完全释放池中所有连接,并销毁连接池!!}}
登录后复制
学习了连接池之后,JdbcUtil工具类中的getConnection方法就可以应用,如下:
- package com.atguigu.jdbc;import java.io.FileInputStream;import java.io.IOException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.Properties;import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;import com.mchange.v2.c3p0.DataSources;/** * 预备工作 : * 1) 把要访问的数据库相关的驱动程序复制到项目中, 就是jar包 * 2) 配置项目属性, 把jar包导入到本项目的buildpath中 * @author Administrator * */public class JdbcUtil {private static DataSource dataSource; // 声明静态属性对象引用.static {dataSource = new ComboPooledDataSource("mysql-config"); // 连接池对象只需要创建一次就可以了}public static Connection getConnection() throws SQLException {return dataSource.getConnection(); // 要想获取连接, 只需要从连接池中获取,用完以后, 再归还回来}public static Connection getConnectionOld() throws IOException, ClassNotFoundException, SQLException {// 1) 读取配置文件Properties properties = new Properties();properties.load(new FileInputStream("jdbc.properties"));// 2) 获取配置文件中的必要的信息String driverClass = properties.getProperty("driverClass");String url = properties.getProperty("url");String user = properties.getProperty("user");String password = properties.getProperty("password");// 3) 注册驱动 , 加载驱动类Class.forName(driverClass);// 4) 通过驱动管理器获取连接(需要url,用户,密码)return DriverManager.getConnection(url, user, password);// 暗含 new Socket(host,port), 认证,其他各种初始化操作}//关闭连接public static void close(Connection connection) {close(connection, null);}public static void close(Connection connection, Statement statement) {close(connection, statement, null);}public static void close(Connection connection, Statement statement, ResultSet resultSet) {if (resultSet != null) {try {resultSet.close();} catch (Exception e) {e.printStackTrace();}}if (statement != null) {try {statement.close();} catch (Exception e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (Exception e) {e.printStackTrace();}}}//销毁连接池public static void destroy() {try {DataSources.destroy(dataSource);} catch (SQLException e) {e.printStackTrace();}}}
登录后复制
DBUtils工具类
将常用的操作数据库的JDBC的类和方法集合在一起,就是DBUtils.JDBC。提供供我们使用的工具类QueryRunner来执行操作。
在使用之前我们仍然需要将commons-dbutils-1.3.jar添加到当前工程下,并添加到path路径。
- package com.atguigu.jdbc;import java.sql.Connection;import java.sql.SQLException;import java.util.List;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.ArrayListHandler;import org.apache.commons.dbutils.handlers.BeanHandler;import org.apache.commons.dbutils.handlers.BeanListHandler;import org.apache.commons.dbutils.handlers.ScalarHandler;import org.junit.Test;public class QueryRunnerTest {// 使用我们自定义工具实现表的创建@Testpublic void test1() throws SQLException {QueryRunner qr = new QueryRunner();Connection connection = JdbcUtil.getConnection();qr.update(connection, "create table test2(aa int, bb varchar(10))");JdbcUtil.close(connection);}// 使用我们自定义工具向表中插入一条记录@Testpublic void test2() throws SQLException {QueryRunner qr = new QueryRunner();Connection connection = JdbcUtil.getConnection();int rows = qr.update(connection, "insert into test2(aa, bb) values(?,?)", 10, "xxx");System.out.println(rows + " rows");JdbcUtil.close(connection);}// 使用DBUtils.JDBC接口中提供的方法对departments表进行查询,把结果集中的所有记录转换为department对象集合并存入List集合中,然后遍历输出对象@Testpublic void test3() throws SQLException {//query(Connection conn, String sql, ResultSetHandler rsh, Object... params) String sql = "select * from departments where department_id > ?";QueryRunner qr = new QueryRunner();Connection connection = JdbcUtil.getConnection();BeanListHandler rsh = new BeanListHandler(Department.class); // 把结果集中的所有记录转换为对象集合List list = qr.query(connection, sql, rsh, 20);for (Department department : list) {System.out.println(department);}}// 使用DBUtils.JDBC接口中提供的方法对departments表进行查询,把结果集中的一条记录转换为department实体对象,然后输出对象@Testpublic void test4() throws SQLException {String sql = "select * from departments where department_id = ?";QueryRunner qr = new QueryRunner();Connection connection = JdbcUtil.getConnection();BeanHandler rsh = new BeanHandler(Department.class); // 把结果集中的一条记录转换为实体对象Department objDepartment = qr.query(connection, sql, rsh, 20);System.out.println(objDepartment);}// 使用DBUtils.JDBC接口中提供的方法对departments表进行查询,将每一条记录存入集合中,然后遍历输出每一个数据@Testpublic void test5() throws SQLException {String sql = "select * from employees";QueryRunner qr = new QueryRunner();Connection connection = JdbcUtil.getConnection();ArrayListHandler rsh = new ArrayListHandler();List
登录后复制
到这里就可以统一整理一下自己定义的JdbcUtil工具类、CommonUtil工具类,使自定义的工具类能达到JDButi.JDBC相同的功能,如下:
JdbcUtils.java
- package com.atguigu.jdbc;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;import com.mchange.v2.c3p0.DataSources;public class JdbcUtil {private static DataSource dataSource;static {dataSource = new ComboPooledDataSource("config1"); // 它必须依赖文件src/c3p0-config.xml}// 获取c3p0连接池的连接public static Connection getConnection() throws SQLException {return dataSource.getConnection();}public static void close(Connection connection) {close(connection, null);}public static void close(Connection connection, Statement statement) {close(connection, statement, null);}public static void close(Connection connection, Statement statement, ResultSet resultSet) {if (resultSet != null) {try {resultSet.close();} catch (Exception e) {e.printStackTrace();}}if (statement != null) {try {statement.close();} catch (Exception e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (Exception e) {e.printStackTrace();}}}public static void destroy() {try {DataSources.destroy(dataSource);} catch (SQLException e) {e.printStackTrace();}}}
登录后复制
CommonUtil.java
- package com.atguigu.jdbc;import java.lang.reflect.Field;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;public class CommonUtil {/** * 把结果集中的每一行都放入Object对象数组中, 再把所有的Object对象数组放入一个List集合中. * @throws SQLException */public static List
登录后复制
以上就是JDBC-数据连接池的使用 的内容,更多相关内容请关注PHP中文网(www.php.cn)!