ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Java Web(day12) —— 数据库连接池与DBUtils工具

2022-01-08 19:31:27  阅读:181  来源: 互联网

标签:Web Java java 数据库 Connection day12 sql import 连接池


一、数据库连接池

1、数据库连接池的概念

   用池来管理Connection,这可以重复使用Connection。有了池,所以我们就不用自己来创建Connection,而是通过池来获取Connection对象。当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection“归还”给池。池就可以再利用这个Connection对象了。

在这里插入图片描述

2.DataSource接口

JDBC提供了javax.sql.DataSource接口,它负责建立与数据库的连接,在应用程序中访问数据库时不必编写连接数据库的代码,可以直接从数据源获得数据库连接

(1)数据库和连接池

在DataSource中事先建立了多个数据库连接,这些数据库连接保存在连接池(ConnectPool)中。java程序访问数据库时,只需要从连接池中取出空闲状态的数据库连接,当程序访问数据库结束,再将数据库连接放回连接池,这样做可以调高访问数据库的效率。

如果Web应用每次接收到客户的请求,都和数控建立一个连接,数控操作结束就断开连接,这样会消费大量的时间和资源。因为数据库每次配置连接都要将Connection对象加载到内存中,再验证用户名和密码。

(2)数据源和JNDI资源

由于DataSource对象是由Tomcat提供的,因此不能够在程序中创建一个DataSource对象,而要采用JNDI技术来获得DataSource对象的引用。
   可以简单的把JNDI理解为一种将对象和名字绑定的技术,对象工厂负责生产出对象,这些对象都和唯一的名字绑定,外部程序可以通过名字来获得某个对象的引用。在javax.naming包中提供了Context接口,该接口提供了将对象和名字绑定,以及通过名字检索对象的方法。

在这里插入图片描述
3.DBCP数据源

DBCP是Apache提供的一款开源免费的数据库连接池!Tomcat 的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用。Hibernate3.0之后不再对DBCP提供支持!因为Hibernate声明DBCP有致命的缺欠!

需要应用程序应在系统中增加如下两个 jar 文件:

·Commons-dbcp.jar:连接池的实现
·Commons-pool.jar:连接池实现的依赖库

实现DBCP

(1)加入jar包

(2)编写dbcpconfig.properties

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/testdb
username=root
password=123456

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000


#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] 
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=UTF8

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=false

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=REPEATABLE_READ

(3)在获取数据库连接的工具类(如jdbcUtils)的静态代码块中创建池

package cn.zy.utils;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;


/*
 * 数据库连接工具类DBCP
 */
public class JdbcUtils_DBCP {
    /*
     * 在java中,编写数据库连接池需实现java.sql.DataSource接口,每一种数据库连接池都是DataSource接口的实现
     * DBCP连接池就是javax.sql.DataSource接口的一个具体实现
     */
    private static DataSource ds =null;
    //在静态代码块中创建数据库连接池
    static {
        try {
            //加载配置文件
            InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties prop = new Properties();
            prop.load(in);
            //创建数据源
             ds = BasicDataSourceFactory.createDataSource(prop);
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }
    
    /*
     * 从数据源中获取数据库连接
     */
    public static Connection getConnection() throws SQLException{
        return ds.getConnection();
    }
    
    /*
     * 释放资源
     */
    public static void release(Connection conn,Statement st,ResultSet rs){
        if(rs!=null){
            try{
                rs.close();
            }catch (Exception e){
                e.printStackTrace();
            }
            if(st!=null){
                try {
                    st.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if(conn!=null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

测试连接

package cn.zy.test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import org.junit.Test;

import cn.zy.utils.JdbcUtils_DBCP;

/*
 * 测试DBCP数据源
 */
public class DbcpTest {
    @Test
    public void dbcpDataSourceTest(){
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            //获取数据库连接
            conn = JdbcUtils_DBCP.getConnection();
            String sql = "insert into account(name,money) values(?,?)";
            st = conn.prepareStatement(sql);
            st.setString(1, "D");
            st.setFloat(2, 2000);
            st.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
             //释放资源
           JdbcUtils_DBCP.release(conn, st, rs);
        }
    }

}

4.C3P0数据源

C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。C3P0数据源在项目开发中使用得比较多。

c3p0与dbcp区别:

·dbcp没有自动回收空闲连接的功能
·c3p0有自动回收空闲连接功能

在应用程序中加入C3P0连接池

(1)导入相关jar包

c3p0-0.9.2-pre1.jar、mchange-commons-0.2.jar,如果操作的是Oracle数据库,那么还需要导入c3p0-oracle-thin-extras-0.9.2-pre1.jar

(2)在src下加入C3P0的配置文件:c3p0-config.xml,注意:

配置文件要求:

l 文件名称:必须叫c3p0-config.xml

l 文件位置:必须在src下

c3p0-config.xml的配置信息如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--
c3p0-config.xml必须位于类路径下面
private static ComboPooledDataSource ds;
static{
    try {
        ds = new ComboPooledDataSource("MySQL");
    } catch (Exception e) {
        throw new ExceptionInInitializerError(e);
    }
}
-->

<c3p0-config>
    <!--
    C3P0的缺省(默认)配置,
    如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource();”这样写就表示使用的是C3P0的缺省(默认)配置信息来创建数据源
    -->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/testdb</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        
        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>

    <!--
    C3P0的命名配置,
    如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource("MySQL");”这样写就表示使用的是name是MySQL的配置信息来创建数据源
    -->
    <named-config name="MySQL">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/testdb</property>
        <property name="user">root</property>
        <property name="password">123456</property>
        
        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </named-config>

</c3p0-config>

(3)在获取数据库连接的工具类(如jdbcUtils)的静态代码块中创建池

package cn.zy.utils;

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;

/*
 * 数据库连接工具类
 */
public class JdbcUtils_C3P0 {
    private static ComboPooledDataSource dataSource = null;
    //在静态块中创建数据库连接池
    static{
        try {
            //通过代码创建数据库连接池
            /*ds = new ComboPooledDataSource();
            ds.setDriverClass("com.mysql.jdbc.Driver");
            ds.setJdbcUrl("jdbc:mysql://localhost:3306/testdb");
            ds.setUser("root");
            ds.setPassword("123456");
            ds.setInitialPoolSize(10);
            ds.setMinPoolSize(5);
            ds.setMinPoolSize(20);*/

            //通过读取xml来获取数据源
            //ds = new ComboPooledDataSource();//使用C3P0的默认配置来创建数据源
            dataSource = new ComboPooledDataSource("MySQL");//使用C3P0的命名配置来创建数据源
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    /*
     * 从数据源中获取数据库连接
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    /*
     * 返回连接池
     */
    public static DataSource getDataSource() {
        return dataSource;
    }
    /*
     * 释放资源
     */
    public static void release(Connection conn,Statement st,ResultSet rs){
        if(rs!=null){
            try{
                //关闭存储查询结果的ResultSet对象
                rs.close();
            }catch (Exception e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if(st!=null){
            try{
                //关闭负责执行SQL命令的Statement对象
                st.close();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }

        if(conn!=null){
            try{
                //将Connection连接对象还给数据库连接池
                conn.close();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

编写测试类:

package cn.zy.test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import org.junit.Test;

import cn.zy.utils.JdbcUtils_C3P0;

public class C3p0Test {
    @Test
    public void fun(){
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils_C3P0.getConnection();
            String sql = "insert into account(name,money) values(?,?)";
            st = conn.prepareStatement(sql);
            st.setString(1, "F");
            st.setFloat(2,3000);
            st.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

二、DBUtils工具

1.DBUtils工具介绍

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

DButils封装了对JDBC的操作,简化了JDBC操作,可以少些代码。DButils的三个核心功能:

·QueryRunner提供了对sql语句操作的API

·ResultSetHandler接口,用于定义select操作后怎样去封装结果

· DButils类,是一个工具类,定义了关闭资源与事物处理的方法

2.QueryRunner类

(1)query(Connection conn,String sql,ResultSetHandler rsh,Object…params),用来完成表数据的查询操作。
esultSetHandler结果集处理类
在这里插入图片描述

(2)update(Connection conn,String sql,Object…params),用于完成表数据增加、删除、修改的操作

3、ResultSetHandler接口

该接口用于处理java.sql.ResultSet,将数据按要求转换为另一种形式。
ResultSetHandler接口提供了一个单独的方法:Object handle(java.sql.ResultSet.rs)。

4.ResultSetHandler实现类

ArrayHandler:把结果集中的第一行数据转换成对象数组。

ArrayListHandler:把结果集中的每一行数据都转换成一个对象数组,再存放到List中。

BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。

BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。

MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。

MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List。

ColumnListHandler:将结果集中某一列的数据存放到List中。

KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(List),再把这些map再存到一个map里,其key为指定的列。

ScalarHandler:获取结果集中第一行数据指定列的值,常用来进行单值查询

标签:Web,Java,java,数据库,Connection,day12,sql,import,连接池
来源: https://blog.csdn.net/m0_55689316/article/details/122352274

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有