com.alibaba.druid

关于数据库连接池

我们都知道,在使用数据库时,基本分为三步骤。

  1. 建立数据库连接。
  2. 执行sql
  3. 关闭或销毁连接

但是,如果每执行一次sql都需要经过这三步的话,可以明显看出,第1步和第2步是重复的,这样会增加不必要的系统开销,影响系统的效率,由此我们引进数据库连接池来解决这些问题:

数据库连接池通过在内部维护一定数量的数据库连接,并对外暴露数据库连接的获取和返回方法。外部使用者可通过getConnection方法获取数据库连接,使用完毕后再通过releaseConnection方法将连接返回,注意此时的连接并没有关闭,而是由连接池管理器回收,并为下一次使用做好准备,这样就体现出了数据库连接池的优点:

由于数据库连接得到重用,避免了频繁创建、释放连接引起的大量性能开销。在减少系统消耗的基础上,增进了系统环境的平稳性(减少内存碎片以级数据库临时进程、线程的数量)

数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池内备用。此时连接池的初始化操作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。

在较为完备的数据库连接池实现中,可根据预先的连接占用超时设定,强制收回被占用的连接,从而避免了常规数据库连接操作中可能出现的资源泄露

由上可知,数据库连接池的主要功能类似于线程池,都是为了减少系统开支,提高系统的响应时间等。

Druid是什么?

Druid是目前Java语言中比较好的数据库连接池,Druid不仅提供了数据库连接池的功能,同时还提供了监控数据库状态,慢sql记录等比较实用的功能,帮助我们更好的操作数据库。

spring boot项目如何集成Druid?

对于SpringBoot项目,集成Druid是比较容易的:

  1. 添加mvn依赖如下:
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>{druid-version}</version>
</dependency>
  1. 添加如下的配置信息(mysql为例):
# MYSQL链接(常规的数据库连接属性,不做多余解释)
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.url=jdbc:mysql://localhost:3306/XXXX
spring.datasource.druid.username=admin
spring.datasource.druid.password=123456

# 连接池属性配置
#启动程序时,在连接池中初始化多少个连接
spring.datasource.druid.initial-size=10
#连接池中最多支持多少个活动会话
spring.datasource.druid.max-active=20
#回收空闲连接时,将保证至少有minIdle个连接.
spring.datasource.druid.min-idle=5
#程序向连接池中请求连接时,超过maxWait的值后,认为本次请求失败,即连接池没有可用连接,单位毫秒,设置-1时表示无限等待
spring.datasource.druid.max-wait=60000
#缓存通过以下两个方法发起的SQL: public PreparedStatement prepareStatement(String sql) public PreparedStatement prepareStatement(String sql,int resultSetType, int resultSetConcurrency)
spring.datasource.druid.pool-prepared-statements=false
#检查池中的连接是否仍可用的 SQL 语句,drui会连接到数据库执行该SQL, 如果正常返回,则表示连接可用,否则表示连接不可用
spring.datasource.druid.validation-query=select 'x'
spring.datasource.druid.validation-query-timeout=1
#程序 申请 连接时,进行连接有效性检查(低效,影响性能)
spring.datasource.druid.test-on-borrow=false
#程序 返还 连接时,进行连接有效性检查(低效,影响性能)
spring.datasource.druid.test-on-return=false
#当程序请求连接,池在分配连接时,是否先检查该连接是否有效。(高效)
spring.datasource.druid.test-while-idle=true
#检查空闲连接的频率,单位毫秒, 非正整数时表示不进行检查
spring.datasource.druid.time-between-eviction-runs-millis=60000
#池中某个连接的空闲时长达到 N 毫秒后, 连接池在下次检查空闲连接时,将回收该连接,要小于防火墙超时设置
spring.datasource.druid.min-evictable-idle-time-millis=180000
spring.datasource.druid.max-evictable-idle-time-millis=300000
spring.datasource.druid.filters=stat,wall,log4j

3.根据需要配置Filter

# 配置StatFilter(记录慢Sql,定义慢sql阈值等)
spring.datasource.druid.filter.stat.enabled=true
spring.datasource.druid.filter.stat.db-type=mysql
spring.datasource.druid.filter.stat.log-slow-sql=true
spring.datasource.druid.filter.stat.slow-sql-millis=2000
spring.datasource.druid.filter.stat.merge-sql=true
spring.datasource.druid.filter.stat.connection-stack-trace-enable=true

# 配置WallFilter
(可用于防御SQL注入攻击等,详细的配置说明见附录)
spring.datasource.druid.filter.wall.enabled=true
spring.datasource.druid.filter.wall.db-type=mysql
spring.datasource.druid.filter.wall.config.delete-allow=false
spring.datasource.druid.filter.wall.config.drop-table-allow=false

3.根据需要配置Druid内置监控页面
(增加如下配置后,可在启动项目后通过http://{ip}:{port}/druid/index.html访问监控页面,用户名密码为下面配置的值)

spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.login-username=admin
spring.datasource.druid.stat-view-servlet.login-password=123456
spring.datasource.druid.stat-view-servlet.reset-enable=false
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.web-stat-filter.url-pattern=/*
spring.datasource.druid.web-stat-filter.exclusions="*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
spring.datasource.druid.web-stat-filter.enabled=true

至此,Druid就已经集成到你的SpringBoot项目了。

附录-配置 wallfilter

拦截配置-语句

配置项缺省值描述
selelctAllowtrue是否允许执行SELECT语句
selectAllColumnAllowtrue是否允许执行SELECT * FROM T这样的语句。如果设置为false,不允许执行select * from t,但select * from (select id, name from t) a。这个选项是防御程序通过调用select *获得数据表的结构信息。
selectIntoAllowtrueSELECT查询中是否允许INTO字句
deleteAllowtrue是否允许执行DELETE语句
updateAllowtrue是否允许执行UPDATE语句
insertAllowtrue是否允许执行INSERT语句
replaceAllowtrue是否允许执行REPLACE语句
mergeAllowtrue是否允许执行MERGE语句,这个只在Oracle中有用
callAllowtrue是否允许通过jdbc的call语法调用存储过程
setAllowtrue是否允许使用SET语法
truncateAllowtruetruncate语句是危险,缺省打开,若需要自行关闭
createTableAllowtrue是否允许创建表
alterTableAllowtrue是否允许执行Alter Table语句
dropTableAllowtrue是否允许修改表
commentAllowfalse是否允许语句中存在注释,Oracle的用户不用担心,Wall能够识别hints和注释的区别
noneBaseStatementAllowfalse是否允许非以上基本语句的其他语句,缺省关闭,通过这个选项就能够屏蔽DDL
multiStatementAllowfalse是否允许一次执行多条语句,缺省关闭
useAllowtrue是否允许执行mysql的use语句,缺省打开
describeAllowtrue是否允许执行mysql的describe语句,缺省打开
showAllowtrue是否允许执行mysql的show语句,缺省打开
commitAllowtrue是否允许执行commit操作
rollbackAllowtrue是否允许执行roll back操作

如果把selectIntoAllow、deleteAllow、updateAllow、insertAllow、mergeAllow都设置为false,这就是一个只读数据源了

WallFilter配置说明

配置项缺省值描述
logViolationfalse对被认为是攻击的SQL进行LOG.error输出
throwExceptiontrue对被认为是攻击的SQL抛出SQLException

刚开始引入WallFilter的时候,把logViolation设置为true,而throwException设置为false。就可以观察是否存在违规的情况,同时不影响业务运行。

参考链接:点击这里

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这段代码是用于创建数据库连接池的。其中,`com.alibaba.druid.pool.DruidDataSourceFactory`是一个工厂类,用于创建`DruidDataSource`对象,而`DruidDataSource`则是一个数据库连接池。在使用这段代码之前,需要先导入相关的包,包括`com.alibaba.druid.pool.DruidDataSourceFactory`和`javax.sql.DataSource`等。具体使用方法可以参考以下代码: ```java import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class Test { public static void main(String[] args) throws SQLException, IOException { // 加载配置文件 Properties properties = new Properties(); InputStream inputStream = Test.class.getClassLoader().getResourceAsStream("druid.properties"); properties.load(inputStream); // 创建数据源 DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); // 获取连接 Connection connection = dataSource.getConnection(); // 执行查询 Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT * FROM user"); // 处理结果集 while (resultSet.next()) { System.out.println(resultSet.getString("name")); } // 关闭连接 resultSet.close(); statement.close(); connection.close(); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值