数据库连接池是什么
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
数据库连接是一种关键的、有限的、昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。
影响因素:
- 最小连接数
是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费。 - 最大连接数
是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,这会影响之后的数据库操作。 - 最小连接数与最大连接数差距
最小连接数与最大连接数相差太大,那么最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。
导入jar包
要使用DBCP或者C3P0我们就需要导入相应的jar包
DBCPjar包地址:
http://commons.apache.org/proper/commons-dbcp/download_dbcp.cgi
https://commons.apache.org/proper/commons-pool/download_pool.cgi
C3P0jar包地址
https://sourceforge.net/projects/c3p0/
编写规范
不使用数据库连接池的JDBC
编写配置文件jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456
编写工具类jdbcUtil
public class jdbcUtil {
static String driver=null;
static String url=null;
static String username=null;
static String password=null;
static {
InputStream resourceAsStream = jdbcUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties properties = new Properties();
try {
properties.load(resourceAsStream);
driver=properties.getProperty("driver");
url=properties.getProperty("url");
username=properties.getProperty("username");
password=properties.getProperty("password");
Class.forName(driver);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
public static void release(Connection con, Statement st, ResultSet rs) throws SQLException {
if(rs!=null){
rs.close();
}
if(st!=null){
st.close();
}
if(con!=null){
con.close();
}
}
}
实际使用(编写一个删除数据的类sqlDelete)
public class sqlDelete {
public static void main(String[] args) throws SQLException {
delete("wangwu");
}
public static void delete(String username) throws SQLException {
Connection con=jdbcUtil.getConnection();
String sql="delete from `users` where `NAME`=?";
PreparedStatement st = con.prepareStatement(sql);
st.setString(1,username);
int i = st.executeUpdate();
if(i>0){
System.out.println("删除成功");
}
jdbcUtil.release(con,st,null);
}
}
使用DBCP
编写配置文件DBCPconfig.properties
#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456
#<!-- 初始化连接 -->
initialSize=10
#最大连接数量
maxActive=50
#<!-- 最大空闲连接 -->
maxIdle=20
#<!-- 最小空闲连接 -->
minIdle=5
#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000
#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=utf8
#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true
#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED
编写工具类jdbcUtil_dbcp
public class jdbcUtil_dbcp {
private static DataSource dataSource=null;
static {
try {
InputStream in = jdbcUtil_dbcp.class.getClassLoader().getResourceAsStream("DBCPconfig.properties");
Properties properties = new Properties();
properties.load(in);
dataSource = BasicDataSourceFactory.createDataSource(properties);
}catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getconnection() throws SQLException {
return dataSource.getConnection();
}
public static void release(Connection con, Statement st, ResultSet rs) throws SQLException {
if(rs!=null){
rs.close();
}
if(st!=null){
st.close();
}
if(con!=null){
con.close();
}
}
}
实际使用(创建一个用于插入数据的类DBCPTest)
public class DBCPTest {
public static void main(String[] args) throws SQLException {
insert("lihua", "123456");
}
public static void insert(String username, String password) throws SQLException {
Connection con = null;
PreparedStatement st = null;
try {
con = jdbcUtil_dbcp.getconnection();
String sql = "insert into `users` values (?,?,?,?,?)";
st = con.prepareStatement(sql);
st.setInt(1, 6);
st.setString(2, username);
st.setString(3, password);
st.setString(4, "12412441241@qq.com");
st.setDate(5, new java.sql.Date(new Date().getTime()));
int i = st.executeUpdate();
if (i > 0) {
System.out.println("插入成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
jdbcUtil_dbcp.release(con, st, null);
}
}
}
使用C3P0
编写配置文件c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!--默认配置-->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&uesSSL=true&serverTimezone=UTC/property
</property>
<property name="user">root</property>
<property name="password">123456</property>
<!-- 初始化连接池数量 -->
<property name="initialPoolSize">10</property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize">20</property>
<!--连接池中保留的 最小连接数 -->
<property name="minPoolSize">5</property>
<property name="acquireIncrement">5</property>
</default-config>
<!--根据不同数据库的自定义不同配置,在后面使用时根据传入的参数决定使用哪个配置-->
<named-config name="MySQL">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&uesSSL=false
</property>
<property name="user">root</property>
<property name="password">123456</property>
<!-- 初始化连接池数量 -->
<property name="initialPoolSize">10</property>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize">20</property>
<!--连接池中保留的 最小连接数 -->
<property name="minPoolSize">5</property>
<property name="acquireIncrement">5</property>
</named-config>
</c3p0-config>
C3P0配置具体含义参考https://blog.csdn.net/caychen/article/details/79625411
编写工具类jdbcUtil_c3p0
public class jdbcUtil_c3p0 {
private static ComboPooledDataSource C3P0_mysql=null;
static {
try {
//xml配置文件无需读取并载入properties类,直接就可以创建ComboPooledDataSource类
C3P0_mysql = new ComboPooledDataSource("MySQL");//根据传入的参数名,决定使用哪个配置
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getconnection() throws SQLException {
return C3P0_mysql.getConnection();
}
public static void release(Connection con, Statement st, ResultSet rs) throws SQLException {
if(rs!=null){
rs.close();
}
if(st!=null){
st.close();
}
if(con!=null){
con.close();
}
}
}
实际使用(还是编写一个用于插入数据的c3p0Test类)
public class c3p0Test {
public static void main(String[] args) throws SQLException {
insert("lihua", "1323425");
}
public static void insert(String username, String password) throws SQLException {
Connection con = null;
PreparedStatement st = null;
try {
con = jdbcUtil_c3p0.getconnection();
String sql = "insert into `users` values (?,?,?,?,?)";
st = con.prepareStatement(sql);
st.setInt(1, 8);
st.setString(2, username);
st.setString(3, password);
st.setString(4, "12412441241@qq.com");
st.setDate(5, new java.sql.Date(new Date().getTime()));
int i = st.executeUpdate();
if (i > 0) {
System.out.println("插入成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
jdbcUtil_c3p0.release(con, st, null);
}
}
}