package com.sm.utils
import java.sql.{Connection, PreparedStatement, SQLException, Statement}
import java.util.Properties
import com.alibaba.druid.pool.DruidDataSourceFactory
import com.sm.common.conf.ConfigManager
import com.sm.constants.Constants
import javax.sql.DataSource
import org.slf4j.LoggerFactory
/**
* Druid 连接池工具类
*
* create by LiuJinHe 2020/8/5
*/
object DruidUtils {
private[this] val logger = LoggerFactory.getLogger(this.getClass.getSimpleName)
// 获取Druid连接池的配置文件
private val druidProps: Properties = ConfigManager.load(Constants.DRUID_PROP)
// 初始化线程池
var dataSource: DataSource = _
def initDataSource(): Unit = {
if(dataSource == null){
try {
dataSource = DruidDataSourceFactory.createDataSource(druidProps)
} catch {
case e: Exception =>
logger.error("初始化连接池失败...", e)
}
}
}
/**
* 获取连接
*/
def getConnection: Connection = {
dataSource.getConnection()
}
/**
* 提交事务
*/
def commit(conn: Connection): Unit = {
if (conn != null) {
try {
conn.commit()
} catch {
case e: SQLException =>
logger.error(s"提交数据失败,conn: $conn", e)
} finally {
close(conn)
}
}
}
/**
* 事务回滚
*/
def rollback(conn: Connection): Unit = {
if (conn != null) {
try {
conn.rollback()
} catch {
case e: SQLException =>
logger.error(s"事务回滚失败,conn: $conn", e)
} finally {
close(conn)
}
}
}
/**
* 关闭连接
*/
def close(conn: Connection): Unit = {
if (conn != null) {
try {
conn.close()
} catch {
case e: SQLException =>
logger.error(s"关闭连接失败,conn: $conn", e)
}
}
}
/**
* 关闭连接
*/
def close(ps: PreparedStatement, conn: Connection): Unit = {
if (ps != null) {
try {
ps.close()
} catch {
case e: SQLException =>
logger.error(s"关闭连接失败,ps: $ps", e)
}
}
close(conn)
}
/**
* 关闭连接
*/
def close(stat: Statement, conn: Connection): Unit = {
if (stat != null) {
try {
stat.close()
} catch {
case e: SQLException =>
logger.error(s"关闭连接失败,stat: $stat", e)
}
}
close(conn)
}
}
配置文件
# 40
url = jdbc:mysql://10.0.0.6:3306/origin_platform?useSSL=false&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&rewriteBatchedStatements=true&useServerPrepStmts=true
username = xxx
password = xxx
driverClassName = com.mysql.cj.jdbc.Driver
# 初始化时建立连接的数量
initialSize = 8
# 最大连接池数量
maxActive = 50
# 最小空闲连接池数量
minIdle = 1
# 获取连接时最大等待时间
maxWait = 60000
# 检测需要关闭的空闲连接的间隔时间,单位毫秒,1分钟运行一次空闲连接回收器
# 检测时:
# 1.如果连接空闲并且超过minIdle以外的连接,如果空闲时间超过minEvictableIdleTimeMillis设置的值则直接物理关闭。
# 2.在minIdle以内的不处理。
timeBetweenEvictionRunsMillis = 60000
# 连接在连接池中的最小空闲时间,单位毫秒,池中的连接空闲 220秒/3分40秒 后被回收
# 注意:minEvictableIdleTimeMillis + timeBetweenEvictionRunsMillis < wait_timeout
# 40 mysql wait_timeout 为 360秒(6分钟)
minEvictableIdleTimeMillis = 220000
# 最大空闲存活时长
# 注意:maxEvictableIdleTimeMillis - minEvictableIdleTimeMillis > timeBetweenEvictionRunsMillis
maxEvictableIdleTimeMillis = 290000
# 检测连接是否有效
validationQuery = select 1
# validationQueryTimeout 最好配置,不然可能出现长达15分钟的校验时间,导致整个查询超时
validationQueryTimeout = 1
# 如果空闲时间大于 timeBetweenEvictionRunsMillis
# 执行 validationQuery 检测连接是否有效
testWhileIdle = true
# 申请连接时执行 validationQuery 检测连接是否有效, 影响效率
testOnBorrow = false
# 归还连接时执行 validationQuery 检测连接是否有效
testOnReturn = false
# 关闭自动提交
defaultAutoCommit = false
# 在小于minIdle连接数的时候执行保活操作
# 初始化连接池时会填充到 minIdle 数量
# 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作
# 当网络断开等原因产生的由ExceptionSorter检测出来的死连接被清除后,自动补充连接到minIdle数量
keepAlive = true
# 从线程池获取的连接超过时间限制是否回收
#removeAbandoned = true
# 超时时间,单位秒。默认1800 秒为30分钟
#removeAbandonedTimeout = 300
#logAbandoned = false