Home > Database > Mysql Tutorial > body text

JDBC-Usage of data connection pool

黄舟
Release: 2017-02-11 11:07:12
Original
980 people have browsed it


Database connection pool (connection pool)

In yesterday’s exercise, each exercise required establishing a connection with the database. Complete However, when the amount of data processed is special, it is very time-consuming and reduces efficiency. Today we learn to use the connection pool, put the connection in the connection pool, and take it out when needed, Putting it back into the pool after use does not mean disconnecting it.

The basic idea of ​​database connection pool is to establish a "buffer pool" for database connections. Put a certain number of connections in the buffer pool in advance. When you need to establish a database connection, you only need to take one out of the "buffer pool" and put it back after use.
The database connection pool will create a certain number of database connections and put them into the connection pool during initialization. The number of these database connections is set by the minimum number of database connections. Regardless of whether these database connections are used or not, the connection pool will always be guaranteed to have at least this many connections. The maximum number of database connections in the connection pool limits the maximum number of connections that the connection pool can occupy. When the number of connections requested by the application from the connection pool exceeds the maximum number of connections, these requests will be added to the waiting queue.
In order to solve the database connection problem in traditional development, database connection pool technology can be used.
The database connection pool is responsible for allocating, managing and releasing database connections. It allows applications to reuse an existing database connection instead of re-establishing one.

DBCP Connection Pool

First we use the DBCP connection pool (a free and open source connection pool). We need to first place the commons-dbcp-1.4.jar file under the current project. and configure the environment (add to Build Path). Let's learn how to use DBCP connection pool through a program:


We need to create a "dbcp.properties" file here as before and put the necessary parameters into it. Its content is as follows, (this file is placed under the current project). The DBCP connection pool can use this file to complete the establishment of mysql and oracle connection pools, but only one can be created at a time, and the other one needs to be commented.

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 {
	@Test
	public 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();
	}
}
Copy after login


C3P0 connection pool

Next we learn a more powerful connection pool, C3P0 (still a free and open source connection pool). As above, we need to first commons-dbcp -1.4.jar file is placed under the current project and the environment is configured (added to Build Path).


Here is a program to learn how to use DBCP connection pool:

Like DBCP connection pool, we need to create a "c3p0-config.xml" file and put the necessary parameters into Among them, the content is as follows, (this file is placed in the src directory of the current project)



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 {
	@Test
	public 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);// 完全释放池中所有连接,并销毁连接池!!
	}		
		
	@Test
	public 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);// 完全释放池中所有连接,并销毁连接池!!
	}	
}
Copy after login


学习了连接池之后,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();
		}
	}	
}
Copy after login


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 {

	// 使用我们自定义工具实现表的创建
	@Test
	public 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);
	}	
	
	// 使用我们自定义工具向表中插入一条记录
	@Test
	public 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集合中,然后遍历输出对象
	@Test
	public void test3() throws SQLException {
		//query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) 
		String sql = "select * from departments where department_id > ?";
		QueryRunner qr = new QueryRunner();
		Connection connection = JdbcUtil.getConnection();
		BeanListHandler<Department> rsh = new BeanListHandler<Department>(Department.class); // 把结果集中的所有记录转换为对象集合
		List<Department> list = qr.query(connection, sql, rsh, 20);
		for (Department department : list) {
			System.out.println(department);
		}
	}	
	
	// 使用DBUtils.JDBC接口中提供的方法对departments表进行查询,把结果集中的一条记录转换为department实体对象,然后输出对象
	@Test
	public void test4() throws SQLException {
		String sql = "select * from departments where department_id = ?";
		QueryRunner qr = new QueryRunner();
		Connection connection = JdbcUtil.getConnection();
		BeanHandler<Department> rsh = new BeanHandler<Department>(Department.class); // 把结果集中的一条记录转换为实体对象
		Department objDepartment = qr.query(connection, sql, rsh, 20);
		System.out.println(objDepartment);
	}
	
	// 使用DBUtils.JDBC接口中提供的方法对departments表进行查询,将每一条记录存入集合中,然后遍历输出每一个数据
	@Test
	public void test5() throws SQLException {
		String sql = "select * from employees";
		QueryRunner qr = new QueryRunner();
		Connection connection = JdbcUtil.getConnection();
		ArrayListHandler rsh = new ArrayListHandler();
		List<Object[]> list = qr.query(connection, sql, rsh);
		for (Object[] objects : list) {
			for (int i = 0; i < objects.length; i++) {
				System.out.print(objects[i] + "\t");
			}
			System.out.println();
		}
	}		
		
	// 使用DBUtils.JDBC接口中提供的方法对departments表进行查询,将查询到的一个数据输出	
	@Test
	public void test6 () throws SQLException {
		String sql = "select count(*) from world.country";
		QueryRunner qr = new QueryRunner();
		Connection connection = JdbcUtil.getConnection();
		ScalarHandler rsh = new ScalarHandler();
		Object singleValue = qr.query(connection, sql, rsh);
		System.out.println(singleValue);
	}	
	
		
	@Test
	public void test7() throws Exception {
		QueryRunner qr = new QueryRunner();
		List<Object> list = qr.query(JdbcUtil.getConnection(),  "select * from student", new ColumnListHandler(1));
		for (Object object : list) {
			System.out.println(object);
		}
	}

	//MapHandler把第一行数据封装到Map集合中, 列名作为键, 对应值作为值
	@Test
	public void test8() throws Exception {
		QueryRunner qr = new QueryRunner();
		Map<String, Object> map = qr.query(JdbcUtil.getConnection(),  "select * from student", new MapHandler());
		Set<String> keys = map.keySet();
		for (String key : keys) {
			Object value = map.get(key);
			System.out.println(key + " -------- " + value);
		}
	}	
		
	//MapListHandler把一行数据封装到Map集合中, 并把所有行生成的Map再放入一个List集合
	@Test
	public void test9() throws Exception {
		QueryRunner qr = new QueryRunner();
		List<Map<String, Object>> list = qr.query(JdbcUtil.getConnection(),  "select * from student", new MapListHandler());
		for (Map<String, Object> map2 : list) {
			Set<String> keys = map2.keySet();
			for (String key : keys) {
				Object value = map2.get(key);
				System.out.println(key + " -------- " + value);
			}
			System.out.println();
		}
	}	
}
Copy after login

到这里就可以统一整理一下自己定义的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();
		}
	}
}
Copy after login


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<Object[]> query(Connection connection, String sql, Object... values) throws SQLException {
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		try {
			preparedStatement = connection.prepareStatement(sql);
			fillArguments(preparedStatement, values);
			resultSet = preparedStatement.executeQuery();
			List<Object[]> list = new ArrayList<Object[]>();
			int cols = resultSet.getMetaData().getColumnCount();
			while (resultSet.next()) {
				Object[] dataRow = new Object[cols];
				for (int i = 0; i < dataRow.length; i++) {
					dataRow[i] = resultSet.getObject(i + 1);
				}
				list.add(dataRow);
			}
			return list;
		} finally {
			JdbcUtil.close(null, preparedStatement, resultSet);
		}
	}

	/**
	 * 把结果集中的第一行数据,全放入一个对象数组中
	 * @throws SQLException 
	 */
	public static Object[] queryValueArray(Connection connection, String sql, Object... values) throws SQLException {
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		try {
			preparedStatement = connection.prepareStatement(sql);
			fillArguments(preparedStatement, values);
			resultSet = preparedStatement.executeQuery();
			if (resultSet.next()) {
				Object[] dataRow = new Object[resultSet.getMetaData().getColumnCount()];
				for (int i = 0; i < dataRow.length; i++) {
					dataRow[i] = resultSet.getObject(i + 1);
				}
				return dataRow;
			} else {
				return null;
			}
		} finally {
			JdbcUtil.close(null, preparedStatement, resultSet);
		}
	}
	
	/**
	 * 从结果集中获取第一行的第一列
	 * @throws SQLException 
	 */
	public static Object queryValue(Connection connection, String sql, Object... values) throws SQLException {
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		try {
			preparedStatement = connection.prepareStatement(sql);
			fillArguments(preparedStatement, values);
			resultSet = preparedStatement.executeQuery();
			if (resultSet.next()) {
				return resultSet.getObject(1);
			} else {
				return null;
			}
		} finally {
			JdbcUtil.close(null, preparedStatement, resultSet);
		}
	}
	
	/**
	 * 把结果集中第一行转换为对象返回
	 * @throws SQLException 
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public static <T> T queryBean(Connection connection, String sql, Class<T> clazz, Object... values) throws SQLException, 
	NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		try {
			preparedStatement = connection.prepareStatement(sql);
			
			fillArguments(preparedStatement, values);
			
			resultSet = preparedStatement.executeQuery();
			if (resultSet.next()) {
				T t = clazz.newInstance();
				ResultSetMetaData metaData = resultSet.getMetaData();
				int cols = metaData.getColumnCount();
				for (int i = 0; i < cols; i++) {
					String label = metaData.getColumnLabel(i + 1);
					Object value = resultSet.getObject(label);
					Field field = clazz.getDeclaredField(label);
					field.setAccessible(true);
					field.set(t, value);
				}
				return t;
			} else {
				return null;
			}
		} finally {
			JdbcUtil.close(null, preparedStatement, resultSet);
		}
	}

	/**
	 * 把结果集的所有记录都封装成对象,并把所有对象放在一个List集合中
	 * @throws SQLException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 */
	public static <T> List<T> query(Connection connection, String sql, Class<T> clazz, Object... values) throws SQLException, 
	InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		try {
			preparedStatement = connection.prepareStatement(sql);
			
			fillArguments(preparedStatement, values);
			
			resultSet = preparedStatement.executeQuery();
			List<T> list = new ArrayList<T>();
			ResultSetMetaData metaData = resultSet.getMetaData();
			int cols = metaData.getColumnCount();
			while (resultSet.next()) {
				T t = clazz.newInstance();
				for (int i = 0; i < cols; i++) {
					String label = metaData.getColumnLabel(i + 1);
					Object value = resultSet.getObject(label);
					if (value != null) {
						Field field = clazz.getDeclaredField(label);
						field.setAccessible(true);
						field.set(t, value);
					}
				}
				list.add(t);
			}
			return list;
		} finally {
			JdbcUtil.close(null, preparedStatement, resultSet);
		}
	}
	
	/**
	 * 通用更新操作
	 * @throws SQLException 
	 */
	public static int update(Connection connection, String sql, Object... values) throws SQLException {
		PreparedStatement preparedStatement = null;
		try {
			preparedStatement = connection.prepareStatement(sql);
			fillArguments(preparedStatement, values);
			return preparedStatement.executeUpdate();
		} finally {
			JdbcUtil.close(null, preparedStatement);
		}
	}
	
	public static void fillArguments(PreparedStatement preparedStatement, Object... values) throws SQLException {
		for (int i = 0; i < values.length; i++) {
			preparedStatement.setObject(i + 1, values[i]);
		}
	}	
}
Copy after login

BaseDAO

综合之前学习过的知识,在这里创建一个BaseDAO类借助DBUtils工具类实现数据操作功能:


package com.atguigu.jdbc;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

public class BaseDAO<T>{

	protected Class<T> clazz; // T泛型究竟是什么类型, 用类模板对象来描述
	protected QueryRunner qr = new QueryRunner(); // 用于执行通用查询和更新的工具类对象
	protected Connection connection; // 数据库连接
	protected String tableName; // 涉及到的表,需要通过构造器初始化赋值
	
	public JdbcDAO(String tableName) {
		// 以下代码的执行者是子类对象,所以this.getClass是获取子类的类模板对象
		Type type = this.getClass().getGenericSuperclass(); // JdbcDAO<Teacher>
		if (type instanceof ParameterizedType) {
			ParameterizedType parameterizedType = (ParameterizedType)type;//JdbcDAO<Teacher>
			Type[] types = parameterizedType.getActualTypeArguments();
			clazz = (Class<T>)types[0];
		} else {
			clazz = (Class<T>)Object.class;
		}
		// 获取一个连接供所有方法使用
		try {
			connection = JdbcUtil.getConnection();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		this.tableName = tableName;
	}
	
	//获得记录中具体的一个数据
	public Object getValue(String sql, Object... values) {
		try {
			return qr.query(connection, sql, new ScalarHandler(), values);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	//获得一行数据并封装成javabean对象
	public T get(String sql, Object... values) {
		try {
			return qr.query(connection, sql, new BeanHandler<T>(clazz), values);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}

	//获得多行记录,封装成javabean对象,保存在list集合中
	public List<T> getList(String sql, Object... values) {
		try {
			return qr.query(connection, sql, new BeanListHandler<T>(clazz), values);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	
	//获得所有记录,封装成javabean对象,保存在list集合中
	public List<T> getAll() {
		return getList("select * from " + tableName);
	}
	
	//根据id获取某一条记录,并封装成javabean对象返回
	public T getById(int id) {
		return get("select * from " + tableName + " where id = ?", id);
	}
	
	//根据id删除某一条记录,删除成功返回ture,失败返回false
	public boolean deleteById(int id) {
		int rows = update("delete from " + tableName + " where id = ?", id);
		if (rows > 0) {
			return true;
		}
		return false;
	}

	//通用的更新操作
	public int update(String sql, Object... values) {
		try {
			return qr.update(connection, sql, values);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return 0;
	}
	
	//关闭连接
	public void close() {
		JdbcUtil.close(connection);
	}
}
Copy after login


以上就是JDBC-数据连接池的使用 的内容,更多相关内容请关注PHP中文网(www.php.cn)!







    

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!