四、MySQL数据库之连接池和DBUtils(1)

本文详细介绍了数据库连接池的概念、原理及常见的第三方连接池,如C3P0和Druid。C3P0配置包括初始化连接数、最大连接数等参数,而Druid以其高性能和监控特性受到广泛应用。同时,文章讲解了DBUtils工具类的使用,包括QueryRunner如何进行数据的增删改查操作,以及ResultSetHandler接口在查询结果处理中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 连接池

1.1 连接池概述

Connection对象在JDBC使用的时候就会去创建一个对象,使用结束以后就会将这个对象给销毁了(close).每次创建和销毁对象都是耗时操作.需要使用连接池对其进行优化.
为了解决建立数据库连接耗费资源和时间很多的问题

1.2 连接池原理

在这里插入图片描述

  1. 程序一开始就创建一定数量的连接,放在一个容器中,这个容器称为连接池(相当于碗柜/容器)。
  2. 使用的时候直接从连接池中取一个已经创建好的连接对象。
  3. 关闭的时候不是真正关闭连接,而是将连接对象再次放回到连接池中。

1.3 常见第三方连接池

面向接口编程:
Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商需要让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池!

  • C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。C3P0是异步操作的,所以一些操作时间过长的JDBC通过其它的辅助线程完成。目前使用它的开源项目有Hibernate,Spring等。C3P0有自动回收空闲连接功能
  • 阿里巴巴-德鲁伊druid连接池:Druid是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和SQL解析器组成。该项目主要是为了扩展JDBC的一些限制,可以让程序员实现一些特殊的需求。
  • DBCP(DataBase Connection Pool)数据库连接池,是Apache上的一个Java连接池项目,也是Tomcat使用的连接池组件。dbcp没有自动回收空闲连接的功能。(已经过时抛弃

1.4 C3P0连接池

C3P0开源免费的连接池!目前使用它的开源项目有:Spring、Hibernate等。使用C3P0连接池需要导入jar包,c3p0使用时还需要添加配置文件“c3p0-config.xml”

 *  C3p0连接池的使用
 *    开发人员来说: 从连接池中,拿连接使用
 *    肯定实现接口 DataSource
 *
 *  使用步骤:
 *    1: 导入jar包
 *    2: 连接数据库的4大信息为必须有
 *       配置文件中(固定位置、固定名称)
 *       A: 文件名字 c3p0-config.xml
 *       B: 文件放在src下
 *
 *   3: 创建出DataSource接口实现类
 *     实现类方法Connection getConnection()  获取连接使用

2 编写配置文件 c3p0-config.xml

<c3p0-config>
    <!-- 使用默认的配置读取连接池对象 -->
    <default-config>
        <!--  连接参数 -->
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/mydatabase</property>
        <property name="user">root</property>
        <property name="password">root</property>
        <!-- 连接池参数 -->
        <property name="initialPoolSize">5</property>
    </default-config>
</c3p0-config>

c3p0连接池常用的配置参数:
c3p0连接池常用的配置参数:

参数说明
initialPoolSize初始连接数
maxPoolSize最大连接数
checkoutTimeout最大等待时间
maxIdleTime最大空闲回收时间

初始连接数:刚创建好连接池的时候准备的连接数量
最大连接数:连接池中最多可以放多少个连接
最大等待时间:连接池中没有连接时最长等待时间
最大空闲回收时间:连接池中的空闲连接多久没有使用就会回收


3 使用厂商提供的DataSource接口实现类,创建连接池

public class C3P0Utils {
    //3: 创建出DataSource接口实现类的对象
    /**
     *  类C3p0Utils只要进入内存,加载静态成员
     *  创建接口DataSource的实现类对象new ComboPooledDataSource()
     *  实现类对象,会自动读取配置文件!!
     */
    private static DataSource dataSource = new ComboPooledDataSource();

    //提供方法,返回连接对象
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    //定义方法,获取DataSource接口实现类
    public static DataSource getDataSource(){
        return dataSource;
    }
}

1.5 Druid 连接池

Druid是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是国内目前最好的数据库连接池。在功能、性能、扩展性方面,都超过其他数据库连接池。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。如:一年一度的双十一活动,每年春运的抢火车票。

Druid的下载地址:https://github.com/alibaba/druid

DRUID连接池使用的jar包:druid-1.1.16.jar

 *  阿里巴巴的连接池 Druid 德鲁伊连接池
 *  目的: 从连接池中取出连接
 *
 *  实现步骤:
 *    1: 导入jar包
 *    2: 创建druid.properties, 放在src目录下(数据库连接的四大要素)
 *        对比C3P0的配置文件名字任意,存储位置任意
 *		   我们自己读取配置文件的内容
 *
 *    3: 创建DataSource接口实现类
 *      实现类的方法 getConnection()获取连接

1 编写druid.properties的配置文件

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydatabase
username=root
password=root

2 使用厂商提供的DataSource接口实现类,创建连接池

public class DruidUtils {
    //创建DataSource接口变量
    private static DataSource dataSource ;

    static {
        try {
            //自己读取配置文件
            InputStream inputStream = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            //流中的数据,存储在集合中
            Properties properties = new Properties();
            properties.load(inputStream);
            //3: 创建DataSource接口实现类
            //设计模式,工厂设计模式,通过工厂类获取对象
            //工厂类获取 接口 DataSource对象
            //DruidDataSourceFactory方法.createDataSource()
            //日历类; Calendar c = Calendar.getInstance();
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        }catch (Exception ex){
            ex.printStackTrace();
        }

    }
    //定义方法,获取连接对象
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    //定义方法,获取DataSource接口实现类
    public static DataSource getDataSource(){
        return dataSource;
    }
}

2 DBUtils

如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC开发,本案例我们讲采用apache commons组件一个成员:DBUtils。

DBUtils就是JDBC的简化开发工具包。需要项目导入commons-dbutils-1.6.jar才能够正常使用DBUtils工具。

2.1 DBUtils概述

DBUtils是java编程中的数据库操作实用工具,小巧简单实用。DBUtils封装了对JDBC的操作简化了JDBC操作,可以少写代码。

Dbutils三个核心功能介绍

  • QueryRunner中提供对sql语句操作的API.
  • ResultSetHandler接口,用于定义select操作后,怎样封装结果集.
  • DbUtils类,它就是一个工具类,定义了关闭资源与事务处理的方法

2.2 QueryRunner核心类介绍

A 提供连接

  • 构造方法
    • QueryRunner() 创建核心类,提供无参构造方法
  • 普通方法
    • update(Connection conn , String sql , Object ... params) 使用提供的Connection,完成DML语句
    • query(Connection conn , String sql , ResultSetHandler , Object ... params) 使用提供的Connection,执行DQL语句,并将查询结果封装到对象中。

B 提供数据源DataSource

  • 构造方法
    • QueryRunner(DataSource) 创建核心类,并提供数据源,内部自己维护Connection
  • 普通方法
    • update(String sql , Object ... params) 执行DML语句
    • query(String sql , ResultSetHandler , Object ... params) 执行DQL语句,并将查询结果封装到对象中。
2.2.1 QueryRunner实现添加、更新、删除操作
  • update(Connection conn , String sql , Object ... params) 使用提供的Connection,完成DML语句
/**
 *  使用DBUtils工具类,实现数据的 insert,update,delete
 *  核心类 QueryRunner执行SQL语句
 *  1: 创建对象
 *    无参数构造,直接new
 *    QueryRunner(DataSource ds) 传递DataSource接口实现类的对象
 *    c3p0,druid  自己从连接池中取连接
 *
 *  2: 调用方法update
 *   int  update(Connection conn, String sql, Object... params)
 *      conn连接对象
 *      sql SQL语句
 *      params SQL语句中的问号占位符
 *
 Execute an SQL INSERT, UPDATE, or DELETE query.
 */
public class DBUtilsDemo {
    public static void main(String[] args) throws SQLException {
        delete();
    }
    /**
     * 实现删除数据
     */
    public static void delete()throws SQLException{
        //创建QueryRunner的对象
        QueryRunner qr = new QueryRunner();
        //删除的SQL
        String sql = "delete from product where pid = ?";
        //参数,直接传递主键
        int row = qr.update(DruidUtils.getConnection(), sql, 14);
        System.out.println(row);
    }

    /**
     *  实现更新数据
     */
    public static void update()throws SQLException{
        //创建QueryRunner的对象
        QueryRunner qr = new QueryRunner();
        //拼写update语句
        String sql = "update product set pname = ? , price = ? ,category_id = ? where pid = ?";
        //问号中参数,定义在数组中
        Object[] params = {"老年机",199,"c001",15};
        //update方法执行SQL
        int row = qr.update(DruidUtils.getConnection(), sql, params);
        System.out.println(row);
    }


    /**
     *  实现数据的添加
     */
    public static void insert()throws SQLException{
        //创建QueryRunner的对象
        QueryRunner qr = new QueryRunner();
        //拼写添加数据的SQL
        String sql = "insert into product values(?,?,?,?)";
        //执行update方法
        //传递数据库连接对象,c3p0,druid
        //SQL语句中参数,存储在数组,代码可读性,维护性提高
        Object[] params = {null,"8848手机",1898,"c001"};
        int row = qr.update(DruidUtils.getConnection(),sql,params);
        System.out.println(row);
    }
}


2.2.2 QueryRunner实现查询操作
  • query(String sql, ResultSetHandler<T> rsh, Object... params) 用来完成表数据的查询操作

ResultSetHandler 结果集

  • BeanHandler:将结果集中第一条记录封装到一个指定的javaBean中。
  • BeanListHandler:将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中
  • ScalarHandler:它是用于单数据。例如select count(*) from 表操作。
  • ColumnListHandler:将结果集中指定的列的字段值,封装到一个List集合中
    在这里插入图片描述

JavaBean

JavaBean就是一个类,在开发中常用语封装数据。具有如下特性

  1. 需要实现接口:java.io.Serializable ,通常实现接口这步骤省略了,不会影响程序。
  2. 提供私有字段:private 类型 字段名;
  3. 提供getter/setter方法:
  4. 提供无参构造
import lombok.Data;

import java.io.Serializable;

/**
 *   一个类包含私有成员变量,包含get/set方法,包含无参数构造
 *    称为JavaBean对象
 *    应该可以被序列化 (目前省略)
 */
@Data
public class Product {
    private int  pid ;
    private String pname ;
    private double price ;
    private String category_id ;
}

实例:

/**
 *  实现查询
 *  1: QueryRunner构造方法
 *    QueryRunner(DataSource ds) 传递接口实现类
 *    接口的实现类,数据源,连接池
 *    QueryRunner自动从连接池取出连接使用
 *
 *  2: JavaBean对象
 *    一个类包含私有成员变量,包含get/set方法,包含无参数构造
 *    称为JavaBean对象
 *
 *   QueryRunner类的方法 query执行查询 Select语句
 *   query(String sql, ResultSetHandler<T> rsh, Object... params)
 *   参数 sql :传递执行的select语句
 *   参数 rsh: 是接口ResultSetHandler的实现类对象
 *      ResultSetHandler:表示的是查询后的结果集
 *      接口实现类:
 *        BeanHandler :  查询数据表的第一行数据,存储到JavaBean对象
 *        BeanListHandler : 查询数据表,数据的每一行存储到JavaBean对象,多个JavaBean对象,存储到List集合
 *        ColumnListHandler : 查询数据表中的一个列的数据,存储到List集合
 *        ScalarHandler : 适合单值查询,结果集只有一个值 count(*)
 *
 *
 *   参数params: SQL语句中问号占位符参数
 *
 */
public class DBUtilsDemo02 {
    public static void main(String[] args) throws SQLException {
        scalarHandler();
    }
    /**
     * ScalarHandler : 适合单值查询,结果集只有一个值 count(*)
     * 查询的结果集只有一个值,例如聚合函数  avg max min  sum
     * select pname from product where pid = 1;
     */
    public static void scalarHandler()throws SQLException{
        //创建QueryRunner对象,构造方法,传递DataSource接口实现类
        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
        //查询表中共有多少条数据
        String sql = "select count(pid) from product";
        Long object = qr.query(sql,new ScalarHandler<Long>());
        System.out.println(object);
    }

    /**
     * ColumnListHandler : 查询数据表中的一个列的数据,存储到List集合
     */
    public static void columnListHandler()throws SQLException{
        //创建QueryRunner对象,构造方法,传递DataSource接口实现类
        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
        //拼写查询语句
        String sql = "select * from product ";
        //执行查询语句,传递的对象是ColumnListHandler,要一个列的数据
        //ColumnListHandler(String columnName)传递参数,是列名
        List<Object> list = qr.query(sql,new ColumnListHandler<Object>("pname"));
        for(Object o : list){
            System.out.println(o);
        }

    }

    /**
     * BeanListHandler : 查询数据表,数据的每一行存储到JavaBean对象,
     * 多个JavaBean对象,存储到List集合
     * 查询不到数据,集合是存在的,长度=0
     */
    public static void  beanListHandler()throws SQLException{
        //创建QueryRunner对象,构造方法,传递DataSource接口实现类
        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
        //拼写查询语句
        String sql = "select * from product ";
        // 方法query执行SQL语句,传递结果集处理对象 BeanListHandler(传递JavaBean类的class对象)
        List<Product> list = qr.query(sql,new BeanListHandler<Product>(Product.class));
        for(Product product :list){
            System.out.println(product);
        }
    }

    /**
     *  BeanHandler :  查询数据表的第一行数据,存储到JavaBean对象
     *  JavaBean对象是 Product
     */
    public static void  beanHandler()throws SQLException{
        //创建QueryRunner类对象,有参数构造方法,传递DataSource接口实现类
        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());
        //拼写查询语句
        String sql = "select * from product ";
        //方法query执行SQL语句
        //传递结果集BeanHandler(Class<T> type) 传递JavaBean类的class文件对象
        Product product =  qr.query(sql,new BeanHandler<Product>(Product.class));
        System.out.println(product);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值