创建数据库连接池:
package com.mengya.JDBCUitl;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
public class DataSource {
private InputStream inStream;
private Properties pro;
private static int initCount = 10;// 初始连接数
private static int maxCount = 100;// 数据库最大连接数
static int currentConnt = 0;// 当前数据库的连接数,同包能放问
LinkedList<Connection> connectionpool = new LinkedList<Connection>();//同包能放问
DataSource() {
inStream = this.getClass().getResourceAsStream("/system.properties");
pro = new Properties();
try {
pro.load(inStream);
try {
Class.forName(pro.getProperty("driver"));
for(int i=0;i<initCount;i++){
this.connectionpool.add(this.CreateConnection());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("注册数据库驱动错误!");
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("加载配置文件出错!");
}
}
//创建数据库连接...所有创建的Connection都是自己写的那个MyConnection,而在MyConnection的Close方法我又重写了***************
private Connection CreateConnection() {
Connection conn = null;
try {
conn = DriverManager.getConnection(pro.getProperty("url"), pro
.getProperty("username"), pro.getProperty("password"));
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("创建数据库连接时失败!");
}
currentConnt++;
return new MyConnection(conn, this);
}
//得到数据库连接
public Connection getConnection() {
Connection conn = null;
synchronized (connectionpool) {
if (connectionpool.size() > 0) {
conn = this.connectionpool.removeFirst();
}
else if(currentConnt<maxCount){
conn = new MyConnection(this.CreateConnection(),this);
}
else{
throw new RuntimeException("数据库已达到最大连接数!");
}
}
return conn;
}
//释放数据库连接
public void freeConnection(Connection conn){
this.connectionpool.addLast(conn);
}
}
在上面的数据库连接池中的Connection全都是下面自己写了MyConnection,目的就是为了使别人用的时候和普通的Connection一样,关键是自己写了MyConnection的close方法不是直
接关闭了,而是放到了数据库连接池当中去了.
创建自己的Connection类:
说明:MyConnection继承了Connection接口,所在MyConnection要实现接口中的所有方法,但这个接口实现起来非常复杂,并且和数据库有关.故在Myconnection构造方法中需要一个
真正的Connection对象,该对象可以由DriverManager.getConnection(pro.getProperty("url"), pro.getProperty("username"), pro.getProperty("password"));
得到,这样在Myconnection中的方法就可以由传过来的Connectioin负责实现了.
自己写了一个MyConnection继承了Connection接口主要是为了改变它的close方法,在它的close方法时将Connection放到数据库连接池当中去,故构造方法也需要一个数据库连接池.
package com.mengya.JDBCUitl;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.Map;
public class MyConnection implements Connection {
private Connection conn;
private DataSource ds;
private int maxUseCount = 10;// 当前对象最大使用次数
private int currentUseConnt = 0;// 当前本对象使用的次数
public MyConnection(Connection conn, DataSource ds) {
this.conn = conn;
this.ds = ds;
}
public void clearWarnings() throws SQLException {
this.conn.clearWarnings();
}
//这里的close方法才是我们最感趣的方法
// close方法就是我要重写的方法
public void close() throws SQLException {
this.currentUseConnt++;//不能在始例化的时候作为使用的次数,因为始例化后就放到了数据库连结池当中去了
if(currentUseConnt<maxUseCount){
this.ds.connectionpool.addLast(this);
}else{
this.conn.close();//关闭数据库连接.也是就这个对象已经达到了最大的使用次数,释放与数据库的连结,让数据库创建一个新的.
this.ds.currentConnt--;//当前数据库连接个数
}
}
public void commit() throws SQLException {
this.conn.commit();
}
public Statement createStatement() throws SQLException {
return this.createStatement();
}
public Statement createStatement(int resultSetType, int resultSetConcurrency)
throws SQLException {
return this.createStatement(resultSetType, resultSetConcurrency);
}
...Connection接口还有很多其它的方法,这里我就不写了,所有做法都和上面的一样,由构造方法传过来的Connectoin负责处理.
}
JDBC工具类(负责得到Connection和关闭资源):
package com.mengya.JDBCUitl;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBConnectionUitl {
private static DBConnectionUitl dbconuitl;
private static DataSource ds;
private DBConnectionUitl(){
ds=new DataSource();
}
//单例模式,DBConnectionUitl只实例化一次
public static DBConnectionUitl getDBConnectionUitl(){
if(dbconuitl==null){
synchronized (DBConnectionUitl.class) {
if(dbconuitl==null){
dbconuitl=new DBConnectionUitl();
}
}
}
return dbconuitl;
}
//得到Connection。(其实是我们自己实现了的MyConnection而不是DriverManager产生的Connection)
public Connection getConnection(){
return ds.getConnection();
}
public void free(ResultSet rs,Statement sta,Connection con){
try {
if(rs!=null){
rs.close();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
if(sta!=null){
sta.close();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(con!=null){
try {
con.close();//在这里就可以真接关掉,但它并不是正真的闭了,而在放到了数据库连接池当中去了。
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
}