C3P0连接池

步骤:

  1. 导c3p0的jar包
  2. 创建配置文件并配置
  3. 创建核心对象 ComboPooledDataSource
  4. 获取连接 getConnection

C3P0初始化:

  • 先导入两个包:(MySQL的驱动要确保已经导入,否则用不了)

    • c3p0-0.9.5.2.jar
    • mchange-commons-java-0.2.12.jar
  • 创建配置文件:

    • 在src目录下直接创建C3P0的配置文件,文件可以是c3p0-config.xml或c3p0.properties(文件名及扩展名一定要一样,否则识别不了)使用这两种方式进行配置时,只要将配置好的文件放入classpath文件夹下即可,在java代码当中不用显示的给出访问配置方式的代码,c3p0会自动识别

    • c3p0-config.xml:

      <?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/databaseName</property>
      <property name="user">root</property>
      <property name="password">admin</property>
      <!-- 连接池参数 -->
      <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数-->
      <property name="acquireIncrement">3</property>
      <!-- 关闭自动提交 -->
      <property name="autoCommitOnClose">false</property>
      <property name="initialPoolSize">5</property>
      <property name="minPoolSize">2</property>
      <property name="maxPoolSize">10</property>
      <!-- 最大等待时间 -->
      <property name="checkoutTimeout">3000</property>
      <!-- 最大空闲回收时间 -->
      <property name="maxIdleTime">1000</property>
      </default-config> <!-- 使用自定义的配置读取连接池对象,如果要使用named-config里面配置初始化数据源,则只要使用一个带参数的ComboPooledDataSource构造器就可以了 -->
      <named-config name="oracle">
      <!-- 连接参数 -->
      <property name="driverClass">com.mysql.jdbc.Driver</property>
      <property name="jdbcUrl">jdbc:mysql://localhost:3306/databaseName</property>
      <property name="user">root</property>
      <property name="password">admin</property> <!-- 连接池参数 -->
      <property name="initialPoolSize">5</property>
      <property name="maxPoolSize">8</property>
      <property name="checkoutTimeout">1000</property>
      </named-config>
      </c3p0-config>
    • c3p0.properties:

      #连接参数
      c3p0.jdbcUrl=jdbc:mysql://localhost:3306/databaseName
      c3p0.driverClass=com.mysql.jdbc.Driver
      c3p0.user=root
      c3p0.password=admin
      #连接池参数
      c3p0.acquireIncrement=3
      c3p0.autoCommitOnClose=false
      c3p0.initialPoolSize=5
      c3p0.minPoolSize=2
      c3p0.maxPoolSize=10
      c3p0.checkoutTimeout=3000
      c3p0.maxIdleTime=1000
    • 通过setters方法一个个地设置各个配置项(不推荐):

      ComboPooledDataSource cpds = new ComboPooledDataSource();
      cpds.setDriverClass("com.mysql.jdbc.Driver");
      cpds.setJdbcUrl("jdbc:mysql:///users");
      cpds.setUser("root");
      cpds.setPassword("admin");

创建C3P0工具类:

package top.linzeliang.web.dataSource.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement; public class C3P0Util { private static DataSource ds = null; static {
//仅仅在类被加载时系统创建一个连接池,自动识别配置文件
ds = new ComboPooledDataSource();
} public static Connection getConnection() {
try {
//获取一个连接,已经存在的
return ds.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
System.out.println("获取连接失败!");
return null;
}
} public static void closeConnection(Statement stmt, Connection conn) { if (stmt != null) {
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
} if (conn != null) {
try {
//将连接返回连接池
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}

创建C3P0测试类:

package top.linzeliang.web.dataSource.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test; import javax.sql.DataSource;
import java.io.IOException;
import java.sql.*; public class C3P0Demo { @Test
public void test() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = "CREATE TABLE user(id INT NOT NULL, username VARCHAR(18) NOT NULL, password VARCHAR(16) NOT NULL, PRIMARY KEY (id))"; try {
conn = C3P0Util.getConnection();
pstmt = conn.prepareStatement(sql);
int count = pstmt.executeUpdate();
System.out.println(count);
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
C3P0Util.closeConnection(pstmt, conn);
}
}
}

好了,这就是C3P0的基本使用了


Druid连接池(由阿里巴巴提供的数据库连接池实现技术)

步骤:

  1. 导包
  2. 创建定义配置文件
  3. 加载配置文件
  4. 获取数据库连接池对象,通过工厂来获取DruidDataSourceFactory
  5. 获取连接 getConnection

Druid初始化:

  • 同样,先导入包:(MySQL的驱动也要确保导入)

    • druid-1.1.23.jar
  • 创建配置文件:

    • 要以properties后缀名结尾,我的是 druid.properties

      • druid.properties

        driverClassName=com.mysql.jdbc.Driver //驱动加载
        url=jdbc:mysql://127.0.0.1:3306/student?characterEncoding=utf-8 //注册驱动
        username=root //连接数据库的用户名
        password=admin //连接数据库的密码。
        filters=stat //属性类型的字符串,通过别名的方式配置扩展插件, 监控统计用的stat 日志用log4j 防御sql注入:wall
        initialSize=2 //初始化时池中建立的物理连接个数。
        maxActive=300 //最大的可活跃的连接池数量
        maxWait=60000 //获取连接时最大等待时间,单位毫秒,超过连接就会失效。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降, 如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
        timeBetweenEvictionRunsMillis=60000 // 连接回收器的运行周期时间,时间到了清理池中空闲的连接,testWhileIdle根据这个判断
        minEvictableIdleTimeMillis=300000
        validationQuery=SELECT 1 //用来检测连接是否有效的sql,要求是一个查询语句。
        testWhileIdle=true //建议配置为true,不影响性能,并且保证安全性。 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis, 执行validationQuery检测连接是否有效。
        testOnBorrow=false //申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。设置为false
        testOnReturn=false //归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能,设置为flase
        poolPreparedStatements=false //是否缓存preparedStatement,也就是PSCache。
        maxPoolPreparedStatementPerConnectionSize=200 // 池中能够缓冲的preparedStatements语句数量
    • 可以放在任意位置(通过反射来获取该文件)

    • 加载配置文件:

      //加载配置文件
      Properties pro = new Properties();
      InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
      pro.load(is);
      //获取连接对象
      DataSource ds = DruidDataSourceFactory.createDataSource(pro);
      //获取连接
      Connection conn = ds.getConnection();

创建Druid工具类:

package top.linzeliang.web.dataSource.druid;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.io.InputStream;
import java.sql.Connection; public class DruidUtil {
private static DataSource ds = null;
static {
try {
//加载配置文件
Properties pro = new Properties();
InputStream is = DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//获取连接对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
e.printStackTrace();
}
} public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
System.out.println("获取连接失败");
return null;
}
} public static void closeConnection(Statement stmt, Connection conn) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
} if (conn != null) {
try {
//将连接返回给连接池
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}

创建Druid测试类:

package top.linzeliang.web.dataSource.druid;

import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; public class DruidDemo { @Test
public void test() {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = "UPDATE product SET product_name=? WHERE product_id=?"; try {
conn = DruidUtil.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "6666");
pstmt.setString(2, "0009");
int count = pstmt.executeUpdate();
System.out.println(count);
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DruidUtil.closeConnection(pstmt, conn);
}
}
}

Spring JDBC

Spring JDBC:Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发

步骤:

  1. 导包:

    • commons-logging-1.2.jar
    • spring-beans-5.1.5.RELEASE.jar
    • spring-core-5.1.5.RELEASE.jar
    • spring-jdbc-5.1.5.RELEASE.jar
    • spring-tx-5.1.5.RELEASE.jar
  2. 创建JdbcTemplate对象(依赖于DataSource对象):
    • JdbcTemplate template = new JdbcTemplate(dataSource)
  3. 调用JdbcTemplate的方法来完成CRUD操作

常用方法:

  • update():执行DML语句,及对数据的增、删、改(查是DQL语句)

  • queryForMap():将列名作为key、值作为value将这条记录封装为一个Map集合(这个方法查询的结果只能有一条记录,如果出现了两条就会报错)

  • queryForList():将结果集封装为List集合(一个Map对应一个记录,List将这些Map装起来)

  • query():将结果封装为JavaBean对象

    • query的参数:RowMapper

      package top.linzeliang.web.dataSource.SpringJDBC;
      
      import java.util.Date;
      
      public class Product {
      private String product_id;
      private String product_name;
      private String product_type;
      private Integer sale_price;
      private Integer purchase_price;
      private Date regist_date; public String getProduct_id() {
      return product_id;
      } public void setProduct_id(String product_id) {
      this.product_id = product_id;
      } public String getProduct_name() {
      return product_name;
      } public void setProduct_name(String product_name) {
      this.product_name = product_name;
      } public String getProduct_type() {
      return product_type;
      } public void setProduct_type(String product_type) {
      this.product_type = product_type;
      } public Integer getSale_price() {
      return sale_price;
      } public void setSale_price(Integer sale_price) {
      this.sale_price = sale_price;
      } public Integer getPurchase_price() {
      return purchase_price;
      } public void setPurchase_price(Integer purchase_price) {
      this.purchase_price = purchase_price;
      } public Date getRegist_date() {
      return regist_date;
      } public void setRegist_date(Date regist_date) {
      this.regist_date = regist_date;
      } @Override
      public String toString() {
      return "Product{" +
      "product_id='" + product_id + '\'' +
      ", product_name='" + product_name + '\'' +
      ", product_type='" + product_type + '\'' +
      ", sale_price=" + sale_price +
      ", purchase_price=" + purchase_price +
      ", regist_date=" + regist_date +
      '}';
      }
      }

      然后:

      package top.linzeliang.web.dataSource.SpringJDBC;
      
      import org.junit.Test;
      import org.springframework.jdbc.core.JdbcTemplate;
      import org.springframework.jdbc.core.RowMapper;
      import top.linzeliang.web.util.DruidUtil; import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.util.List; public class JDBCTemplate { @Test
      public void test() {
      JdbcTemplate template = new JdbcTemplate(DruidUtil.getDateSource());
      String sql = "SELECT * FROM product";
      //使用匿名内部类,重写mapRow方法
      List<Product> list = template.query(sql, new RowMapper<Product>() {
      @Override
      public Product mapRow(ResultSet rs, int i) throws SQLException {
      Product product = new Product();
      product.setProduct_id(rs.getString(1));
      product.setProduct_name(rs.getString(2));
      product.setProduct_type(rs.getString(3));
      product.setSale_price(rs.getInt(4));
      product.setPurchase_price(rs.getInt(5));
      product.setRegist_date(rs.getDate(6));
      return product;
      }
      }); for (Product p : list) {
      System.out.println(p);
      }
      }
      } 结果:
      九月 14, 2020 12:33:40 上午 com.alibaba.druid.pool.DruidDataSource info
      信息: {dataSource-1} inited
      Product{product_id='0001', product_name='T恤衫', product_type='衣服', sale_price=1000, purchase_price=500, regist_date=2009-09-20}
      Product{product_id='0002', product_name='打孔器', product_type='办公用品', sale_price=500, purchase_price=320, regist_date=2009-09-11}
      Product{product_id='0003', product_name='运动T恤', product_type='衣服', sale_price=4000, purchase_price=2800, regist_date=null}
      Product{product_id='0004', product_name='菜刀', product_type='厨房用具', sale_price=3000, purchase_price=2800, regist_date=2009-09-20}
      Product{product_id='0005', product_name='高压锅', product_type='厨房用具', sale_price=6800, purchase_price=5000, regist_date=2009-01-15}
      Product{product_id='0006', product_name='叉子', product_type='厨房用具', sale_price=500, purchase_price=0, regist_date=2009-09-20}
      Product{product_id='0007', product_name='擦菜板', product_type='厨房用具', sale_price=880, purchase_price=790, regist_date=2008-04-28}
      Product{product_id='0008', product_name='圆珠笔', product_type='办公用品', sale_price=100, purchase_price=0, regist_date=2009-11-11}
      Product{product_id='0009', product_name='123456789', product_type='2', sale_price=3, purchase_price=4, regist_date=null}
      • 但是这样子写有没有感觉还是太繁琐了,所以一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装,同样,可得到一样的结果

      • new BeanPropertyRowMapper<类型>(类型.class)

        package top.linzeliang.web.dataSource.SpringJDBC;
        
        import org.junit.Test;
        import org.springframework.jdbc.core.BeanPropertyRowMapper;
        import org.springframework.jdbc.core.JdbcTemplate;
        import top.linzeliang.web.util.DruidUtil;
        import java.util.List; public class JDBCTemplate { @Test
        public void test() {
        JdbcTemplate template = new JdbcTemplate(DruidUtil.getDateSource());
        String sql = "SELECT * FROM product";
        List<Product> list = template.query(sql, new BeanPropertyRowMapper<Product>(Product.class)); for (Product p : list) {
        System.out.println(p);
        }
        }
        }
  • queryForObject():将聚合查询结果封装为指定类型的对象(一般用于聚合函数的查询

    package top.linzeliang.web.dataSource.SpringJDBC;
    
    import org.junit.Test;
    import org.springframework.jdbc.core.JdbcTemplate;
    import top.linzeliang.web.util.DruidUtil; public class JDBCTemplate { @Test
    public void test() {
    JdbcTemplate template = new JdbcTemplate(DruidUtil.getDateSource());
    String sql = "SELECT COUNT(*) FROM product";
    int count = template.queryForObject(sql, Integer.class); /*这里填写的Integer.class是将来你的结果封装的类型,因为我们COUNT(*)查询结果是整数,所以我们使用Integer类型*/
    System.out.println(count);
    }
    }

C3P0和Druid数据库连接池的更多相关文章

  1. Druid数据库连接池配置

    DRUID是阿里巴巴开源平台上一个数据库连接池实现,它结合了C3P0.DBCP.PROXOOL等DB池的优点,同时加入了日志监控,可以很好的监控DB池连接和SQL的执行情况,可以说是针对监控而生的DB ...

  2. Druid数据库连接池就这么简单

    前言 本章节主要讲解Druid数据库连接池,为什么要学Druid数据库连接池呢?? 我的知识储备数据库连接池有两种->C3P0,DBCP,可是现在看起来并不够用阿~当时学习C3P0的时候,觉得这 ...

  3. Druid数据库连接池源码分析

    上一篇文章重点介绍了一下Java的Future模式,最后意淫了一个数据库连接池的场景.本想通过Future模式来防止,当多个线程同时获取数据库连接时各自都生成一个,造成资源浪费.但是忽略了一个根本的功 ...

  4. Spring Boot [使用 Druid 数据库连接池]

    导读 最近一段时间比较忙,以至于很久没有更新Spring Boot系列文章,恰好最近用到Druid, 就将Spring Boot 使用 Druid作为数据源做一个简单的介绍. Druid介绍: Dru ...

  5. Druid 数据库连接池

    druid 数据库连接池 由阿里提供 步骤 1 导包 durid1.0.9 jar 包 2 定义配置文件 必须是 properties文件 名字任意 位置也任意 3 获得数据库连接池对象 通过 Dur ...

  6. 阿里druid数据库连接池配置

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  7. 【spring boot】15.spring boot项目 采用Druid数据库连接池,并启用druid监控功能

    在http://www.cnblogs.com/sxdcgaq8080/p/9039442.html的基础上,来看看spring boot项目中采用Druid连接池. GitHub地址:示例代码 == ...

  8. Spring Boot集成Druid数据库连接池

    1. 前言 Druid数据库连接池由阿里巴巴开源,号称是java语言中最好的数据库连接池,是为监控而生的.Druid的官方地址是:https://github.com/alibaba/druid 通过 ...

  9. 基于Druid数据库连接池的DBUtil工具类

    工具类 DruidUtil.java package com.zzuli.util; import com.alibaba.druid.pool.DruidDataSourceFactory; imp ...

随机推荐

  1. Spring Cloud系列(四):Eureka源码解析之客户端

    一.自动装配 1.根据自动装配原理(详见:Spring Boot系列(二):Spring Boot自动装配原理解析),找到spring-cloud-netflix-eureka-client.jar的 ...

  2. MacOS下Terminal获取GPS经纬度坐标

    通过命令行直接获取经纬度坐标MacOS 首先下载WhereAmI,最新版本: https://github.com/robmathers/WhereAmI/releases/download/v1.1 ...

  3. vs调试程序缺少 msvcp140d.dll 解决方法

    简介一下吧: 如果只是为了解决问题请直接看第      7       点 ,谢谢. vs2013运行刚安装的opencv问题总结,尤其是电脑还很渣的情况下------花了我起码2天样子----很无奈 ...

  4. Visual C++中各种文件的作用(详细)

    参考:http://blog.sina.com.cn/s/blog_6975d67c0100r3kx.html DSW:全称是Developer Studio Workspace,最高级别的配置文件, ...

  5. Ubuntu通过Apache安装WebDav

    使用KeePass保存密码,在个人服务器上安装WebDav协议. # 安装Apache2服务器 sudo aptitude install -y apache2 # 开启Apache2中对WebDav ...

  6. ASP。NET MVC的部分视图和部分模型

    下载source - 1.7 MB 介绍 本文解决了返回视图内容包含表单元素的部分视图的问题. 代码重用是一种非常有用的节省时间的特性,任何优秀的工程师都会在他们的工作过程中构建许多有用的函数.对于W ...

  7. NOIP提高组2013 D2T3 【华容道】

    某王  老师给我们考了一场noip2013的真题...心态爆炸! 题目大意: 有一个n*m的棋盘,每个格子上都有一个棋子,有些格子上的棋子能够移动(可移动的棋子是固定的),棋盘中有一个格子是空的,仍何 ...

  8. 微服务通信之feign集成负载均衡

    前言 书接上文,feign接口是如何注册到容器想必已然清楚,现在我们着重关心一个问题,feign调用服务的时候是如何抉择的?上一篇主要是从读源码的角度入手,后续将会逐步从软件构架方面进行剖析. 一.R ...

  9. BeetleX之webapi自定义响应内容

    输出内容多样性在webapi服务中比较普遍的,有的情况使用json,xml,图片和二进制流下载等等:为了适应用不同情况的需要,组件支持自定义内容输出.接下来的主要描述组件在webapi如何定义各种内容 ...

  10. 关于【s】和[t]字符

    [s]:当一个具有执行权限的文件设置 [s](SetUID) 权限后,用户执行这个文件时将以文件所有者的身份执行.passwd 命令具有 SetUID 权限,所有者为 root(Linux 中的命令默 ...