一、为什么我们要用连接池技术?
前面的数据库连接的建立及关闭资源的方法有些缺陷。统舱传统数据库访问方式:一次数据库访问对应一个物理连接,每次操作数据库都要打开、关闭该物理连接, 系统性能严重受损。
解决方案:数据库连接池(Connection Pool)。
系统初始运行时,主动建立足够的连接,组成一个池.每次应用应用程序请求数据库连接时,无需重新打开连接,而是从池中取出已有的连接,使用完后,不再关闭,而是归还。
二、连接池的实现
新建一个java工程并导入相应的包,新建db.properties文件:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/jsonke jdbc.user=root jdbc.password=123456 initsize=1 maxactive=99 maxwait=5000 maxidle=99 minidle=1
db.properties的基本配置的介绍
1.initialSize :连接池启动时创建的初始化连接数量(默认值为0)
2.maxActive :连接池中可同时连接的最大的连接数(默认值为8,调整为20,高峰单机器在20并发左右,自己根据应用场景定)
3.maxIdle:连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制(默认为8个,maxIdle不能设置太小,因为假如在高负载的情况下,连接的打开时间比关闭的时间快,会引起连接池中idle的个数 上升超过maxIdle,而造成频繁的连接销毁和创建,类似于jvm参数中的Xmx设置)
4.minIdle:连接池中最小的空闲的连接数,低于这个数量会被创建新的连接(默认为0,调整为5,该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大,因为在机器很空闲的时候,也会创建低于minidle个数的连接,类似于jvm参数中的Xmn设置)
5.maxWait :最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待(默认为无限,调整为60000ms,避免因线程池不够用,而导致请求被无限制挂起
JDBC实例化代码如下:
package com.jdbc;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import org.apache.commons.dbcp.BasicDataSource;
/**
* 使用连接池技术管理数据库连接
*/
public class DBUtil {
//数据库连接池
private static BasicDataSource dbcp;
//为不同线程管理连接
private static ThreadLocal<Connection> tl;
//通过配置文件来获取数据库参数
static{
try{
Properties prop
= new Properties();
InputStream is
= DBUtil.class.getClassLoader()
.getResourceAsStream(
"com/jdbc/db.properties");
prop.load(is);
is.close();
//一、初始化连接池
dbcp = new BasicDataSource();
//设置驱动 (Class.forName())
dbcp.setDriverClassName(prop.getProperty("jdbc.driver"));
//设置url
dbcp.setUrl(prop.getProperty("jdbc.url"));
//设置数据库用户名
dbcp.setUsername(prop.getProperty("jdbc.user"));
//设置数据库密码
dbcp.setPassword(prop.getProperty("jdbc.password"));
//初始连接数量
dbcp.setInitialSize(
Integer.parseInt(
prop.getProperty("initsize")
)
);
//连接池允许的最大连接数
dbcp.setMaxActive(
Integer.parseInt(
prop.getProperty("maxactive")
)
);
//设置最大等待时间
dbcp.setMaxWait(
Integer.parseInt(
prop.getProperty("maxwait")
)
);
//设置最小空闲数
dbcp.setMinIdle(
Integer.parseInt(
prop.getProperty("minidle")
)
);
//设置最大空闲数
dbcp.setMaxIdle(
Integer.parseInt(
prop.getProperty("maxidle")
)
);
//初始化线程本地
tl = new ThreadLocal<Connection>();
}catch(Exception e){
e.printStackTrace();
}
}
/**
* 获取数据库连接
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
//通过连接池获取一个空闲连接
Connection conn = dbcp.getConnection();
tl.set(conn);
return conn;
}
//关闭数据库连接
public static void closeConnection(){
try{
Connection conn = tl.get();
if(conn != null){
//通过连接池获取的Connection
//的close()方法实际上并没有将
//连接关闭,而是将该链接归还。
conn.close();
tl.remove();
}
}catch(Exception e){
e.printStackTrace();
}
}
//测试是否连接成功
//@param args
//@throws SQLException
public static void main(String[] args) throws SQLException {
System.out.println(getConnection());
}
}
0 条评论。