今日内容:
  • 数据库连接池
  • 简化操作--Spring JDBC提供的 JDBC Template(JDBC的封装)
一、数据库连接池
1.引入
之前:每一次都要获取连接、释放连接……
现在:连接重复使用
2.概念:其实就是一个容器(集合),存放数据库连接的容器
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象。用户访问完之后,会将连接对象归还给容器
好处
  • 节约资源
  • 用户访问高效
3.实现
java.sql.DataSource标准接口
DataSource接口由驱动程序供应商实现,有三种类型的实现
  • 基本实现 - 生成标准的Connection对象
  • 连接池实现 - 生成将自动参与连接池的Connection对象。 此实现与中间层连接池管理器配合使用。
  • 分布式事务实现 - 生成可用于分布式事务的Connection对象,并且几乎总是参与连接池。 此实现与中间层事务管理器一起工作,并且几乎总是使用连接池管理器。
3.1方法
获取连接:Connection getConnection() 尝试建立与此 DataSource对象所代表的数据源的连接。 
归还连接:如果连接对象是从Connection连接池中获取的,那么调用Connection.close()方法,不会再关闭连接了,而是归还连接
一般由数据库厂商来实现
两种数据库连接池技术实现:
  • C3P0:数据库连接池技术
  • Druid德鲁伊数据库连接池实现技术,由阿里巴巴提供
4.c3p0连接池(两种使用方式)
硬编码(不推荐)
配置文件:c3p0.properties or c3p0-config.xml
Configuration files are normally looked up under standard names (c3p0.properties or c3p0-config.xml) at the top level of an application's classpath, but the XML configuration can be placed anywhere in an application's file system or classpath, if the system property com.mchange.v2.c3p0.cfg.xml is set.
  • 使用步骤
    • 导入两个jar包 c3p0-0.9.5.2.jar 和 mchange-commons-java-0.2.12.jar(doc里面有文档)
    • 定义配置文件
      • 名称c3p0.properties或 c3p0-config.xml
      • 路径:直接蒋文杰放到src目录下即可

    • 创建核心对象--数据库连接池对象---ComboPooledDataSource
    • 获取连接:getConnection
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);
}
}
验证 其他参数是否合适
package cn.itcast.datasource.c3p0;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import java.sql.Connection;
import java.sql.SQLException; /**
* 演示:连接池参数的验证
*/
public class C3poDemo2 {
public static void main(String[] args) throws SQLException { //1.获取DataSource连接池,使用默认配置
//ComboPooledDataSource ds = new ComboPooledDataSource();
//2.获取连接
/*
* <!--最大的连接池数量-->
<property name="maxPoolSize">10</property>*/
/* for (int i=1;i<=11;i++){
//超过最大连接池数量会等待三秒,然后报错
Connection conn = ds.getConnection();
System.out.println(i+":"+conn);
if (i==5){
conn.close();
}
}*/
//new C3poDemo2().testNamedConfig();
testNamedConfig(); }
public static void testNamedConfig() throws SQLException {
//1.1获取DataSource连接池,使用指定名称的配置
ComboPooledDataSource ds = new ComboPooledDataSource("otherc3p0");
//2.获取连接
/*
* <!--最大的连接池数量-->
<property name="maxPoolSize">10</property>*/
for (int i=1;i<=10;i++){
//超过最大连接池数量会等待三秒,然后报错
Connection conn = ds.getConnection();
System.out.println(i+":"+conn);
}
}
}
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<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">10</property>
<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>
总结:
  • maxPoolSize最大连接个数,checkoutTimeout失败后等待时间
  • 可以配置多个连接池,不再使用default,而是<named-config name="otherc3p0">
  • ComboPooledDataSource构造函数中则需要对应传递参数
5.Druid数据库连接池,阿里巴巴提供_基本使用
步骤:
  • 导入jar包druid-1.0.9.jar
  • 定义配置文件
    • 配置文件是properties形式的
    • 可以叫任意名称,可以放至任意目录下(需要手动加载)
  • 加载配置文件,Properties
  • 获取数据库连接池对象:通过工厂类获取 DruidSourceFactory
  • 获取连接: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 DruidDemo {
public static void main(String[] args) throws Exception {
//1.导入jar包
//2.定义配置文件
//3.加载配置文件
Properties pro=new Properties();
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//4.获取连接池对象
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
//5.获取连接
Connection conn=ds.getConnection();
System.out.println(conn);
}
}
6.数据库连接池_druid_工具类
步骤
  1. 定义一个工具类JDBCUtils
  2. 提供静态代码块,加载配置文件并初始化连接池对象
  3. 提供方法
    1. 获取连接方法:通过数据库连接池获取连接
    2. 释放资源(关闭连接 )
    3. 获取连接池的方法
package cn.itcast.datasource.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
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 {
//1.加载配置文件
Properties pro=new Properties();
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//2.获取DataSource
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){
/*if (stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn!=null){
try {
conn.close();//归还连接
} catch (SQLException e) {
e.printStackTrace();
}
}*/
//简化书写
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;
}
}
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对象
pstmt = conn.prepareStatement(sql);
//4.给?赋值
pstmt.setString(1,"王五");
pstmt.setDouble(2,3000);
int count = pstmt.executeUpdate();
System.out.println(count); } catch (SQLException e) {
e.printStackTrace();
}finally {
//6.释放资源
JDBCUtils.close(pstmt,conn); }
}
}
二、JDBCTemplate
1.介绍
JDBCTemplate是Spring提供的对JDBC的简单封装,通过JDBCTemplate简化JDBC的开发
之前封装对象等,比较麻烦
步骤:
  • 导入jar包
  • 创建JDBCTemplate对象,该对象依赖于数据源DataSource
    • 如:JDBCTemplate template =new JDBCTemplate(ds)
  • 调用JDBCTemplat的方法来完成CRUD的操作(update和query)
    • update()---执行DML语句,实现增删改语句
    • queryForMap()--查询结果,将结果集封装为map集合
      • 注意:结果集长度只能为1
      • 将列名作为key,将值作为value,将这条记录封装为一个map集合
    • queryForList()--查询结果,将结果集封装为list集合
      • 将每一条记录封装为一个map集合,再将map集合封装为list集合
    • query()--JavaBean查询结果,将结果集封装为JavaBean对象
      • 需要的参数包括RowMapper接口,常使用其实现类BeanPropertyRowMapper,可以完成数据到javabean的自动封装
      • new BeanPropertyRowMapper<类型>(类型.class)
    • queryForObject()--对象查询结果,将结果集封装为对象
      • 一般用于聚合函数的查询
2.快速入门
package cn.itcast.datasource.jdbctemplate;
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.创建JDBCTemplate对象
//ctrl+p查看参数
//jdbc资源的释放和申请操作由JDBCTemplate完成
JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
//3.调用方法
String sql="update account set balance =5000 where id=?";
int count = template.update(sql, 3);
System.out.println(count);
}
}
3.练习_JDBCTemplate_执行DML语句
需求
  1. 修改1号数据的salary为10000
  2. 添加一条记录
  3. 删除刚才添加的记录
  4. 查询所有id为1的记录,将其封装为map集合
  5. 查询所有记录,将其封装为list集合
  6. 查询所有记录,将其 封装为 Emp对象的list集合
  7. 查询总的记录数(count')
package cn.itcast.jdbctemplate;
import cn.itcast.utils.JDBCUtils;
import org.junit.Test;
import org.springframework.jdbc.core.JdbcTemplate;
public class JdbcTemplateDemo2 {
//Junit单元测试,可以让方法独立执行
//1.获取JDBCtemplate对象
private JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource()); /**
* 修改1号数据的salary为10000
*/
@Test
public void test1(){
//2.定义sql
String sql="update emp set salary =10000 where id=1001";
//3.执行sql
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);
}
}
4.JDBCTemplate_执行DQL语句
 /**
* 查询所有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);
//{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}
}
/**
* 如果有多条记录
* 注意:此方法queryForMap结果集长度只能为1
*/
@Test
public void test5(){
String sql="select * from emp where id= ? or id= ?";
Map<String, Object> map = template.queryForMap(sql, 1001,1002);
System.out.println(map);
//{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}
}
/**
* 查询所有记录,将其封装为list集合
*/
@Test
public void test6(){
String sql="select * from emp";
List<Map<String, Object>> list = template.queryForList(sql);
for (Map<String, Object> stringObjectMap : list) {
System.out.println(stringObjectMap);
}
}
/**
* 查询所有记录,将其封装为 Emp对象的list集合
*/
@Test
public void test7(){
String sql="select * from emp";
List<Emp> list = template.query(sql, new RowMapper<Emp>() {
@Nullable
@Override
public Emp mapRow(ResultSet rs, int i) throws SQLException {
Emp emp=new Emp();
int id = rs.getInt("id");
String ename = rs.getString("ename");
int job_id = rs.getInt("job_id");
int mgr = rs.getInt("mgr");
Date joindate = rs.getDate("joindate");
double salary = rs.getDouble("salary");
double bonus = rs.getDouble("bonus");
int dept_id = rs.getInt("dept_id");
emp.setId(id);
emp.setEname(ename);
emp.setJob_id(job_id);
emp.setMgr(mgr);
emp.setJoindate(joindate);
emp.setSalary(salary);
emp.setBonus(bonus);
emp.setDept_id(dept_id);
return emp;
}
});
for (Emp emp : list) {
System.out.println(emp);
}
}
/**
* 查询所有记录,将其封装为 Emp对象的list集合
* template已经提供了实现类
*/
@Test
public void test8(){
String sql="select * from emp";
List<Emp> list = template.query(sql,new BeanPropertyRowMapper<Emp>(Emp.class));
//提示空值不能转换为double,则需要修改javabean为引用数据类型
for (Emp emp : list) {
System.out.println(emp);
}
}
/**
* 查询总的记录数(count')
*/@Test
public void test9(){
String sql="select count(id) from emp";
Long total = template.queryForObject(sql, Long.class);//用于执行聚合函数
System.out.println(total);
}
}

JavaEE Day06 JDBC连接池&JDBCTemplate的更多相关文章

  1. Java中JDBC连接池&JDBCTemplate

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

  2. JavaWeb——JDBC连接池&JDBCTemplate

    今日内容 1. 数据库连接池 2. Spring JDBC : JDBC Template 数据库连接池 1. 概念:其实就是一个容器(集合),存放数据库连接的容器. 当系统初始化好后,容器被创建,容 ...

  3. JDBC连接池&JDBCTemplate

    今日内容 1. 数据库连接池 2. Spring JDBC : JDBC Template 数据库连接池 1. 概念:其实就是一个容器(集合),存放数据库连接的容器. 当系统初始化好后,容器被创建,容 ...

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

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

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

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

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

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

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

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

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

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

  9. Jmeter(九)JDBC连接池

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

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

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

随机推荐

  1. 认识RocketMQ4.x架构设计

    消息模型 单体的消息模型 RocketMQ消息模型跟其他的消息队列一样 都是 producer - > topic->consumer producer 生产消息 也就是发送者 topic ...

  2. win7通过netsh命令禁用、启用本地连接 定时关闭开启网络连接

    1) 先检查网络接口名称 C:\Windows\system32>netsh interface show interface 管理员状态 状态 类型 接口名称 ---------------- ...

  3. Docker安装prometheus

    # 拉取镜像 docker pull prom/prometheus:v2.22.0 # 创建配置文件 mkdir -p /opt/prometheus/ cd /opt/prometheus vim ...

  4. .Net WebApi 中的 FromBody FromForm FromQuery FromHeader FromRoute

    在日常后端Api开发中,我们跟前端的沟通中,通常需要协商好入参的数据类型,和参数是通过什么方式存在于请求中的,是表单(form).请求体(body).地址栏参数(query).还是说通过请求头(hea ...

  5. POJ3417 Network暗的连锁 (树上差分)

    树上的边差分,x++,y++,lca(x,y)-=2. m条边可以看做将树上的一部分边覆盖,就用差分,x=1,表示x与fa(x)之间的边被覆盖一次,m次处理后跑一遍dfs统计子树和,每个节点子树和va ...

  6. Vue学习之--------深入理解Vuex、原理详解、实战应用(2022/9/1)

    @ 目录 1.概念 2.何时使用? 3.搭建vuex环境 3.1 创建文件:src/store/index.js 3.2 在main.js中创建vm时传入store配置项 4.基本使用 4.1.初始化 ...

  7. 记录一次成功反混淆脱壳及抓包激活app全过程

    记录一次成功反混淆脱壳及抓包激活app全过程 前言 ​ 近期接到一个需求,要对公司之前开发的一款app进行脱壳.因为该app是两年前开发的,源代码文件已经丢失,只有加壳后的apk文件,近期要查看其中一 ...

  8. Droplet——一款轻量的Golang应用层框架

    Github地址 如标题所描述的,Droplet 是一个 轻量 的 中间层框架,何为中间层呢? 通常来说,我们的程序(注意这里我们仅仅讨论程序的范围,而非作为一个系统,因此这里不设计如 LB.Gate ...

  9. Debian11管理员手册

    1 用户与群组数据库 用户清单通常保存在 /etc/passwd 文件内,把哈希编码后的密码保存在 /etc/shadow 文件内.这两个文件都是纯文本档,以简单的格式保存,可以用文本编辑器读取与修改 ...

  10. 三种梯度下降法的对比(BGD & SGD & MBGD)

    常用的梯度下降法分为: 批量梯度下降法(Batch Gradient Descent) 随机梯度下降法(Stochastic Gradient Descent) 小批量梯度下降法(Mini-Batch ...