在使用JDBC時我們可以自己去創建一個工具類(JDBCUtils),每次來調用它的方法來獲取連接或者來釋放連接,具體該類的實現如下:
package JDBCUtils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;
//獲取連接和釋放資源的方法
public class JDBCUtils {
private static String driver;
private static String url;
private static String username;
private static String password;
//靜態代碼塊
static {
//讀取配置文件
ResourceBundle bundle=ResourceBundle.getBundle("db");
//獲取文件中的數據
driver=bundle.getString("driver");
url=bundle.getString("url");
username=bundle.getString("username");
password=bundle.getString("password");
}
//獲取連接
public static Connection getConnection() {
Connection conn = null;
try {
Class.forName(driver);
conn=DriverManager.getConnection(url, username, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
//釋放資源
public static void release(Connection conn,PreparedStatement pstmt,ResultSet rs){
if(rs!=null)
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
if(pstmt!=null)
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
if(conn!=null)
try {
rs.close();
} catch (SQLException e){
e.printStackTrace();
}
}
}
在這裏我們使用配置文件來存儲鏈接數據庫所需要的信息,配置文件名爲db.properties
這個類中有兩個方法,一是來獲取數據庫的連接,二是來釋放資源
但是,如果反覆的創建資源釋放資源,這會造成很大的浪費,所以,我們可以使用jdbc連接池來存放,在連接池中我們可以存放多個已經事先創建好的連接,每次使用時只需要取出來,使用完後再放回去,這樣做提高了效率。
package DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.logging.Logger;
import javax.sql.DataSource;
import JDBCUtils.JDBCUtils;
public class MyDataSource implements DataSource{
//創建集合用來存儲conn
private static ArrayList<Connection> pool=new ArrayList<>();
//使用靜態代碼塊創建5個連接放到連接池中
static {
Connection conn=null;
for(int i=0;i<5;i++) {
conn=JDBCUtils.getConnection();
pool.add(conn);
}
}
//寫返回類
@Override
public Connection getConnection() throws SQLException {
Connection conn=null;
//判斷是否爲空
if(pool==null) {
for(int i=0;i<5;i++) {
conn=JDBCUtils.getConnection();
pool.add(conn);
}
}
//刪除第一個
conn=pool.remove(0);
return conn;
}
//寫回收方法
public void backConnection(Connection conn){
pool.add(conn);
}
//!!!!.....此處省略了很多需要寫上的類
}
創建連接池的大概思路就是,我們先創建一個集合(池),然後通過靜態代碼塊創建多個(上段代碼創建了5個)連接,然後將他們全部放到集合中,如果每次要獲得連接,直接從集合中取出一個,使用完後再調用這個類中的返回方法將連接歸還
這是測試類:
public class TestMyDataSource {
@Test
public void Test() {
Connection conn=null;
PreparedStatement pstmt=null;
MyDataSource datasource=new MyDataSource();
try {
//獲取連接
conn=datasource.getConnection();
String sql="insert into t_user values(null,?,?)";
pstmt=conn.prepareStatement(sql);
pstmt.setString(1,"aaa");
pstmt.setString(2,"666");
int x=pstmt.executeUpdate();
if(x>0) {
System.out.println("操作成功");
}else {
System.out.println("操作失敗");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
datasource.backConnection(conn);
}
}
}
通過測試,成功的將數據填入數據庫中。
這是一種使用連接池的方法,如果我們要在最後依然習慣性的調用JDBCUtils中的方法release方法,但是這樣就會釋放連接,我們想讓他中的close方法不是釋放而是歸還,那麼我們就需要重寫這個方法,首先創建一個Connection類
package DataSource;
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
public class MyConnection implements Connection{
private Connection conn;
private ArrayList<Connection> pool;
public MyConnection(Connection conn,ArrayList<Connection> pool){
this.conn=conn;
this.pool=pool;
}
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
return conn.prepareStatement(sql);
}
@Override
public void close() throws SQLException {
pool.add(conn);
}
//!!!、、、、、此處省略了許多必須存在的方法
}
這裏我們牀架一個類,實際這個類就是對conn連接的一個封裝,我們再寫一個創建連接池的類,和上一個差不多
package DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.ArrayList;
import java.util.logging.Logger;
import javax.sql.DataSource;
import JDBCUtils.JDBCUtils;
public class MyDataSource1 implements DataSource{
//創建集合用來存儲conn
private static ArrayList<Connection> pool=new ArrayList<>();
//使用靜態代碼塊創建5個連接放到連接池中
static {
Connection conn=null;
for(int i=0;i<5;i++) {
conn=JDBCUtils.getConnection();
MyConnection myconn=new MyConnection(conn, pool);
pool.add(myconn);
}
}
//寫返回類
@Override
public Connection getConnection() throws SQLException {
Connection conn=null;
//判斷是否爲空
if(pool==null) {
for(int i=0;i<5;i++) {
conn=JDBCUtils.getConnection();
MyConnection myconn=new MyConnection(conn, pool);
pool.add(myconn);
}
}
//刪除第一個
conn=pool.remove(0);
return conn;
}
//此處省略多個必須存在方法
}
實際我們可以看到我們現在通過這個方法所得到的conn連接實際不是Connection瞭解,而是他的子類MyConnection,是一個封裝對象,我們再得到它後,就對它進行使用
@Test
public void Test1() {
Connection myconn=null;
PreparedStatement pstmt=null;
MyDataSource1 datasource1=new MyDataSource1();
try {
//獲取連接
myconn=datasource1.getConnection();
String sql="insert into t_user values(null,?,?)";
pstmt=myconn.prepareStatement(sql);
pstmt.setString(1,"wae1");
pstmt.setString(2,"6661");
int x=pstmt.executeUpdate();
if(x>0) {
System.out.println("操作成功");
}else {
System.out.println("操作失敗");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.release(myconn, pstmt, null);
}
}
通過測試,成功的添加了信息到數據庫中,起始在全部過程中,我們所操作的只是Connection的封裝類,並沒有操作實際的Connec,最後調用JDBCUtils中的release方法,它中有close方法,再調用MyConnection中的close將連接放回連接池中。