C3P0与DBCP的区别及C3P0与DBUtils的联合使用及数据库连接池

2024-01-16 14:32

本文主要是介绍C3P0与DBCP的区别及C3P0与DBUtils的联合使用及数据库连接池,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  •  C3P0

        使用步骤:1.添加(c3p0-0.9.1.2) jar 包

                          2.编写配置文件 c3p0-config.xml (文件名字固定,位置固定在src下面),系统会自动读取配置文件

                           配置文件

<?xml version="1.0" encoding="UTF-8"?><c3p0-config><default-config><property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://localhost:3306/db3</property><property name="user">root</property><property name="password">123456</property><property name="automaticTestTable">con_test</property><property name="checkoutTimeout">30000</property><property name="idleConnectionTestPeriod">30</property><property name="initialPoolSize">10</property><property name="maxIdleTime">30</property><property name="maxPoolSize">100</property><property name="minPoolSize">10</property><property name="maxStatements">200</property><user-overrides user="test-user"><property name="maxPoolSize">10</property><property name="minPoolSize">1</property><property name="maxStatements">0</property></user-overrides></default-config><!-- This app is massive! --><named-config name="intergalactoApp"> <property name="acquireIncrement">50</property><property name="initialPoolSize">100</property><property name="minPoolSize">50</property><property name="maxPoolSize">1000</property><!-- intergalactoApp adopts a different approach to configuring statement caching --><property name="maxStatements">0</property> <property name="maxStatementsPerConnection">5</property><!-- he's important, but there's only one of him --><user-overrides user="master-of-the-universe"> <property name="acquireIncrement">1</property><property name="initialPoolSize">1</property><property name="minPoolSize">1</property><property name="maxPoolSize">5</property><property name="maxStatementsPerConnection">50</property></user-overrides></named-config>
</c3p0-config>

                      3.编写工具类

package com.qianfeng.util;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;import com.mchange.v2.c3p0.ComboPooledDataSource;
/** 注意事项:* 1.系统会自动读取c3p0-config.xml文件:a.文件的名字要固定-c3p0-config.xml   b.文件的位置也是固定的--src下面* 2.一般会自己创建xml配置文件,按照要求创建即可.* 3.优势:又有不需要自己关联配置文件,所以使用更方便*/public class C3P0Util {//1.创建池子(数据源)---创建了数据源之后,系统会自动添加连接private static ComboPooledDataSource dataSource =  new ComboPooledDataSource();//使用文件中默认的值//private static ComboPooledDataSource dataSource = new ComboPooledDataSource("initergalactoApp");//使用c3p0-config.xml配置文件中的named-config节点中name属性的值//向池子中添加连接---系统会自动读取c3p0-config.xml文件:a.文件的名字要固定-c3p0-config.xml    b.文件的位置也是固定的--src下面//2.获取连接public static Connection getConnection() throws SQLException {return dataSource.getConnection();}//获取数据源public static ComboPooledDataSource getDataSource() {return dataSource;}//3.释放连接public static void release(Connection conn,PreparedStatement statement,ResultSet set) {if (conn != null) {try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (statement != null) {try {statement.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (set != null) {try {set.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
}
  •      DBUtils

  •     作用:

               DBUtils是java编程中的数据库操作实用工具,小巧简单实用。

               DBUtils封装了对JDBC的操作,简化了JDBC操作。可以少写代码。

                1.对于数据表的读操作,他可以把结果转换成List,Array,Set等java集合,便于程序员操作;

                2.对于数据表的写操作,也变得很简单(只需写sql语句)

                3.可以使用数据源,使用JNDI,数据库连接池等技术来优化性能--重用已经构建好的数据库连接对象

  •     DBUtils的三个核心对象  

                 QueryRunner类

                 ResultSetHandler接口

                 DBUtils类

                    QueryRunner

                         QueryRunner中提供对sql语句操作的API.

                         它主要有三个方法

                              query() 用于执行select

                              update() 用于执行insert update delete

                              batch() 批处理

                   ResultSetHandler接口

                               用于定义select操作后,怎样封装结果集.

                   DbUtils

                                它就是一个工具类,定义了关闭资源与事务处理的方法

  • DBUtils快速入门

            步骤:导入jar包  (commons-dbutils-1.4.jar)(c3p0与mysql驱动jar也要导入)

                      创建QueryRunner对象

                      使用query方法执行select语句

                      使用ResultSetHandler封装结果集

                      使用DBUtils类释放资源

  •  QueryRunner对象

          new QueryRunner(); 它的事务可以手动控制。

              也就是说此对象调用的方法(如:query、update、batrch)参数中要有Connection对象。

          new QueryRunner(DataSource ds); 它的事务是自动控制的。一个sql一个事务。

              此对象调用的方法(如:query、update、batrch)参数中无需Connection对象。

          代码:

public void  test2() throws SQLException{//写sql语句String sql = "insert into user(id,name,password) values(?,?,?)";//第一种:使用的是无参的QueryRunner()方法----为了更加方便的使用事务,因为可以直接获取到Connection对象//1.创建干活的的对象--QueryRunnerQueryRunner qRunner = new QueryRunner();//2.获取连接对象Connection connection = C3P0Util.getConnection();//3.调用update()方法实现对数据库的访问int num = qRunner.update(connection, sql,6,"马六","345");if (num >0) {System.out.println("增加成功");}else {System.out.println("增加失败");}//第二种:使用的是有参的QueryRunner()方法--参数是数据源//1.创建干活儿的对象并绑定数据源
//		QueryRunner qRunner2 = new QueryRunner(C3P0Util.getDataSource());
//		//2.调用update()方法
//		int num2 = qRunner2.update(sql,7,"马六1","3451");
//		if (num2 >0) {
//			System.out.println("增加成功");
//		}else {
//			System.out.println("增加失败");
//		}}//批量增加--只能同时执行一种操作@Testpublic void test3() throws SQLException{QueryRunner qRunner2 = new QueryRunner(C3P0Util.getDataSource());//创建一个二维数组装 数据Object[][] params = new Object[3][];for (int i = 0; i < params.length; i++) {params[i] = new Object[]{i+8,"bingbing"+i,"333"+i};}//写sql语句String sql = "insert into user(id,name,password) values(?,?,?)";int[] nums = qRunner2.batch(sql, params);}
  •  ResultSetHandler接口

          ResultSetHandler下的所有结果处理器

           

package com.qianfeng.test;import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;import javax.enterprise.inject.New;import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.ArrayHandler;
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.ColumnListHandler;
import org.apache.commons.dbutils.handlers.KeyedHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;import com.qianfeng.domain.User;
import com.qianfeng.util.C3P0Util;public class TestDemo2 {/** ResultSetHandler接口*/@SuppressWarnings("unchecked")//@Test//获取全部的数据public void test1() throws SQLException{QueryRunner qRunner2 = new QueryRunner(C3P0Util.getDataSource());ResultSetHandler handler = new ResultSetHandler<List<User>>() {/** 这是真正处理数据的方法* 参数就是得到的结果集* 这个方法会被自动调用*/@Overridepublic List<User> handle(ResultSet set) throws SQLException {List<User> list = new ArrayList<User>();while (set.next()) {User user = new User();user.setName(set.getString("name"));user.setPassword(set.getString("password"));list.add(user);}return list;}};List<User> list = qRunner2.query("select * from user", handler);System.out.println(list);}//@Test//返回所有的数据--将记录装入模型,将模型装入listpublic void test2() throws SQLException{QueryRunner qRunner2 = new QueryRunner(C3P0Util.getDataSource());//<对应模型的类>(模型的字节码文件)List<User> list = qRunner2.query("select * from user", new BeanListHandler<User>(User.class));System.out.println(list);}@Test//返回一条记录-得到的是模型public void test3() throws SQLException{QueryRunner qRunner2 = new QueryRunner(C3P0Util.getDataSource());User user = qRunner2.query("select * from user where id=?", new BeanHandler<User>(User.class),1);System.out.println(user);}//取一条记录//ArrayHandler:只能返回一个记录,并且没有存储到javabean中,默认返回的是第一个记录//@Testpublic void test13() throws SQLException{QueryRunner qRunner = new QueryRunner(C3P0Util.getDataSource());//Object[] objects = qRunner.query("select * from user", new ArrayHandler());for (Object object : objects) {System.out.println(object);}}//取多条记录//ArrayListHandler:可以返回查到的多行记录,将一条记录的每个字段存储到一个数组中,再将这些数组放入一个集合中,并返回//@Testpublic void test4() throws SQLException{QueryRunner qRunner = new QueryRunner(C3P0Util.getDataSource());List<Object[]> list = qRunner.query("select * from user", new ArrayListHandler());for (Object[] objects : list) {for (Object object : objects) {System.out.print(object+"  ");}System.out.println();}}//ColumnListHandler:根据指定的列数,取某一列的数据,封装到list中返回//@Testpublic void test5() throws SQLException{QueryRunner qRunner = new QueryRunner(C3P0Util.getDataSource());//参数的意思是:指定查询的列号---从1开始计数List<Object> list = qRunner.query("select * from user", new ColumnListHandler(2));for (Object object : list) {System.out.print(object+"  ");}}//KeyedHandler:可以取多条记录,每一条记录被封装在了map中,然后再将所有的map对象放在一个大的map中,让每条记录中的某个字段充当外层map的key//注意:如果充当key的字段有重复,和面的记录会将前面所有的记录覆盖//@Testpublic void test6() throws SQLException{QueryRunner qRunner = new QueryRunner(C3P0Util.getDataSource());Map<Object, Map<String, Object>> map=qRunner.query("select * from user", new KeyedHandler(5));for(Map.Entry<Object, Map<String, Object>> en:map.entrySet()){Object key = en.getKey();Map<String, Object> subMap = en.getValue();for(Map.Entry<String, Object> suben:subMap.entrySet()){String subkey = suben.getKey();Object value = suben.getValue();System.out.print(subkey+"="+value+"   ");}System.out.println("  key="+key);}}//只能取一条记录//MapHandler:将一条记录的字段和对应的值封装到一个map中,返回,默认取的是第一行//@Testpublic void test7() throws SQLException{QueryRunner qRunner = new QueryRunner(C3P0Util.getDataSource());Map<String, Object> map = qRunner.query("select * from user", new MapHandler());for(String key:map.keySet()){System.out.print(key+"="+map.get(key)+"   ");}}//MapHandler:将一条记录的字段和对应的值封装到一个map中,再将所有的map放到一个list中并返回//@Testpublic void test8() throws SQLException{QueryRunner qRunner = new QueryRunner(C3P0Util.getDataSource());List<Map<String, Object>> list = qRunner.query("select * from user", new MapListHandler());for (Map<String, Object> map : list) {for(String key:map.keySet()){System.out.print(key+"="+map.get(key)+"   ");}System.out.println();}}//取第一行的某一列的值//ScalarHandler:适合取单行单列的数据@Testpublic void test9() throws SQLException{QueryRunner qRunner = new QueryRunner(C3P0Util.getDataSource());//参数:代表第一行对应的行号,取这个列下的数据,若果不写,默认取第一列//Object object = qRunner.query("select * from user", new ScalarHandler(3));//与聚合函数联合使用,参数可以取的列是select后面可以获取的列数Object object1 = qRunner.query("select *,count(*) from user", new ScalarHandler(6));System.out.println(object1);}
}

 

  •   DBCP

           使用步骤:添加jar包  commons-dbcp-1.4.jar  commons-pool-1.5.6.jar​​​​​​​

                             添加属性资源文件 

                             编写数据源工具类

  •  资源文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db6
user=root
password=971125
initSize=3
maxSize=3
  •  编写工具类

      

package com.qianfeng.dbcp;import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;import javax.sql.DataSource;import org.apache.commons.dbcp.BasicDataSourceFactory;
/** 1.导入三方架包* 2.编写配置文件:配置文件的类型必须是properties,名字随意,位置随意* 3.创建DBCPUtil工具类*/public class DBCPUtil {//1.创建数据源private static DataSource dataSource;//2.连接配置文件static{Properties properties = new Properties();try {//获取配置信息,将内容保存到properties对象里面properties.load(DBCPUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties"));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}//得到连接池对象,将配置信息指定给连接池对象try {dataSource = BasicDataSourceFactory.createDataSource(properties);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}//3.获取连接public static Connection getConnection() throws SQLException {return dataSource.getConnection();}//4.释放连接public static void release(Connection conn,PreparedStatement statement,ResultSet set) {if (conn != null) {try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (statement != null) {try {statement.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if (set != null) {try {set.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
}
  •  数据库连接池

  •    基本原理

                 在内部对象池中,维护一定数量的数据库连接,并对外暴露数据库连接的获取和返回方法。如外部使用者可通过getConnection方法获取数据库连接,使用完毕后再通过releaseConnection方法将连接返回,注意此时的连接并没有关闭,而是由连接池管理器回收,并为下一次使用做好准备。

  •  作用

           ①资源重用

             由于数据库连接得到重用,避免了频繁创建、释放连接引起的大量性能开销。在减少系统消耗的基础上,增进了系统环境的平稳性(减少内存碎片以级数据库临时进程、线程的数量)

           ②更快的系统响应速度

             数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池内备用。此时连接池的初始化操作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。

           ③新的资源分配手段

             对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接的配置,实现数据库连接技术。

           ④统一的连接管理,避免数据库连接泄露

            在较为完备的数据库连接池实现中,可根据预先的连接占用超时设定,强制收回被占用的连接,从而避免了常规数据库连接操作中可能出现的资源泄露

  

  •  编写标准的数据源

        自定义数据库连接池要实现javax.sql.DataSource接口,一般都叫数据源

        

  •  编写数据源时遇到的问题及解决办法

     

      a.装饰设计模式:使用频率很高​​​​​​​

                目的:改写已存在的类的某个方法或某些方法,装饰设计模式(包装模式)

                口诀:

                    1、编写一个类,实现与被包装类相同的接口。(具备相同的行为)

                    2、定义一个被包装类类型的变量。

                    3、定义构造方法,把被包装类的对象注入,给被包装类变量赋值。

                    4、对于不需要改写的方法,调用原有的方法。

                    5、对于需要改写的方法,写自己的代码。

                  

         b.默认适配器:装饰设计模式一个变体​​​​​​​

         

        

  •  常用的数据源有  DBCP  ,C3P0

       区别一:

           DBCP(DataBase connection pool):是 apache 上的一个 java 连接池项目。

           C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展

       区别二:      

           DBCP没有自动的去回收空闲连接的功能,C3P0有自动回收空闲连接功能

       区别三:

           DBCP连接池的持续运行的稳定性还是可以,不过速度稍慢,在大并发量的压力下稳定性有所下降

           C3P0连接池的持续运行的稳定性相当不错,在大并发量的压力下稳定性也有一定保证

 

 

 

 

这篇关于C3P0与DBCP的区别及C3P0与DBUtils的联合使用及数据库连接池的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/612894

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Python调用Orator ORM进行数据库操作

《Python调用OratorORM进行数据库操作》OratorORM是一个功能丰富且灵活的PythonORM库,旨在简化数据库操作,它支持多种数据库并提供了简洁且直观的API,下面我们就... 目录Orator ORM 主要特点安装使用示例总结Orator ORM 是一个功能丰富且灵活的 python O

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Linux使用nload监控网络流量的方法

《Linux使用nload监控网络流量的方法》Linux中的nload命令是一个用于实时监控网络流量的工具,它提供了传入和传出流量的可视化表示,帮助用户一目了然地了解网络活动,本文给大家介绍了Linu... 目录简介安装示例用法基础用法指定网络接口限制显示特定流量类型指定刷新率设置流量速率的显示单位监控多个

Java中ArrayList和LinkedList有什么区别举例详解

《Java中ArrayList和LinkedList有什么区别举例详解》:本文主要介绍Java中ArrayList和LinkedList区别的相关资料,包括数据结构特性、核心操作性能、内存与GC影... 目录一、底层数据结构二、核心操作性能对比三、内存与 GC 影响四、扩容机制五、线程安全与并发方案六、工程

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本