1.连接池的作用
连接池一般比直接连接更有优越性,因为它提高了性能的同时还保存了宝贵的资源。在整个应用程序的使用过程,当中重复的打开直接连接将导致性能的下降。而池连接只在服务器启动时打开一次,从而消除了这种性能问题。
连接池主要考虑的是性能,每次获取连接和释放连接都有很大的工作量,会对性能有很大影响;而对资源来说起的是反作用,因为保存一定数量的连接是要消耗内存的。应用程序每次从池里获得Connection对象,而不是直接从数据里获得,这样不占用服务器的内存资源。所以一般要建立连接池,而连接的数量要适当,不能太大,太大会过多消耗资源。(所以,考虑2个方面,一个是内存,另一个是资源)。 连接池就是为了避免重复多次的打开数据库连接而造成的性能的下降和系统资源的浪费。
目前Java中使用连接池的三种方式:
a.自定义连接池
b.使用第三方连接池
c.使用服务器自带的连接池
在自定义连接池的使用上,上网查看了不少案例,自己总结了一下,不多说直接上代码。
2.pom文件
<dependencies>
<!--mysql的jdbc驱动jar包依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--lombok代码生成工具的jar包依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
3.jdbc.properties
jdbc.driverName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.234.131:3306/bas_db
jdbc.username=root
jdbc.password=@WSX1qaz
jdbc.poolName=jdbcThread
jdbc.minConnections=5
jdbc.maxConnections=10
jdbc.initConnections=2
jdbc.connTimeOut=1000
4.DbBean
import lombok.Data;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
@Data
public class DbBean {
private String driverName;
private String url;
private String userName ;
private String password ;
private String poolName ;// 连接池名字
private int minConnections; // 空闲池,最小连接数
private int maxConnections ; // 空闲池,最大连接数
private int initConnections ;// 初始化连接数
private long connTimeOut;// 重复获得连接的频率
{
readConfig();
}
private void readConfig() {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("jdbc.properties");
Properties prop = new Properties();
if (null != inputStream){
try {
prop.load(inputStream);
this.driverName = prop.getProperty("jdbc.driverName");
this.url = prop.getProperty("jdbc.url");
this.userName = prop.getProperty("jdbc.username");
this.password = prop.getProperty("jdbc.password");
this.poolName = prop.getProperty("jdbc.poolName");
this.minConnections = Integer.parseInt(prop.getProperty("jdbc.minConnections"));
this.maxConnections = Integer.parseInt(prop.getProperty("jdbc.maxConnections"));
this.initConnections = Integer.parseInt(prop.getProperty("jdbc.initConnections"));
this.connTimeOut = Long.parseLong(prop.getProperty("jdbc.connTimeOut"));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5.创建连接池
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 连接池
*/
public class ConnectionPoolManager {
//空闲线程
private List<Connection> freeConnection = new Vector<Connection>();
//活跃线程
private List<Connection> activeConnection = new Vector<Connection>();
//连接数
private AtomicInteger connCount = new AtomicInteger();
//DbBean
private DbBean dbBean = new DbBean();
public ConnectionPoolManager() {
this.init();
}
/**
* 初始化
*/
private void init() {
for (int i = 0; i <= dbBean.getInitConnections(); i++) {
Connection conn = this.CreateConnection();
if (null != conn) {
freeConnection.add(conn);
}
}
}
/**
* 创建连接
*
* @return
*/
private Connection CreateConnection() {
try {
if (null == dbBean) {
return null;
}
Class.forName(dbBean.getDriverName());
Connection conn = DriverManager.getConnection(dbBean.getUrl(), dbBean.getUserName(), dbBean.getPassword());
connCount.decrementAndGet();
return conn;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取连接
*
* @return
*/
public synchronized Connection getConnection() {
Connection conn = null;
try {
//判断活跃线程是否大于等于最大连接数,大于等于则等待,
if (activeConnection.size() >= dbBean.getMaxConnections()) {
//大于等于,则等待
wait(dbBean.getConnTimeOut());
this.getConnection();
} else {
//小于
//判断空闲线程数是否大于0,大于则直接从空闲线程中取
if (freeConnection.size() > 0) {
//大于
conn = freeConnection.remove(0);
} else {
//小于,则创建连接
conn = this.CreateConnection();
}
//判断连接是否有效
if (isAvailable(conn)) {
//有效,放入活跃线程中
activeConnection.add(conn);
} else {
conn = this.getConnection();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
/**
* 释放连接
*/
public synchronized void releaseConnection(Connection conn) {
if (!isAvailable(conn)) {
return;
}
//判断空闲线程是否大于最小连接数,大于则关闭连接
if (freeConnection.size() > dbBean.getMinConnections()) {
//大于,直接关闭
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
} else {
//小于,空闲线程加1
freeConnection.add(conn);
this.connCount.decrementAndGet();
}
}
/**
* 判断连接是否有效
*
* @param conn
* @return
*/
public boolean isAvailable(Connection conn) {
try {
if (null == conn || conn.isClosed()) {
return false;
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
}
6.测试
import java.sql.Connection;
import java.sql.PreparedStatement;
public class test {
public static void main(String[] args) {
final ConnectionPo