Tomcat从7.0之后使用他自己的连接池,不在使用Commons-dbcp
Commons-dbcp的缺点:
1. 单线程,为了保证线程安全会锁整个连接池
2. 性能不佳
3. 太复杂,超过60个类
4. dbcp使用静态接口,
5.发展滞后 (似乎不太更新了??)
Tomcat JDBC Pool 特点
1. 近乎兼容dbcp , 性能更高.
2. 异步方式获取连接 ??
3. 使用 javax.sql.PooledConnection接口来获取连接.
4. 支持高并发应用环境
5. 简单,核心文件只有8个.
6.更好的空闲连接处理机制
官方文档地址:Apache Tomcat8 JDBC Connection Pool
这里的例子,是将Tomcat JDBC Connection Pool组件拿出来,单独使用
在工作中,可以将这个组件放到需要的项目中单独使用
代码以及jar包:Tomcat JDBC Connection Pool 代码以及Jar包
公共方法
public class CommonUtils {
/**
* 判断是否是windows操作系统
*
* @return
*/
public static boolean isWindowsOS() {
boolean isWindowsOS = false;
String osName = System.getProperty("os.name");
if (osName.toLowerCase().indexOf("windows") > -1) {
isWindowsOS = true;
}
return isWindowsOS;
}
/**
* 判断相对路径根路径(区分./和../)
*/
static {
if (isWindowsOS()) {
systemRootPath = "./";
} else {
systemRootPath = "../";
}
}
/**
* 相对路径的根路径
*/
public static String systemRootPath;
/**
* tomcat_jdbc_pool 配置文件
*/
public static final String TOMCATJDBCPOOLPROFILEPATH = systemRootPath+"conf/tomcat_jdbc_pool.properties";
}
tomcat_jdbc_pool.properties配置文件
#数据库URL
URL=jdbc:mysql://localhost:3306/test
#数据库驱动
DRIVER=com.mysql.jdbc.Driver
#用户名
USERNAME=root
#密码
PASSWORD=123456
#初始化创建连接数
INITIALSIZE=10
#连接池最大连接数
MAXACTIVE=100
#最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被释放。设为0表示无限制
MAXIDLE=50
#最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接
MINIDLE=10
#最大建立连接等待时间
MAXWAIT=500
#超过removeAbandonedTimeout时间后,是否进行没用连接(废弃)的回收(默认为false,调整为true)
REMOVEABANDONED=true
#超过时间限制,回收没有用(废弃)的连接(默认为300秒,调整为180)
REMOVEABANDONEDTIMEOUT=180
本地logger日志,只在控制台打印,不需要配置文件
public class Local_Logger {
static {
String pattern = "%d{yyyy-MM-dd HH:mm:ss} %l - %m%n";
Logger rootLogger = Logger.getRootLogger();
rootLogger.setLevel(Level.DEBUG);
rootLogger.addAppender(new ConsoleAppender((new PatternLayout(pattern))));
}
}
常量key
public class TomcatJdbcPool_Constants {
/**
* 数据库URL
*/
public static final String URL = "URL";
/**
* 数据库驱动
*/
public static final String DRIVER = "DRIVER";
/**
* 用户名
*/
public static final String USERNAME = "USERNAME";
/**
* 密码
*/
public static final String PASSWORD = "PASSWORD";
/**
* 初始化创建连接数
*/
public static final String INITIALSIZE = "INITIALSIZE";
/**
* 连接池最大连接数
*/
public static final String MAXACTIVE = "MAXACTIVE";
/**
* 最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被释放。设为0表示无限制
*/
public static final String MAXIDLE = "MAXIDLE";
/**
* 最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接
*/
public static final String MINIDLE = "MINIDLE";
/**
* 最大建立连接等待时间
*/
public static final String MAXWAIT = "MAXWAIT";
/**
* 超过removeAbandonedTimeout时间后,是否进行没用连接(废弃)的回收(默认为false,调整为true)
*/
public static final String REMOVEABANDONED = "REMOVEABANDONED";
/**
* 超过时间限制,回收没有用(废弃)的连接(默认为300秒,调整为180)
*/
public static final String REMOVEABANDONEDTIMEOUT = "REMOVEABANDONEDTIMEOUT";
}
Tomcat JDBC Connection Pool连接池实现代码
public class T_JDBC_Pool {
public static final Logger logger = Logger.getLogger(T_JDBC_Pool.class);
private static DataSource dataSource = new DataSource();
private static String url;
private static String driver;
private static String username;
private static String password;
private static int initialSize;
private static int maxActive;
private static int maxIdle;
private static int minIdle;
private static int maxWait;
private static boolean removeAbandoned;
private static int removeAbandonedTimeout;
public static void init() {
//加载本地logger
new Local_Logger();
Properties properties = null;
try {
properties = new Properties();
properties.load(new FileInputStream(new File(CommonUtils.TOMCATJDBCPOOLPROFILEPATH)));
url = properties.getProperty(TomcatJdbcPool_Constants.URL);
driver = properties.getProperty(TomcatJdbcPool_Constants.DRIVER);
username = properties.getProperty(TomcatJdbcPool_Constants.USERNAME);
password = properties.getProperty(TomcatJdbcPool_Constants.PASSWORD);
initialSize = Integer.valueOf(properties.getProperty(TomcatJdbcPool_Constants.INITIALSIZE));
maxActive = Integer.valueOf(properties.getProperty(TomcatJdbcPool_Constants.MAXACTIVE));
maxIdle = Integer.valueOf(properties.getProperty(TomcatJdbcPool_Constants.MAXIDLE));
minIdle = Integer.valueOf(properties.getProperty(TomcatJdbcPool_Constants.MINIDLE));
maxWait = Integer.valueOf(properties.getProperty(TomcatJdbcPool_Constants.MAXWAIT));
removeAbandoned = Boolean.valueOf(properties.getProperty(TomcatJdbcPool_Constants.REMOVEABANDONED));
removeAbandonedTimeout = Integer.valueOf(properties.getProperty(TomcatJdbcPool_Constants.REMOVEABANDONEDTIMEOUT));
logger.debug("url : " + url);
logger.debug("driver : " + driver);
logger.debug("username : " + username);
logger.debug("password : " + password);
logger.debug("initialSize : " + initialSize);
logger.debug("maxActive : " + maxActive);
logger.debug("maxIdle : " + maxIdle);
logger.debug("minIdle : " + minIdle);
logger.debug("maxWait : " + maxWait);
logger.debug("removeAbandoned : " + removeAbandoned);
logger.debug("removeAbandonedTimeout : " + removeAbandonedTimeout);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
PoolProperties poolProperties = null;
try {
poolProperties = new PoolProperties();
poolProperties.setUrl(url);
poolProperties.setDriverClassName(driver);
poolProperties.setUsername(username);
poolProperties.setPassword(password);
poolProperties.setInitialSize(initialSize);
poolProperties.setMaxActive(maxActive);
poolProperties.setMaxIdle(maxIdle);
poolProperties.setMaxWait(maxWait);
poolProperties.setRemoveAbandoned(removeAbandoned);
poolProperties.setRemoveAbandonedTimeout(removeAbandonedTimeout);
dataSource.setPoolProperties(poolProperties);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
/**
* 获取连接
*
* @return
*/
public static Connection getConnection() {
Connection connection = null;
try {
connection = dataSource.getConnection();
} catch (Exception e) {
e.printStackTrace();
}
return connection;
}
}
测试调用类
public class Test_jdbc_pool {
/**
* 调用一次
*/
@Test
public void testQueryDataSource() {
String querySql = "SELECT * FROM STUDENT";
T_JDBC_Pool.init();
Connection connection = T_JDBC_Pool.getConnection();
Statement statement = null;
ResultSet resultSet = null;
try {
statement = connection.createStatement();
resultSet = statement.executeQuery(querySql);
while (resultSet.next()) {
System.out.print(resultSet.getString("studentId") + " ");
System.out.print(resultSet.getString("studentName") + " ");
System.out.print(resultSet.getString("studentAge") + " ");
System.out.println(resultSet.getString("studentPhone"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
connection.close();
statement.close();
resultSet.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 测试并发调用
* @param args
*/
public static void main(String[] args) {
Test_jdbc_pool t = new Test_jdbc_pool();
t.ConcurrentTest();
}
public void ConcurrentTest() {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
testQueryDataSource();
}
}
});
thread1.start();
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
testQueryDataSource();
}
}
});
thread2.start();
}
}
这里哦一直有个疑问
从连接池取出一个连接,用完之后,datasource没有将 连接 返还至连接池的方法....
后来去官方提供的Demo中看了下,官方Demo也仅仅是close了连接,没有将连接返还至连接池....
等有空的时候,翻翻源码...后面再补上