Java开发工程师(Web方向) - 03.数据库开发 - 第2章.数据库连接池
第2章--数据库连接池
数据库连接池
一般而言,在实际开发中,往往不是直接使用JDBC访问后端数据库,而是使用数据库连接池的机制去管理数据库连接,来实现对后端数据库的访问。
建立Java应用程序到后端数据库的物理连接:conn = DriverManager.getConnection(...);
虽然这只是一个方法调用,但是在JDBC的驱动中,就已经完成了大量客户端与服务器端的交互
这里以MySQL数据库为例(MySQL客户端和MySQL服务器端的交互):
1. 客户端发送给服务器端TCP请求
2. 服务器端随机生成密码种子返回给客户端
3. 客户端利用密码种子和自己保存的数据库密码按照约定的加密算法计算得到加密密码,将其发送给服务器端进行验证
4. 服务器端验证完成确认链接建立成功
一个getConnection方法,就需要了四次网络传输:时间开销大
实际开发中,但用户要访问Java程序时,会启动一个线程去处理用户的请求。在处理过程中,如果需要访问后端数据库,则需要创建一个Connection对象来建立到后端数据库的物理连接。之后,随着close方法被调用,该连接被销毁。业务处理完成后,该线程被释放。但是当用户再次发起一个请求时,又要重新建立新的线程,创建新的Connection对象等等......花费大量时间在建立连接上,响应时间增长。
-->连接复用(创建连接--改变为-->租借连接)
每个线程在使用数据库连接后,并不立即销毁,而是把连接交给下一个需要访问数据库的线程。多个线程共用到后端数据库的物理连接,实现连接复用
连接池:每个需要访问数据库的线程到连接池中租借到数据库的连接,使用完毕后再归还给连接池,即可实现连接的重复使用。
数据库服务器端在处理我们的服务请求时,都会在服务器端分配一定的资源,比如内存用来保存数据库查询的结果。在请求处理结束以后,释放这些资源。而服务器端的资源是有限的,不能无限制地分配。当同时有多个数据库请求访问数据库时,服务器端能处理的连接数是有限的。当超过最大可分配的资源时,会出现服务器down机的故障。同时,过多的连接数对后端数据库的性能也有很大影响。连接数增多,数据库会产生很多锁的检测,加大数据库服务器端的资源消耗。为了限制并发访问的连接数,数据库服务器端会设置最大的并发连接数,若超过,则会抛异常。一方面,直接抛异常这个处理并不友好,Java程序需要捕获异常并进行异常处理,另一方面,不能仅仅依靠服务端的最大连接数限制,而应该在数据库访问客户端的时候做到限流,数据库连接需要被有序可控地限制使用,多一种保护手段。
-->限制连接(需要在客户端的Java程序中,实现业务线程排队获取数据库连接、限制最大并发线程数,起到限流、对后端数据库的保护作用。
使用连接池解决。
连接池:本质为一组Java jar包,介于应用程序和数据库JDBC的物理连接之间,负责帮助应用程序来管理JDBC连接,通过连接池暴露的接口,应用程序可以获取数据库连接。使用完毕以后,可以将数据库连接归还给连接池供下一个线程使用。连接池对JDBC连接进行有效管理,在连接池中的JDBC连接不足时,会自动创建连接;在空闲连接较多时,会自动销毁连接;在有多个线程获取数据库连接时,连接池提供了排队等待的功能,保证了应用程序有序的获得数据库连接。
连接池的使用:DBCP连接池(使用最广的连接池)
DBCP:Apache开源项目,tomcat使用的连接池组件
包括三个jar包:commons-dbcp.jar commons-pool.jar commons-logging.jar
下载对应的jar包(缺一不可)https://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi
右键project->Properties->Build Path->Libraries->add external jars->commons-dbcp2-2.1.1.jar
结构:
创建连接池对象:BasicDataSource对象表示一个连接池
告诉DBCP如何连接到JDBC:
.Url / .DriverName / .User / .Password
方法:
basicDataSource.getConnection():从连接池中租借一个连接以访问后端数据库
之后的操作同JDBC,如stmt = conn.createStatement(); rs = stmt.executeQuery(...);等
conn.close():完成操作后,需将连接归还(在JDBC时为销毁连接close(),而DBCP重写了Connection的close方法)
高级配置:
.setInitialSize(); // 第一次访问需要花费较多时间在创建连接等上。解决方法:应用程序启动时在连接池中预置一些连接,以保证第一次访问时已经有一定数量的连接。一般设置为预期业务平均访问量。
.setMaxTotal();// 当连接池中没有空闲连接,并有新的访问需要连接时,连接池会创建新的连接。但若此时连接数已经达到了MaxTotal,则连接池不会新建连接,而是强制让该进程进入等待队列。setMaxTotal()起到了限流保护数据库的作用。
.setMaxWaitMillis(); // 设置最大等待时间,当超过该时间,应用程序会得到一个SQLException异常
.setMaxIdle(); // 若连接池中的空闲连接数超过了maxIdle的数量,则会销毁一部分数据连接。减少不必要的资源损耗。
.setMinIdle(); // 反之,连接池中空闲连接数少于minIdle数量,则会创建一些连接,来保证连接池中有足够连接用于租借。一般为了避免不断进行销毁和创建连接,会将maxIdle和minIdle设置为一样的值。
// 定期检查功能。数据库服务端为了释放一些空闲等待的资源,默认自动关闭空闲时间超过一定数值的数据库连接(MySQL默认关闭空闲超过8小时的数据库连接)。而服务器端关闭连接后,客户端并不知道连接已经被关闭了,当应用程序向连接池租借连接时,很可能将这些失效的连接租借出去从而出现SQLException异常。检查:当服务器端关闭连接之前,会将连接销毁掉,来保证应用程序租借的连接都是有效的。
.setTestWhileIdle(True); // 开启上述功能
.setMinEvictableIdleTimeMillis(); // 销毁连接的最小空闲时间:当连接的空闲时间超过该值时,自动销毁该连接
.setTimeBetweenEvictionRunsMillis(); // 检查的间隔,建议小于服务器端自动关闭连接的时间
数据库连接池单元测试
以下哪项不是使用数据库连接池带来的好处?
- A.连接池可以帮助用户屏蔽数据库服务端异常,使用连接池,应用程序不需要处理数据库异常。5.00/5.00
- B.当应用程序访问后端数据库的连接数超过设定的最大连接数限制时,连接池可以使得应用程序排队有序获取数据库连接。
- C.限制应用程序并发访问数据库的连接数,避免因为连接过多导致的数据库服务端资源耗尽,引发故障;
- D.避免每次访问数据库都新建立连接,节省连接的创建和销毁时间,提高应用程序访问后端数据库的性能。
有关DBCP的描述,下面哪项是不正确的?
- A.DBCP是apache基金会下面的一个开源数据库连接池项目。
- B.一个DBCP连接池可以创建多个不同数据库的连接。5.00/5.00
- C.DBCP底层依赖JDBC实现客户端到服务器端的数据库连接,所以即使使用DBCP,也需要加载MySQL JDBC 驱动架包。
- D.使用DBCP需要下载相应的JAR架包,加载到项目工程中。
以下哪个方法是DBCP将数据库连接归还给数据库连接池?
- A..setMaxTotal()
- B..close()5.00/5.00
- C..setTestWhileIdle()
- D..getConnection()
下列哪项是需要设置数据库连接定期检查的原因?
- A.避免应用程序第一次启动时,获取连接过慢。
- B.防止并发访问的数据库连接数过多,造成数据库服务端资源耗尽引发数据库宕机。
- C.避免数据库连接池中连接过少,造成应用程序访问数据库性能过差。
- D.防止服务端数据库连接异常关闭,导致连接池中的数据库连接失效。5.00/5.00
设置数据库连接定期检查,需要使用那几个方法?
- A..setTestWhileIdle()13.33/40.00
- B..setTimeBetweenEvictableRunMillis()13.33/40.00
- C..setMaxTotal()
- D..setMinEvictableIdleTimeMillis()13.33/40.00
为了避免连接池频繁的创建和销毁数据库连接,一般建议将MaxIdle和MaxTotal设置为一样。
- A.×
- B.√10.00/10.00
在设置数据库连接池MaxTotal参数时,应大于等于服务端MySQ设置的数据库最大连接数限制。
- A.×10.00/10.00
- B.√
数据库连接池作业
https://my.oschina.net/hava/blog/751954
需要同学们使用刚刚学习的数据库连接池相关知识,完成一道编程题目。
请使用DBCP数据库连接池改造上节课程作业中完成的输出商品名称和库存的应用程序,通过连接池实现对数据库的访问。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.commons.dbcp2.BasicDataSource; public class ProductProcessingDBCPAssignment { public static BasicDataSource bs = null;
public static final String DRIVER_NAME = "com.mysql.jdbc.Driver";
public static final String DB_URL = "jdbc:mysql://localhost/productDB";
public static final String DB_USER_NAME = "matt";
public static final String DB_PASSWORD = "matt"; public static void dbcpInit() throws ClassNotFoundException{
bs = new BasicDataSource();
bs.setUrl(DB_URL);
bs.setDriverClassName(DRIVER_NAME);
bs.setUsername(DB_USER_NAME);
bs.setPassword(DB_PASSWORD);
} public static void dataProcessing() {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = bs.getConnection();
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT ProductName, Inventory FROM Product Where Id=1");
while(rs.next()) {
System.out.println(rs.getString("ProductName") + ": " + rs.getString("Inventory"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (conn != null) conn.close();
if (stmt != null) stmt.close();
if (rs != null) rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) throws ClassNotFoundException {
dbcpInit();
dataProcessing();
}
}
Java开发工程师(Web方向) - 03.数据库开发 - 第2章.数据库连接池的更多相关文章
- Java开发工程师(Web方向) - 03.数据库开发 - 第5章.MyBatis
第5章--MyBatis MyBatis入门 Abstract: 数据库框架的工作原理和使用方法(以MyBatis为例) 面向对象的世界与关系型数据库的鸿沟: 面向对象世界中的数据是对象: 关系型数据 ...
- Java开发工程师(Web方向) - 03.数据库开发 - 第3章.SQL注入与防范
第3章--SQL注入与防范 SQL注入与防范 经常遇到的问题:数据安全问题,尤其是sql注入导致的数据库的安全漏洞 国内著名漏洞曝光平台:WooYun.org 数据库泄露的风险:用户信息.交易信息的泄 ...
- Java开发工程师(Web方向) - 03.数据库开发 - 期末考试
期末考试 编程题 本编程题包含4个小题,覆盖知识点从基础的JDBC.连接池到MyBatis. 1(10分) 有一款在线教育产品“天天向上”主要实现了在手机上查看课程表的功能.该产品的后端系统有一张保存 ...
- Java开发工程师(Web方向) - 03.数据库开发 - 第1章.JDBC
第1章--JDBC JDBC基础 通过Java Database Connectivity可以实现Java程序对后端数据库的访问 一个完整的数据库部署架构,通常是由客户端和服务器端两部分组成 客户端封 ...
- Java开发工程师(Web方向) - 03.数据库开发 - 第4章.事务
第4章--事务 事务原理与开发 事务Transaction: 什么是事务? 事务是并发控制的基本单位,指作为单个逻辑工作单元执行的一系列操作,且逻辑工作单元需满足ACID特性. i.e. 银行转账:开 ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第2章.IoC容器
第2章.IoC容器 IoC容器概述 abstract: 介绍IoC和bean的用处和使用 IoC容器处于整个Spring框架中比较核心的位置:Core Container: Beans, Core, ...
- Java开发工程师(Web方向) - 04.Spring框架 - 第1章.Spring概述
第1章.Spring概述 Spring概述 The Spring Framework is a lightweight solution and a potential one-stop-shop f ...
- Java开发工程师(Web方向) - 02.Servlet技术 - 第3章.Servlet应用
第3章.Servlet应用 转发与重定向 转发:浏览器发送资源请求到ServletA后,ServletA传递请求给ServletB,ServletB生成响应后返回给浏览器. 请求转发:forward: ...
- Java开发工程师(Web方向) - 02.Servlet技术 - 第2章.Cookie与Session
第2章--Cookie与Session Cookie与Session 浏览器输入地址--HTTP请求--Servlet--HTTP响应--浏览器接收 会话(session):打开浏览器,打开一系列页面 ...
随机推荐
- mongodb副本集优先级设置
在设置mongodb副本集时,Primary节点.second节点,仲裁节点,有可能资源配置(CPU或者内存)不均衡,所以要求某些节点不能成为Primary我们知道mongodb的设置: 除了仲裁节 ...
- 【luogu P3623 [APIO2008]免费道路】 题解
题目链接:https://www.luogu.org/problemnew/show/P3623 说是对克鲁斯卡尔的透彻性理解 正解: 先考虑加入水泥路,然后再考虑加入剩下必须要加入的最少鹅卵石路. ...
- Android大图片裁剪终极解决方案(下:拍照截图)
http://blog.csdn.net/floodingfire/article/details/8144617 http://mzh3344258.blog.51cto.com/1823534/8 ...
- CodeForces - 607B (记忆化搜索)
传送门: http://codeforces.com/problemset/problem/607/B Genos recently installed the game Zuma on his ph ...
- HDU 2050(折线分割平面)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2050 折线分割平面 Time Limit: 2000/1000 MS (Java/Others) ...
- center os 7 修改 mysql 密码
笔记 本redis 密码 654321忘记密码:修改密码update user set authentication_string=password('123456') where user='roo ...
- 多线程异步非阻塞之CompletionService
引自:https://www.cnblogs.com/swiftma/p/6691235.html 上节,我们提到,在异步任务程序中,一种常见的场景是,主线程提交多个异步任务,然后希望有任务完成就处理 ...
- SQL Server 2012 - 开窗函数
-- 开窗函数:在结果集的基础上进一步处理(聚合操作) -- Over函数,添加一个字段显示最大年龄 SELECT * , MAX(StuAge) OVER ( ) MaxStuAge FROM db ...
- iOS手势识别器
UIGestureRecognizer UIGestureRecognizer类,用于检测.识别用户使用设备时所用的手势.它是一个抽象类,定义了所有手势的基本行为.以下是UIGestureRecogn ...
- React 父子组件和非父子组件传值
零.this.props 可以接收到 外界的传值 和 此组件标签内部自定义的方法 例: <one vals={message} sendVal={this ...