数据库连接池

# 概念:其实就是一个容器(集合),存放数据库连接的容器。
  * 当系统初始化号以后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容其中获取连接对象,用户访问完之后,会将连接对象归还给容器。

# 好处
  * 节约资源
  * 用户访问高效

# 实现
  * 标准接口:DataSource    javax.sql 包下的
    * 方法:
      * 获取连接:getConnection()
      * 归还连接:Connection.close()
        * 如果连接对象 Connection是从连接池中获取的,那么调用 Connection.close() 方法,则不会再关闭连接了,而是归还连接。

  * 一般我们不去实现它,有数据库厂商来实现
    * C3P0:数据库连接池技术
    * Druid:数据库连接池技术,由阿里巴巴提供

C3P0:数据库连接池技术

  * 步骤:
    1)导入 jar 包(两个):c3p0-0.9.5.2.jar 和 mchange-commons-java-0.2.12.jar
      * 不要忘记导入数据库驱动 jar 包
    2)定义配置文件
      * 名称:c3p0.properties 或者 c3p0-config.xml
      * 路径:直接将文件放在 src 目录即可
    3)创建核心对象  数据库连接池对象:ComboPooledDataSource
    4)获取连接:getConnection

  * 代码实现

//1、创建数据库连接池对象
DataSource ds = new ComboPooledDataSource();
//2、获取连接对象
Connection conn = ds.getConnection

<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db4</property>
<property name="user">root</property>
<property name="password">123</property> <!-- 连接池参数 -->
<!-- initialPoolSize初始化申请连接的数量 -->
<property name="initialPoolSize">5</property>
<!-- maxPoolSize最大的连接数量 -->
<property name="maxPoolSize">10</property>
<!-- checkoutTimeout超时时间 -->
<property name="checkoutTimeout">3000</property>
</default-config> <named-config name="otherc3p0">
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property>
<property name="user">root</property>
<property name="password">root</property> <!-- 连接池参数 -->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">8</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>

c3p0-config.xml

package cn.itcast.datasource.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException; /**
* c3p0的演示
*/
public class C3P0Demo1 {
public static void main(String[] args) throws SQLException {
//1、创建数据库连接池对象
DataSource ds = new ComboPooledDataSource();
//2、获取连接对象
Connection conn = ds.getConnection();
//3、打印
System.out.println(conn);
}
}

Druid:数据库连接池技术,阿里巴巴提供

  * 步骤:
    1)导入 jar 包:druid-1.0.9.jar
    2)定义配置文件
      * 是 properties 形式的
      * 可以教任意名字,放在任意目录下
    3)加载配置文件 Properties
    4)获取数据库连接池对象:通过工厂类来获取 :DruidDataSourceFactory
    5)获取连接:getConnection()

  * 代码实现

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

package cn.itcast.datasource.druid;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties; /**
* Druid演示
*/
public class DruidDemo1 {
public static void main(String[] args) throws Exception {
//1、导入jar包
//2、定义配置文件
//3、加载配置文件
Properties pro = new Properties();
InputStream is = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//4、获取连接池对象
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
//5、获取连接
Connection conn = ds.getConnection();
System.out.println(conn);
}
}

* 定义工具类
    * 定义一个类 JDBCUtils
    * 提供静态代码块加载配置文件,初始化连接池对象
    * 提供方法:
      * 获取连接方法:通过数据库连接池获取连接
      * 释放资源
      * 获取连接池的方法

package cn.itcast.datasource.utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.naming.Context;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties; /**
* Druid连接池的工具类
*/
public class JDBCUtils { // 1、定义成员变量 DataSource
private static DataSource ds; static {
try {
Properties pro = new Properties();
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 获取连接的方法
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
} /**
* 释放资源的方法
*/
public static void close(Statement stmt, Connection conn) {
close(null, stmt, conn);
} public static void close(ResultSet rs, Statement stmt, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
} if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
} if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} /**
* 获取连接池的方法
*/
public static DataSource getDataSource() {
return ds;
}
}

JDBCutils

package cn.itcast.datasource.druid;

import cn.itcast.datasource.utils.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException; /**
* 使用新的工具类
*/
public class DruidDemo2 {
public static void main(String[] args) {
/**
* 完成添加操作,给account表添加一条记录
*/
Connection conn = null;
PreparedStatement pstmt = null;
try {
//1、获取连接
conn = JDBCUtils.getConnection();
//2、定义sql
String sql = "insert into account values(null,?,?)";
//3、获取执行对象
pstmt = conn.prepareStatement(sql);
//4、给问号赋值
pstmt.setString(1, "王五");
pstmt.setDouble(2, 3000);
//5、执行sql
int count = pstmt.executeUpdate();
System.out.println(count);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtils.close(pstmt, conn);
}
}
}

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db3
username=root
password=123
# 初始化的连接数量
initialSize=5
# 最大连接数
maxActive=10
# 超时时间
maxWait=3000

properties

Spring JDBC

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

  * 步骤:
    1)导入 jar 包
    2)创建 JdbcTemplate 对象,依赖于数据源 DataSource
      * JdbcTemplate template = new JdbcTemplate(ds);
    3)调用 JdbcTemplate 的方法来完成 CRUD 的操作
      * update():执行 DML 语句,实现 增、删、改 操作
      * queryForMap():查询结果将封装为 map 集合,将列名作为 Key,将值作为 value,将这条记录封装为一个 map 集合
        * 注意:这个方法查询的结果集长度只能为1
      * queryForList():查询结果将封装为 list 集合
        * 注意:将每一条记录封装为一个 Map 集合,再将 Map 集合装载到 List 集合中
      * query():查询结果将封装为 JavaBean 对象
        * query() 的参数:
          * 一般我们使用 BeanPropertyRowMapper 实现类,可以完成数据到 JavaBean 的自动封装
          * new BeanPropertyRowMapper< 类型 >( 类型.class )
      * queryForObject():查询结果将封装为对啊ing
        * 一般用于聚合函数的查询

package cn.itcast.jdbtemplate;

import cn.itcast.datasource.utils.JDBCUtils;
import org.springframework.jdbc.core.JdbcTemplate; /**
* JdbcTemplate入门
*/
public class JdbcTemplateDemo1 {
public static void main(String[] args) {
//1、导入jar包
//2、创建J的BCTemplate对象
JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
//3、调用方法
String sql = "update account set balance = 5000 where id = ?";
int count = template.update(sql, 4);
System.out.println(count); } }

  * 练习:
    * 需求:
      1)修改 1 号数据的 salary 为 10000
      2)添加一条记录
      3)删除刚才添加的记录
      4)查询 id 为 1 的记录,将其封装为 Map 集合
      5)查询所有记录,将其封装为 List
      6)查询所有记录,将其封装为 Emp 对象的List集合
      7)查询总记录数

package cn.itcast.jdbtemplate;

import cn.itcast.bean.Emp;
import cn.itcast.datasource.utils.JDBCUtils;
import org.junit.Test;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper; import javax.sql.DataSource;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map; public class JdbcTemplateDemo2 {
//Junit单元测试,可以让方法独立的执行,不再依赖于主方法
//1、获取JDBCTemplate对象
private DataSource dataSource = JDBCUtils.getDataSource();
private JdbcTemplate template = new JdbcTemplate(dataSource); /**
* 修改 1 号数据的 salary 为 10000
*/
@Test
public void test1() {
String sql = "update emp set salary = 1000 where id = 1001";
int count = template.update(sql);
System.out.println(count);
} /**
* 添加一条记录
*/
@Test
public void test2() {
String sql = "insert into emp(id,ename,dept_id) values(?,?,?)";
int count = template.update(sql, 1015, "郭靖", 10);
System.out.println(count);
} /**
* 删除刚才添加的记录
*/
@Test
public void test3() {
String sql = "delete from emp where id = ?";
int count = template.update(sql, 1015);
System.out.println(count);
} /**
* 查询 id 为 1 的记录,将其封装为 Map 集合
*/
@Test
public void test4() {
String sql = "select * from emp where id = ?";
Map<String, Object> map = template.queryForMap(sql, 1001);
System.out.println(map);
} /**
* 查询所有记录,将其封装为 List
*/
@Test
public void test5() {
String sql = "select * from emp";
List<Map<String, Object>> maps = template.queryForList(sql);
for (Map<String, Object> map : maps) {
System.out.println(map);
}
} /**
* 查询所有记录,将其封装为 Emp 对象的List集合
*/
@Test
public void test6() {
String sql = "select * from emp";
List<Emp> list = template.query(sql, new RowMapper<Emp>() {
@Override
public Emp mapRow(ResultSet resultSet, int i) throws SQLException {
Emp emp = new Emp();
int id = resultSet.getInt("id");
String ename = resultSet.getString("ename");
int job_id = resultSet.getInt("job_id");
int mgr = resultSet.getInt("mgr");
Date joindate = resultSet.getDate("joindate");
double salary = resultSet.getDouble("salary");
int dept_id = resultSet.getInt("dept_id");
double bonus = resultSet.getDouble("bonus"); emp.setId(id);
emp.setE_name(ename);
emp.setBounds(bonus);
emp.setJoin_date(joindate);
emp.setMgr(mgr);
emp.setDept_id(dept_id);
emp.setJob_id(job_id);
emp.setSalary(salary); return emp;
}
}); for (Emp emp : list) {
System.out.println(emp);
}
} /**
* 查询所有记录,将其封装为 Emp 对象的List集合
*/
@Test
public void test6_2() {
String sql = "select * from emp";
List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
for (Emp emp : list) {
System.out.println(emp);
}
} /**
* 查询总记录数
*/
@Test
public void test7() {
String sql = "select count(id) from emp";
Long total = template.queryForObject(sql, Long.class);
System.out.println(total);
}
}

JDBC 连接池 & Template的更多相关文章

  1. 四大流行的jdbc连接池之C3P0篇

    C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSourc ...

  2. Spring+SpringMVC+MyBatis+easyUI整合优化篇(九)数据层优化-jdbc连接池简述、druid简介

    日常啰嗦 终于回到既定轨道上了,这一篇讲讲数据库连接池的相关知识,线程池以后有机会再结合项目单独写篇文章(自己给自己挖坑,不知道什么时候能填上),从这一篇文章开始到本阶段结束的文章都会围绕数据库和da ...

  3. JDBC连接池-C池3P0连接

    JDBC连接池-C3P0连接 c3p0连接池的学习英语好的看英文原版      c3p0 - JDBC3 Connection and Statement Pooling 使用c3p0连接池  三种方 ...

  4. JDBC连接池(三)DBCP连接池

    JDBC连接池(三)DBCP连接池 在前面的随笔中提到 了  1.JDBC自定义连接池  2. C3P0连接池 今天将介绍DBCP连接池 第一步要导入jar包   (注意:mysql和mysql 驱动 ...

  5. JDBC连接池-自定义连接池

    JDBC连接池 java JDBC连接中用到Connection   在每次对数据进行增删查改 都要 开启  .关闭  ,在实例开发项目中 ,浪费了很大的资源 ,以下是之前连接JDBC的案例 pack ...

  6. Jmeter(九)JDBC连接池

    JDBC为java访问数据库提供通用的API,可以为多种关系数据库提供统一访问.因为SQL是关系式数据库管理系统的标准语言,只要我们遵循SQL规范,那么我们写的代码既可以访问MySQL又可以访问SQL ...

  7. jdbc连接池&改进dbUtil成C3P0Util

    一.jdbc连接池 1.连接池的存在理由   前面介绍的dbUtils工具类虽然实现了一个对jdbc的简单封装.但它依旧采取从驱动管理获取连接 (DriverManager.getConnection ...

  8. Tomcat 的 JDBC 连接池

    JDBC 连接池 org.apache.tomcat.jdbc.pool 是 Apache Commons DBCP 连接池的一种替换或备选方案. 那究竟为何需要一个新的连接池? 原因如下: Comm ...

  9. 【JDBC&Dbutils】JDBC&JDBC连接池&DBUtils使用方法(重要)

    -----------------------JDBC---------- 0.      db.properties文件 driver=com.mysql.jdbc.Driver url=jdbc: ...

随机推荐

  1. 牛客编程巅峰赛S2第10场 - 钻石&王者 C.牛牛的路径和 (位运算,dfs)

    题意:给你节点数为\(n\)的树,每个节点都有自己的权值,求所有路径的上的点的权值按位与的和. 题解:题目给的数据很大,我们不能直接去找.因此我们可以枚举二进制\([1,20]\)的每一位,然后再枚举 ...

  2. HDU -1151 二分匹配与有向无环图不相交最小路径覆盖数

    题意: 考虑一个小镇,那里的所有街道都是单向的,并且每条街道都从一个路口通往另一个路口.还众所周知,从一个十字路口开始,穿过城镇的街道,您将永远无法到达同一十字路口,即,城镇的街道没有环. 基于这些假 ...

  3. Codeforces Round #602 Div2 D1. Optimal Subsequences (Easy Version)

    题意:给你一个数组a,询问m次,每次返回长度为k的和最大的子序列(要求字典序最小)的pos位置上的数字. 题解:和最大的子序列很简单,排个序就行,但是题目要求字典序最小,那我们在刚开始的时候先记录每个 ...

  4. Codeforces Gym-102219 2019 ICPC Malaysia National E. Optimal Slots(01背包+输出路径)

    题意:给你一个体积为\(T\)的背包,有\(n\)个物品,每个物品的价值和体积都是是\(a_{i}\),求放哪几个物品使得总价值最大,输出它们,并且输出价值的最大值. 题解:其实就是一个01背包输出路 ...

  5. office响应慢,但电脑速度没问题的解决方案

    看了非常多教程都没有用,有点崩,最后终于解决了,记录一下. 问题描述 :office启动没问题,但word打开后,选中一段文字非常慢,大概延迟鼠标移动2-3秒.点击工具栏时也有延迟(点击动画看的十分清 ...

  6. ARM汇编---程序获取符号的物理地址

    在移植u-boot的过程看到过u-boot在重定向时的实现,当时不知道怎么就觉得很好理解就把这个知识点没怎么深入的理解,最近在看华为的鸿蒙OS在Cortex-A平台上的实现过程时再次遇到一时间看不太懂 ...

  7. Inkscape tricks

    Draw straight lines: click pencil button -> click once on your canvas(starting point) -> click ...

  8. TypeScript Errors All In One

    TypeScript Errors All In One 1. Property 'name' has no initializer and is not definitely assigned in ...

  9. Battery API All In One

    Battery API All In One https://caniuse.com/?search=Battery navigator.getBattery() /* Promise {<pe ...

  10. 「NGK每日快讯」12.2日NGK公链第29期官方快讯!