JDBC实战(七)Apache commons 与开源的数据源连接池DBCP

Apache commons 与开源的数据源连接池DBCP

1、Apache commons

Apache Commons是一个非常有用的工具包,解决各种实际的通用问题 Apache Commons的官网介绍
下面是一些工具包介绍:

类型 描述
BeanUtils Commons-BeanUtils 提供对 Java 反射和自省API的包装
Betwixt Betwixt提供将 JavaBean 映射至 XML 文档,以及相反映射的服务.
Chain Chain 提供实现组织复杂的处理流程的“责任链模式”.
CLI CLI 提供针对命令行参数,选项,选项组,强制选项等的简单API.
Codec Codec 包含一些通用的编码解码算法。包括一些语音编码器, Hex, Base64, 以及URL encoder.
Collections Commons-Collections 提供一个类包来扩展和增加标准的 Java Collection框架
Configuration Commons-Configuration 工具对各种各式的配置和参考文件提供读取帮助.
Daemon 一种 unix-daemon-like java 代码的替代机制
DBCP Commons-DBCP 提供数据库连接池服务
DbUtils DbUtils 是一个 JDBC helper 类库,完成数据库任务的简单的资源清除代码.
Digester Commons-Digester 是一个 XML-Java对象的映射工具,用于解析 XML配置文件.
Discovery Commons-Discovery 提供工具来定位资源 (包括类) ,通过使用各种模式来映射服务/引用名称和资源名称。.
EL Commons-EL 提供在JSP2.0规范中定义的EL表达式的解释器.
FileUpload FileUpload 使得在你可以在应用和Servlet中容易的加入强大和高性能的文件上传能力
HttpClient Commons-HttpClient 提供了可以工作于HTTP协议客户端的一个框架.
IO IO 是一个 I/O 工具集
Jelly Jelly是一个基于 XML 的脚本和处理引擎。 Jelly 借鉴了 JSP 定指标签,Velocity, Cocoon和Xdoclet中的脚本引擎的许多优点。Jelly 可以用在命令行, Ant 或者 Servlet之中。
Jexl Jexl是一个表达式语言,通过借鉴来自于Velocity的经验扩展了JSTL定义的表达式语言。.
JXPath Commons-JXPath 提供了使用Xpath语法操纵符合Java类命名规范的 JavaBeans的工具。也支持 maps, DOM 和其他对象模型。.
Lang Commons-Lang 提供了许多许多通用的工具类集,提供了一些java.lang中类的扩展功能
Latka Commons-Latka 是一个HTTP 功能测试包,用于自动化的QA,验收和衰减测试.
Launcher Launcher 组件是一个交叉平台的Java 应用载入器。 Commons-launcher 消除了需要批处理或者Shell脚本来载入Java 类。.原始的 Java 类来自于Jakarta Tomcat 4.0 项目
Logging Commons-Logging 是一个各种 logging API实现的包裹类.
Math Math 是一个轻量的,自包含的数学和统计组件,解决了许多非常通用但没有及时出现在Java标准语言中的实践问题.
Modeler Commons-Modeler 提供了建模兼容JMX规范的 Mbean的机制.
Net Net 是一个网络工具集,基于 NetComponents 代码,包括 FTP 客户端等等。
Pool Commons-Pool 提供了通用对象池接口,一个用于创建模块化对象池的工具包,以及通常的对象池实现.
Primitives Commons-Primitives提供了一个更小,更快和更易使用的对Java基本类型的支持。当前主要是针对基本类型的 collection。.
Validator commons-validator提供了一个简单的,可扩展的框架来在一个XML文件中定义校验器 (校验方法)和校验规则。支持校验规则的和错误消息的国际化。

2、使用开源DBCP来优化数据源设计

在JDBC里面使用DBCP数据源连接需要两个包

必要时还可以下载

下载以后添加到对应的项目module里面。File-》Project Structure-》Module-》Dependencies
在这里插入图片描述

2.1、使用DBCP替代数据源连接池datasource代码

来看一下之前的代码:

public final class JDBCUtils {
    
    
    private static DataSource datasource;//代理模式的数据源2,实现了DataSource接口
    public static Connection getConnect() throws SQLException {
    
    //异常应该抛出
        return datasource.getConnection();
    }

    static{
    
    //使用class.forName()方法一般用于静态代码块,而且该方法注册驱动不依赖具体的类库
        try {
    
    
            //forName进行类的加载时优先加载静态代码块。
            Class.forName("com.mysql.cj.jdbc.Driver");
            datasource=new DataSource2();
        } catch (ClassNotFoundException e) {
    
    
            e.printStackTrace();
        }
    }


    public static void free(Connection conn, Statement st, ResultSet res) {
    
    
        try {
    
    
            if (res != null) //原则1:晚点连接早点释放。原则2:先创建的后释放
                res.close();
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
                try {
    
    
                    if (st != null)
                        st.close();
                } catch (SQLException e) {
    
    
                    e.printStackTrace();
                } finally {
    
    
                    if (conn != null)
                        try {
    
    
                            conn.close();
                            //datasource.free(conn);//重用,将创建的连接不关闭,而是将其回收到连接池
                        } catch (Exception e) {
    
    
                            e.printStackTrace();
                        }
                }
        }
    }
 }

我们使用的是自己写的简单的数据源连接池实现。现在我们利用DBCP来需改。

第一步:创建配置文件(设置连接的基本属性信息)

在实际开发中我们通常创建一个properties配置文件,然后把数据库参数都放在配置文件中,这样便于数据库参数的管理,当数据库参数变化时可以快速找到配置文件然后进行修改。
在这里插入图片描述
如果你不是创建配置文件,那么你需要在代码里面创建一个properties,然后设置数据库参数,写死了。不够灵活。

第二步,修改数据源的引用和创建
我们只需要修改下面这段代码:

static{
    
    //使用class.forName()方法一般用于静态代码块,而且该方法注册驱动不依赖具体的类库
        try {
    
    
            //forName进行类的加载时优先加载静态代码块。
            Class.forName("com.mysql.cj.jdbc.Driver");
            datasource=new DataSource2();
        } catch (ClassNotFoundException e) {
    
    
            e.printStackTrace();
        }
    }

修改为:

 static{
    
    //使用class.forName()方法一般用于静态代码块,而且该方法注册驱动不依赖具体的类库
        try {
    
    
            //forName进行类的加载时优先加载静态代码块。
            Class.forName("com.mysql.cj.jdbc.Driver");
            //datasource=new DataSource2();
            InputStream inputs = JDBCUtils.class.getClassLoader().getResourceAsStream("DBCP_Config.properties");
            Properties properties = new Properties();
            properties.load(inputs);
            datasource = BasicDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

运行代码报错,原因就是我们利用的加载文件的方式是JDBCUtils.class.getClassLoader().getResourceAsStream(),而我们的文件没有放对位置。其路径,我们可用如下方法打印出来。

  System.out.println(JDBCUtils.class.getClassLoader().getResource(""));

在这里插入图片描述

在将配置文件放到了对应的目录以后运行测试代码

 for(int i=0;i<10;i++){
    
    
            Connection conn = JDBCUtils.getConnect();
            System.out.println(conn);
            JDBCUtils.free(conn,null,null);
        }

报错:
在这里插入图片描述
原因:从理解上看是缺少了一个类文件,logging,即缺少了commons-logging-1.2-bin.tar.gz架包。导入以后运行:
在这里插入图片描述
从输出上看,我们可对比我们自己实现的dataSource,可以说DBCP自己肯定重写了toString方法。输出的是数据库连接的一些信息。

2.2、总结

  • 一,使用DBCP的重点是获取DataSource对象
  • 二,使用DBCP不仅可以节约资源,而且可以直接将查询结果封装成对象,方便使用。
  • 三,在实际开发中建议使用properties配置文件。

猜你喜欢

转载自blog.csdn.net/qq_44861675/article/details/107871172