目录
1.为什么需要连接池呢?
2.什么是连接池
3. 连接池的工作原理
3.1详解连接池的工作原理
3.1.1连接池的创建:
3.1.2?连接池的管理
3.1.3?连接池的关闭
3.1.4相关词组详解
4.连接池的规范
4.1JavaEE规范规定:
4.2常见的第三方连接池
5.如何使用Druid
5.1 导入jar包
5.2 入门案例
1.为什么需要连接池呢?
-
Java程序操作数据库,必须获得一个连接Connection -
实际操作中,我们要先获得连接,使用完成后还有关闭连接。这两个操作都比较耗时。 -
思考:那有没有什么比较方便不耗时的方法呢?当我们要用的时候只需要调用一下就ok,用完了再还回去。这样岂不是免去了【获得、关闭连接】节省了很多时间?那应该怎么实现呢? -
答疑:连接池,就是用于解决这一问题而被需要的。连接池,将我们所需要的连接,放入池子里,形成公共连接。且该池子中的连接被调用时,有且只能被一个人使用,当该连接被归还时,即可恢复为公共连接,被别人重新调用。
2.什么是连接池
-
一组连接组成的一个池子(集合),称为连接池。
-
在描述连接池的工作原理前,先思考思考几个问题???
? 3. 问题解答:
- 问题1:一开始连接池会进行系统初始化,根据系统配置建立,并创建几个连接对象【初始化】
- 问题2:添加的新连接不能超过最大连接数
- 问题3:自动创建即可。
-
如果初始化只有3个连接,但我现在需要第4个连接,该怎么办呢? -
第4个连接我们可以自动创建,但是随着我们的需求越来越多,自动创建连接可以无限创建吗? -
不能,因为连接池中有最大连接数,最大连接数限制了连接的个数,超过了最大连接数就会报错,栈内存溢出异常?
- 问题4:不能,有最大连接数。最大连接数限制了连接的个数,不能超过最大连接数,不然会报栈内存溢出异常。
- ?问题5:因为有最小连接数,所有不能让池子全部空闲,占内存。所以池子中总是有这么几个连接【最小连接数】在等待着被人连接使用
3. 连接池的工作原理
3.1详解连接池的工作原理
3.1.1连接池的创建:
当用户需要访问数据库时,连接池会根据系统初始化,根据系统配置建立。并创建几个连接对象,等待着被需要的用户连接
3.1.2?连接池的管理
1.用户根据需要去连接池获取一个独享连接进行复用;
2.这时连接池接到用户的请求,会从连接池中随意移出一个空闲的连接给用户。如果没有空闲连接,且尚未达到连接的最大连接数,就是 创建一个新的连接,在将新的连接交给用户。如果没有空闲连接,且也已经达到最大连接数的限制,则程序会先让其等待一段时间,如果超过了等待的时间还没有其他空闲的连接,那么程序则会报栈内存溢出异常。
3.当用户获得连接使用完毕后,会将其连接归还给连接池 。在归还连接时,会对其连接池中的连接进行判断,看是否达到最大空闲数,如果已经达到看最大空闲数,已经没有空闲的位置了,那么就会直接将该对象丢弃。如果归还连接时,连接池中的连接小于最小空闲数,则会创建新的对象,来保证连接数大于等于最小空闲数【最小连接数】
4.其实,在我们归还连接后,对于 大于最小空闲和小于最大空闲时,会根据连接的最小空闲时间,做空闲连接检测,如果该连接空闲的时间超过了最小空闲时间,则会将其移除,清除清理掉。【大于最小空闲连接:就是在最小连接是基础上,多出来的那个或几个连接;】【 小于最大空闲连接:就是如最大空闲数是5个,现在却只有4个空闲,则现在的空闲数就小于了最大空闲数,反过来说也就是大于最小空闲数。因为,最大连接数 = 最小连接数+最大空闲数,而最小连接数其实又是最小空闲数即:最大连接数=最小空闲数+最大空闲数,不管那边发生改变都将会造成影响,天平的两端都将不会平衡】
3.1.3?连接池的关闭
当应用程序关闭时,会关闭连接池中的所有连接,释放连接池中相关的资源。但也不是将所有的连接全部关闭,因为如果将其全部关闭了不仅仅占内存,而且如果下一次有用户要进行复用连接的时候,还降低了效率。所有连接池有一个最小连接数,当关闭程序时,连接池会留下几个连接继续处于空闲等待状态,等待着被其他用户连接,其他连接则会被关闭释放资源,连接池就只剩下最小连接数个连接。
3.1.4相关词组详解
-
最大连接数:意思就是在这个连接池中最大可以存放多少个连接 -
最小连接数:意思就是在这个连接池中至少要存在多少个连接,一般系统进行初始化时创建的连接的个数可视为最小连接数 -
最大空闲数:意思就是在最大连接数中除去最小连接数的个数,还剩下多少个连接,可视为可以最大,最多能空闲下来的连接数
4.连接池的规范
4.1JavaEE规范规定:
-
JavaEE规范规定:连接池必须实现javax.sql.DataSource 接口 -
接口中规定方法:getConnection()
4.2常见的第三方连接池
5.如何使用Druid
5.1 导入jar包
<dependency>
? <groupId>com.alibaba</groupId>
? <artifactId>druid</artifactId>
? <version>1.2.4</version>
</dependency>
5.2 入门案例
package com.czxy;
?
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import org.junit.Test;
?
import java.sql.SQLException;
?
public class TestDruid {
? ?@Test
? ?public void testDemo() throws SQLException {
? ? ? ?//1 获得连接池
? ? ? ?//1.1 核心类
? ? ? ?DruidDataSource dataSource = new DruidDataSource();
? ? ? ?//1.2 基本4项
? ? ? ?// 1) 驱动
? ? ? ?dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
? ? ? ?// 2) 连接
? ? ? ?dataSource.setUrl("jdbc:mysql://localhost:3306/ssm_db1");
? ? ? ?// 3) 用户
? ? ? ?dataSource.setUsername("root");
? ? ? ?// 4) 密码
? ? ? ?dataSource.setPassword("1234");
? ? ? ?//1.3 特殊项【可选】
? ? ? ?// 1) 初始化大小
? ? ? ?dataSource.setInitialSize(5);
? ? ? ?// 2) 最大值活动数
? ? ? ?dataSource.setMaxActive(10);
? ? ? ?// 3) 最小空闲数
? ? ? ?dataSource.setMinIdle(2);
?
? ? ? ?//2 从连接池中获得连接
? ? ? ?//对比两次获取到的连接是否一致
? ? ? ?DruidPooledConnection conn = dataSource.getConnection();
? ? ? ?System.out.println(conn);
? ? ? ? //用完了,返还到连接池中
? ? ? ?conn.close();
?
? ? ? ?DruidPooledConnection conn2 = dataSource.getConnection();
? ? ? ?System.out.println(conn2);
? ? ? ?conn2.close();
? }
}
结果输出的地址是一样的,
?----------? 如果第一次获取到的连接没有返还回去,那么所得到的连接地址会一样吗?答案是否定的
//2 从连接池中获得连接
? ? ? ?//对比两次获取到的连接是否一致
? ? ? ?DruidPooledConnection conn = dataSource.getConnection();
? ? ? ?System.out.println(conn);
? ? ? ? //用完了,返还到连接池中
//将其释放资源,进行删除,不进行归还处理
// ? ? ? connection.close();
?
? ? ? ?DruidPooled Connection conn2 = dataSource.getConnection();
? ? ? ?System.out.println(conn2);
? ? ? ?conn2.close();
|