今日内容:
  • 数据库连接池
  • 简化操作--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. 02 uniapp/微信小程序 项目day02

    一.分类 1.1 页面布局 首先创建cate的分支 定义基本结构,因为是两个需要滚动的区域,所以这里要用到组件 scroll 这个组件如果是y scroll那就要固定高度,x scroll那就要固定宽 ...

  2. kubernetes中部署kube-prometheus项目解决ControllerManager与Scheduler无法监控问题

    文章转载自:https://www.kococ.cn/20210302/cid=697.html 一.问题描述 在部署 kube-prometheus 到 kubernetes 集群中总会遇到一个问题 ...

  3. 查看docker容器占用的内存

    # 获取容器ID docker ps => 3b7fa46d9d43 # 根据容器ID获取对应的进程 docker top 3b7fa46d9d43 => 179733 # 查看进程占用的 ...

  4. 如何评判一个企业是否需要实施erp系统?

    一个企业是否需要实施ERP系统很大程度上取决于其规模.这里需要向提问者说明的一点是:很多企业上ERP,并不会用得到MRP,ERP是企业资源计划,不是制造业企业专用,MRP也不是ERP必须,金融.保险之 ...

  5. 前端微信登录获取code,userInfo,openid

    getUser(e) { wx.getUserProfile({ desc: '用户完善会员资料', success: res => { let userInfo = res.userInfo; ...

  6. POJ3662 [USACO08JAN]Telephone Lines (二分答案/分层图求最短路)

    这道题目有两种解法: 1.将每个点视为一个二元组(x,p),表示从起点到x有p条路径免费,相当于构建了一张分层图,N*k个节点,P*k条边.在这张图上用优先队列优化的SPFA算法求解,注意这里的d数组 ...

  7. Upscayl,免费开源的 AI 图像增强软件

    有的时候我们找遍了全网却难以找到一张模糊图片的原图,这时候我们想如果能够一键将图片变成高清的就好了.其实这正是计算机视觉的一大研究反向--图形增强,通过AI计算将模糊的图片增强,将几百kb的低像素图片 ...

  8. CentOS 7.9 安装 kafka_2.13

    一.CentOS 7.9 安装 kafka_2.13 地址 https://kafka.apache.org/downloads.html 二.安装准备 1 安装JDK 在安装kafka之前必须先安装 ...

  9. Selenium+Python系列 - 开发环境搭建

    一.写在前面 我从未想过自己会写python系列的自动化文章,有些同学会问,那你现在为什么又开始写了? 不止一个人找过我,问我可以写一些Python自动化的文章吗,答案是肯定的. 笔者Java党,整P ...

  10. IDEA快速生成数据库表的实体类

    IDEA连接数据库 IDEA右边侧栏有个DataSource,可以通过这个来连接数据库,我们先成功连接数据库 点击进入后填写数据库进行连接,注意记得一定要去Test Connection 确保正常连接 ...