JDBC-数据连接池的使用

数据库连接池(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

  1. 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

50 

 

oracle.jdbc.driver.OracleDriver

jdbc:mysql://127.0.0.1:3306/school

root

123456

       DBCP连接池使用这个文件可以完成mysql、oracle的连接池的建立,每次只能建立一个,但是另一个需要注释起来。因为我们是根据 名建立连接,

  1. 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方法就可以应用,如下:

  1. 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路径。

  1. 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 list = qr.query(connection, sql, rsh);for (Object[] objects : list) {for (int i = 0; i  list = qr.query(JdbcUtil.getConnection(),  "select * from student", new ColumnListHandler(1));for (Object object : list) {System.out.println(object);}}//MapHandler把第一行数据封装到Map集合中, 列名作为键, 对应值作为值@Testpublic void test8() throws Exception {QueryRunner qr = new QueryRunner();Map map = qr.query(JdbcUtil.getConnection(),  "select * from student", new MapHandler());Set keys = map.keySet();for (String key : keys) {Object value = map.get(key);System.out.println(key + " -------- " + value);}}//MapListHandler把一行数据封装到Map集合中, 并把所有行生成的Map再放入一个List集合@Testpublic void test9() throws Exception {QueryRunner qr = new QueryRunner();List> list = qr.query(JdbcUtil.getConnection(),  "select * from student", new MapListHandler());for (Map map2 : list) {Set keys = map2.keySet();for (String key : keys) {Object value = map2.get(key);System.out.println(key + " -------- " + value);}System.out.println();}}}

登录后复制

到这里就可以统一整理一下自己定义的JdbcUtil工具类、CommonUtil工具类,使自定义的工具类能达到JDButi.JDBC相同的功能,如下:

JdbcUtils.java

  1. 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

  1. 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 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 list = new ArrayList();int cols = resultSet.getMetaData().getColumnCount();while (resultSet.next()) {Object[] dataRow = new Object[cols];for (int i = 0; i  T queryBean(Connection connection, String sql, Class 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  List query(Connection connection, String sql, Class 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 list = new ArrayList();ResultSetMetaData metaData = resultSet.getMetaData();int cols = metaData.getColumnCount();while (resultSet.next()) {T t = clazz.newInstance();for (int i = 0; i 

    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{protected Class clazz; // T泛型究竟是什么类型, 用类模板对象来描述protected QueryRunner qr = new QueryRunner(); // 用于执行通用查询和更新的工具类对象protected Connection connection; // 数据库连接protected String tableName; // 涉及到的表,需要通过构造器初始化赋值public JdbcDAO(String tableName) {// 以下代码的执行者是子类对象,所以this.getClass是获取子类的类模板对象Type type = this.getClass().getGenericSuperclass(); // JdbcDAOif (type instanceof ParameterizedType) {ParameterizedType parameterizedType = (ParameterizedType)type;//JdbcDAOType[] types = parameterizedType.getActualTypeArguments();clazz = (Class)types[0];} else {clazz = (Class)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(clazz), values);} catch (SQLException e) {e.printStackTrace();}return null;}//获得多行记录,封装成javabean对象,保存在list集合中public List getList(String sql, Object... values) {try {return qr.query(connection, sql, new BeanListHandler(clazz), values);} catch (SQLException e) {e.printStackTrace();}return null;}//获得所有记录,封装成javabean对象,保存在list集合中public List getAll() {return getList("select * from " + tableName);}//根据id获取某一条记录,并封装成javabean对象返回public T getById(int id) {return get("select * from " + tableName + " where id = ?", id);}//根据id删除某一条记录,删除成功返回ture,失败返回falsepublic 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);}}
  2. 登录后复制

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

  4.     

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

点点赞赏,手留余香

给TA打赏
共0人
还没有人赞赏,快来当第一个赞赏的人吧!
    数据库

    Jdbc--具体代码实现

    2025-2-21 18:53:14

    数据库

    mysql进阶(二十五)解决数据库NO CONNECTION问题

    2025-2-21 18:53:32

    0 条回复 A文章作者 M管理员
    欢迎您,新朋友,感谢参与互动!
      暂无讨论,说说你的看法吧
    个人中心
    购物车
    优惠劵
    今日签到
    私信列表
    搜索