用裝飾模式實現
批量創建與數據庫的連接,並把創建的連接加入List< Connection> pool對象中。
讓getConnection方法每次調用時,從pool中取一個Connection返回給用戶。
當用戶使用完Connection,調用Connection.close()方法時,Collection對象應保證將自己返回到pool中,而不要把conn還給數據庫。
所以Collection保證將自己返回到pool中是此處編程的難點。
package cn.hncu.pool;
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.DriverManager;
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 ConnUtils2 {
private final static List<Connection> pool=new ArrayList<Connection>();
private final static int num=3;
private ConnUtils2(){
}
static{
Properties p=new Properties();
try {
// p.load(ConnUtils.class.getClassLoader().getResourceAsStream("jdbc.properties"));
p.load(ClassLoader.getSystemResourceAsStream("jdbc.properties"));
String driver=p.getProperty("driver");
String url=p.getProperty("url");
String name=p.getProperty("username");
String pwd=p.getProperty("password");
Class.forName(driver);
for(int i=0;i<num;i++){
Connection con=DriverManager.getConnection(url, name, pwd);
//更改conn.close()方法
myConnection conn = new myConnection(con);
pool.add(conn);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//採用包裝模式(裝飾模式) 對Connection conn的功能進行增強
//因爲要訪問ConnUtils2類中的靜態變量pool,因此要聲明成靜態內部類
public static synchronized Connection getConnection(){
if(pool.size()<=0){
System.out.println("池中連接沒有了...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return getConnection();
}
return pool.remove(0);//拿一個移一個
}
public static class myConnection implements Connection{
private Connection con;
public myConnection(Connection con) {
this.con=con;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return con.unwrap(iface);
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return con.isWrapperFor(iface);
}
@Override
public Statement createStatement() throws SQLException {
return con.createStatement();
}
@Override
public PreparedStatement prepareStatement(String sql)
throws SQLException {
return con.prepareStatement(sql);
}
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
return con.prepareCall(sql);
}
@Override
public String nativeSQL(String sql) throws SQLException {
return con.nativeSQL(sql);
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
con.setAutoCommit(autoCommit);
}
@Override
public boolean getAutoCommit() throws SQLException {
return con.getAutoCommit();
}
@Override
public void commit() throws SQLException {
con.commit();
}
@Override
public void rollback() throws SQLException {
con.rollback();
}
@Override
public void close() throws SQLException {
pool.add(this);
}
@Override
public boolean isClosed() throws SQLException {
return con.isClosed();
}
@Override
public DatabaseMetaData getMetaData() throws SQLException {
return con.getMetaData();
}
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
con.setReadOnly(readOnly);
}
@Override
public boolean isReadOnly() throws SQLException {
return con.isReadOnly();
}
@Override
public void setCatalog(String catalog) throws SQLException {
con.setCatalog(catalog);
}
@Override
public String getCatalog() throws SQLException {
return con.getCatalog();
}
@Override
public void setTransactionIsolation(int level) throws SQLException {
con.setTransactionIsolation(level);
}
@Override
public int getTransactionIsolation() throws SQLException {
return con.getTransactionIsolation();
}
@Override
public SQLWarning getWarnings() throws SQLException {
return con.getWarnings();
}
@Override
public void clearWarnings() throws SQLException {
con.clearWarnings();
}
@Override
public Statement createStatement(int resultSetType,
int resultSetConcurrency) throws SQLException {
return con.createStatement(resultSetType, resultSetConcurrency);
}
@Override
public PreparedStatement prepareStatement(String sql,
int resultSetType, int resultSetConcurrency)
throws SQLException {
return con.prepareStatement(sql, resultSetType, resultSetConcurrency);
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency) throws SQLException {
return con.prepareCall(sql, resultSetType, resultSetConcurrency);
}
@Override
public Map<String, Class<?>> getTypeMap() throws SQLException {
return con.getTypeMap();
}
@Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
con.setTypeMap(map);
}
@Override
public void setHoldability(int holdability) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public int getHoldability() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
@Override
public Savepoint setSavepoint() throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public Savepoint setSavepoint(String name) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public void rollback(Savepoint savepoint) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public Statement createStatement(int resultSetType,
int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public PreparedStatement prepareStatement(String sql,
int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public PreparedStatement prepareStatement(String sql,
int autoGeneratedKeys) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public PreparedStatement prepareStatement(String sql,
int[] columnIndexes) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public PreparedStatement prepareStatement(String sql,
String[] columnNames) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public Clob createClob() throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public Blob createBlob() throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public NClob createNClob() throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public SQLXML createSQLXML() throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isValid(int timeout) throws SQLException {
// TODO Auto-generated method stub
return false;
}
@Override
public void setClientInfo(String name, String value)
throws SQLClientInfoException {
// TODO Auto-generated method stub
}
@Override
public void setClientInfo(Properties properties)
throws SQLClientInfoException {
// TODO Auto-generated method stub
}
@Override
public String getClientInfo(String name) throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public Properties getClientInfo() throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public Array createArrayOf(String typeName, Object[] elements)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public Struct createStruct(String typeName, Object[] attributes)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public void setSchema(String schema) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public String getSchema() throws SQLException {
// TODO Auto-generated method stub
return null;
}
@Override
public void abort(Executor executor) throws SQLException {
// TODO Auto-generated method stub
}
@Override
public void setNetworkTimeout(Executor executor, int milliseconds)
throws SQLException {
con.setNetworkTimeout(executor, milliseconds);
}
@Override
public int getNetworkTimeout() throws SQLException {
return con.getNetworkTimeout();
}
}
}
jdbc.properties
##MySQL
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8
username=root
password=1234
size=3
##Oracle
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
#username=scott
#password=tiger
演示
package cn.hncu.tx;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import cn.hncu.pool.ConnUtils2;
//使用的是多例的連接池ConnUtils
public class TxDemo3 {
public static void main(String[] args) throws Exception {
Connection con=ConnUtils2.getConnection();
System.out.println("main線程獲得一個連接:"+con);
Statement st = con.createStatement();
try {
con.setAutoCommit(false);
st.execute("INSERT INTO person VALUES('P200','趙子龍','1')");
new MyThread3(1).start();
new MyThread3(2).start();
new MyThread3(3).start();
new MyThread3(4).start();
new MyThread3(5).start();
Thread.sleep(1000);
con.commit();
System.out.println("main線程提交一個事務....");
} catch (Exception e) {
con.rollback();
System.out.println("main線程回滾一個事務.....");
}finally{
con.setAutoCommit(true);
con.close();
}
}
}
class MyThread3 extends Thread{
private int num;
public MyThread3(int num){
this.num = num;
}
@Override
public void run() {
Connection con=ConnUtils2.getConnection();
System.out.println(num+"線程獲得一個連接:"+con);
try {
Statement st = con.createStatement();
con.setAutoCommit(false);
String sql = "INSERT INTO person VALUES('P09"+num+"','趙子龍','1')";
if(num==3){
sql = "INSERT INTO person VALUES('P09"+num+"'趙子龍','1')";
}else{
Thread.sleep(100);
}
st.executeUpdate(sql);
con.commit();
System.out.println(num+"線程提交一個事務....");
} catch (Exception e) {
try {
con.rollback();
System.out.println(num+"線程回滾一個事務.....");
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally{
try {
con.setAutoCommit(true);
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}