Java之數據庫連接池
數據庫連接池
首先,我們使用JDBC操作數據庫的時候一般都會經歷下面幾個流程
獲取數據庫連接對象 ==> 執行SQL ==> 釋放資源
從執行SQL到釋放資源是很浪費系統資源的一個事情,所以引出了數據庫連接池這麼一個技術。
池化技術就是準備一些預先的資源,當有需要執行SQL時,就先使用這些預先準備的資源
編寫連接池:主要實現DataSource接口即可。
開源的數據庫連接池有
DBCP
C3P0
Druid: alibaba
DBCP
與之前不同的是這裏需要新建一個數據庫連接池,通過數據庫連接池get connection對象再封裝到工具類中供主函數進行調用。
像資源釋放方法還是像之前的寫法即可。
private static DataSource dataSource = null;
static {
try {
//讀取資源文件
InputStream resourceAsStream = DbcpUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties properties = new Properties();
properties.load(resourceAsStream);
//創建數據源
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//獲取連接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
dbcpconfig.properties
#連接設置 數據源名字是jar包中設置好的,不可更改
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=password
#!-- 初始化連接 --
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 指定由連接池所創建的連接的只讀(read-only)狀態。
#如果沒有設置該值,則“setReadOnly”方法將不被調用。(某些驅動並不支持只讀模式,如:Informix)
defaultReadOnly=
#driver default 指定由連接池所創建的連接的事務級別(TransactionIsolation)。
#可用值爲下列之一:(詳情可見javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED
DbcpUtils
public class DbcpUtils {
private static DataSource dataSource = null;
static {
try {
//讀取資源文件
InputStream resourceAsStream = DbcpUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties properties = new Properties();
properties.load(resourceAsStream);
//創建數據源
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//獲取連接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
//釋放資源
public static boolean closeResources(Connection connection, Statement statement, ResultSet resultSet, PreparedStatement preparedStatement){
boolean flag = true;
if (connection!=null){
try {
connection.close();
flag = true;
} catch (SQLException throwables) {
throwables.printStackTrace();
flag = false;
}
}
if (statement!=null){
try {
statement.close();
flag = true;
} catch (SQLException throwables) {
throwables.printStackTrace();
flag = false;
}
}
if (resultSet!=null){
try {
resultSet.close();
flag = true;
} catch (SQLException throwables) {
throwables.printStackTrace();
flag = false;
}
}
if (preparedStatement!=null){
try {
preparedStatement.close();
flag = true;
} catch (SQLException throwables) {
throwables.printStackTrace();
flag = false;
}
}
return flag;
}
}
TestDbcp
public class TestDBCP {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = DbcpUtils.getConnection();
//查詢一條數據
String sqlQ = "SELECT * FROM people where id =?";
preparedStatement = connection.prepareStatement(sqlQ);
preparedStatement.setInt(1,3);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
System.out.println("id = " + resultSet.getInt("id"));
System.out.println("name = " + resultSet.getString("name"));
System.out.println("age = " + resultSet.getInt("age"));
System.out.println("address = " + resultSet.getString("address"));
System.out.println("============================");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 釋放資源
boolean flag = JdbcUtils.closeResources(connection, preparedStatement, resultSet, null);
if (flag){
System.out.println("資源釋放完成!");
}else {
System.out.println("資源釋放失敗!");
}
}
}
}
C3P0
c3p0的配置文件可以配置多個數據庫的配置。在代碼中可以指定參數來制定數據源,不寫參數缺省爲默認的數據源配置。
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource(); //這裏爲缺省數據源配置
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("MySQL"); //選擇MySQL爲數據源配置
C3p0config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<c3p0-config>
<!--
c3p0的缺省(默認)配置
如果在代碼中ComboPooledDataSource ds=new ComboPooledDataSource();這樣寫就表示使用的是c3p0的缺省(默認)-->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&uesSSL=false</property>
<property name="user">root</property>
<property name="password">password</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
<mysql-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&uesSSL=false</property>
<property name="user">root</property>
<property name="password">password</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</mysql-config>
</c3p0-config>
其餘部分可參照DBCP