今日推荐语
一个人知道自己为什么而活,就可以忍受任何一种生活。—— 尼采
日期 | 学习内容 | 打卡编号 |
---|---|---|
2025年01月05日 | JDBC连接池技术配置与实战 | 014 |
前言
哈喽,我是菜鸟阿康。
今天学习了 jdbc 专题的连接池小节,利用连接池来操作数据。
以下是我的学习笔记,既做打卡也做分享,希望对你也有所帮助,不足之处欢迎大家交流指正。
(请忽略错误的大纲编号,我直接从笔记中粘贴过来的,就没严格纠正了,重点在内容!)
文末和主页有往期学习笔记,大家感兴趣也可以去看下。
继续加油!铁铁们!
三、JDBC 优化
(一)JDBC 链接数据库优化
原有配置方式都是将链接的各种参数在代码中写死,导致耦合性比较高,不利于维护。
通过读取配置文件的方式读取参数,能降低耦合性。
备注:
读取配置文件有3种方式:绝对路径,当前工具类获取相对路径,当前线程获取相对路径(其中,相对路径的方式需要将配置文件放到 resources 文件夹中)
(二)操作数据库
通过 java 代码操作增删改查,以下几点做得不够优雅(注意点):
1.@Test 测试方法
可以使用 @Test 关键字测试方法,定义一个专门的测试方法,方法名上加上注解,在内部调用方法即可测试,测试方法没有返回值。
2.分层构建代码
对不同代码的功能进行分层设计,降低耦合度和可读性
3.数据库与 java 实体映射
java 语言万物皆对象,数据表中的数据实体在代码中建立对应实体对象,方便数据操作库。
按照数据库与 java 数据类型的对应关系定义实体类的字段。
4.针对资源关闭定义通用方法
通过 jdbc 操作完数据库,需要对结果集,数据库链接,statement 对象 进行关闭,并且可以抽象出通用方法进行精简代码。
四、数据库连接池
(一)存在问题
原有方式是:建立连接--》操作数据库--》关闭资源,这种方式容易出现3个问题:
- 频繁建立、关闭资源消耗系统资源。jdbc 通过DriverManager 来获取连接,每一次都需要将 Connection 对象加载到内存中,还需要验证账号和密码,会给系统造成压力。
- 并发能力弱。若服务器有几百人或者几千人同时去获取连接关闭连接,可能会导致服务器崩溃。
- 不具备资源管理能力。这种开发方式不能去管理创建的连接对象,分配资源没有管理能力。可能导致内存泄露服务崩溃。
- 如果只建立连接不断开连接,会导致内存泄露,导致需要重启mysql服务器。
(二)数据库连接池
1.概述
为了避免以上问题,引入数据库连接池技术,把为连接建立对应的连接池供系统各功能调用,具体有以下方式规避:
- 数据库连接池即一个资源容器,专门负责分配管理数据库的连接。
- 支持复用,不需要新建,允许应用程序重复使用现有的数据库连接。
- 自动优化资源占用问题。连接池可设置最大空闲时间来释放掉不再使用数据库资源,避免无效占用。
2.意义(面试)
- 资源重用
- 提升系统的性能
- 避免数据库连接的泄露
3.连接池配置
连接池技术是第三方组织实现 SUN 公司提供的数据库连接池标准接口,在标准接口 DataSource定义连接的功能,不在需要 DriverManager 对象去获取连接对象 Connection。
3.1 常见连接池
- DBCP
Apache 提供的数据库连接池,速度相对于 C3P0 较快
DBCP – Download Apache Commons DBCP
- C3P0
速度相对较慢,稳定性可以,Hibernate 官方推荐使用
- 1.下载地址 https://sourceforge.net/projects/c3p0/
- 2.文档 c3p0-v0.10.1 - JDBC3 Connection and Statement Pooling - Documentation
- Druid(德鲁伊)
阿里提供的数据库连接池,涵盖以上连接池优点,速度不一定是最快的,但是企业使用最多。
https://github.com/alibaba/druid
4.三大常见连接池
4.1 DBCP连接池
- 配置方法
https://mvnrepository.com/artifact/org.apache.commons
通过 maven 仓库找到 apache 下边的commons 下载连接池依赖,这里会用到 dbcp ,pool2 , logging 依赖,如果出现报错,直接在以上 maven 路径中 找到对应 jar 包下载导入即可。
比如在这里缺少了logging 的依赖,则直接去https://mvnrepository.com/artifact/org.apache 中下载即可。
- 使用方法
开发文档: org.apache.commons.dbcp2 (Apache Commons DBCP 2.13.0 API)
在这里直接使用构造器,通过线程来获取配置文件中的连接参数进行连接。
备注:这里测试连接没有关闭资源,正规写法应该捕获异常、最后关闭资源。
/**
* dbcp获取连接
* @return
* @throws Exception
*/
public Connection getConnectionByDbcp() throws Exception {
BasicDataSource source = new BasicDataSource();
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
source.setDriverClassName(properties.get("driverClassName").toString());
source.setUrl(properties.get("url").toString());
source.setUsername(properties.get("username").toString());
source.setPassword(properties.get("password").toString());
Connection conn = source.getConnection();
return conn;
}
3.参数介绍
属性名称 | 文字说明 |
initialSize | 连接池启动时创建的初始化连接数量(默认值为0) |
maxActive | 连接池中可同时连接的最大的连接数(默认值为8,调整为20,高峰单机器在20并发左右,自己根据应用场景定) |
maxIdle | 连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制(默认为8个,maxIdle不能设置太小,因为假如在高负载的情况下,连接的打开时间比关闭的时间快,会引起连接池中idle的个数 上升超过maxIdle,而造成频繁的连接销毁和创建,类似于jvm参数中的Xmx设置) |
minIdle | 连接池中最小的空闲的连接数,低于这个数量会被创建新的连接(默认为0,调整为5,该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大,因为在机器很空闲的时候,也会创建低于minidle个数的连接,类似于jvm参数中的Xmn设置) |
maxWait | 最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待(默认为无限,调整为60000ms,避免因线程池不够用,而导致请求被无限制挂起) |
poolPreparedStatements | 开启池的prepared(默认是false,未调整,经过测试,开启后的性能没有关闭的好。) |
maxOpenPreparedStatements | 开启池的prepared 后的同时最大连接数(默认无限制,同上,未配置) |
minEvictableIdleTimeMillis | 连接池中连接,在时间段内一直空闲, 被逐出连接池的时间 |
removeAbandonedTimeout | 超过时间限制,回收没有用(废弃)的连接(默认为 300秒,调整为180) |
removeAbandoned | 超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收(默认为false,调整为true) |
4.2 c3p0连接池
依赖下载:https://mvnrepository.com/artifact/com.mchange/c3p0
可以通过set方式配置数据库参数,也可以通过 xml 配置文件的方式配置。
使用方法 : c3p0-v0.10.1 - JDBC3 Connection and Statement Pooling - Documentation
xml 配置参数:c3p0-v0.10.1 - JDBC3 Connection and Statement Pooling - Documentation
注意:
c3p0通过 xml 配置方式时,定义的参数名需要和官方文档(网页往下划 tomcat )一样
public Connection getConnectionByc3p0() throws Exception {
ComboPooledDataSource cpds = new ComboPooledDataSource("c3p0_test")//xml里定义的连接池名字;
return cpds.getConnection();
}
4.3 Druid (德鲁伊)连接池
阿里巴巴开源连接池,目前企业中使用最多的连接池技术。
官方文档:https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
maven 仓库地址:https://mvnrepository.com/repos/wso2-public
/**
* druid 获取连接
* @throws Exception
*/
public Connection getConnectionByDruid() throws Exception {
DruidDataSource druidDataSource = new DruidDataSource();
//通过配置文件读取 mysql 参数
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
druidDataSource.setDriverClassName(properties.get("driverClassName").toString());
druidDataSource.setUrl(properties.get("url").toString());
druidDataSource.setUsername(properties.get("username").toString());
druidDataSource.setPassword(properties.get("password").toString());
DruidPooledConnection conn = druidDataSource.getConnection();
return conn;