自定义框架TFrameWork之自定义jdbc连接池
最近一直想自己封装下jdbc,写个orm,在此拿出来分享分享我的代码,让高人指点指点,共同进步,也做个备份
先上代码
DataSource.java
packageorg.tension.framework.common.das;
importjava.io.InputStream;
importjava.util.Iterator;
importorg.dom4j.Document;
importorg.dom4j.Element;
importorg.dom4j.io.SAXReader;
/**
*数据源
*@authortension
*
*/
publicclassDataSource{
protectedstaticStringdriverClassName;
protectedstaticStringurl;
protectedstaticStringuser;
protectedstaticStringpassword;
protectedstaticintpoolSize;
protectedstaticintmaxUseCount;
protectedstaticintmaxPoolSize;
protectedstaticintminPoolSize;
protectedstaticStringtransaction_Isolation;
static{
try{
InputStreamips=DataSource.class.getClassLoader().getResourceAsStream("user-config.xml");
SAXReaderreader=newSAXReader();
Documentdoc=null;
doc=reader.read(ips);
Elementroot=doc.getRootElement();
Elementmodule=root.element("module");
Elementgroup=module.element("group");
Iterator<?>configValue=group.elementIterator("configValue");
while(configValue.hasNext()){
Elemente=(Element)configValue.next();
Stringkey=e.attributeValue("key");
Stringvalue=e.getText();
if("DriverClass".equalsIgnoreCase(key)){
driverClassName=value;
}elseif("Url".equalsIgnoreCase(key)){
url=value;
}elseif("UserName".equalsIgnoreCase(key)){
user=value;
}elseif("Password".equalsIgnoreCase(key)){
password=value;
}elseif("PoolSize".equalsIgnoreCase(key)){
poolSize=Integer.valueOf(value);
}elseif("MaxUseCount".equalsIgnoreCase(key)){
maxUseCount=Integer.valueOf(value);
}elseif("MaxPoolSize".equalsIgnoreCase(key)){
maxPoolSize=Integer.valueOf(value);
}elseif("MinPoolSize".equalsIgnoreCase(key)){
minPoolSize=Integer.valueOf(value);
}elseif("Transaction-Isolation".equalsIgnoreCase(key)){
transaction_Isolation=value;
}
}
Class.forName(driverClassName);
}catch(Exceptione){
thrownewExceptionInInitializerError(e);
}
}
}
至于为什么没有去实现DataSource接口,我觉得我暂时不用它,所有没有去实现
ConnectionPool.java
packageorg.tension.framework.common.das;
importjava.sql.Connection;
importjava.sql.DriverManager;
importjava.sql.SQLException;
importjava.util.LinkedList;
/**
*
*2012-9-12
*
*@author<ahref="mailto:[email protected]">tension</a>
*
*/
publicclassConnectionPoolextendsDataSource{
/**当前连接数*/
intcurrentCount=0;
LinkedList<Connection>connectionsPool=newLinkedList<Connection>();
/**
*默认构造方法,一次性获得poolSize个连接放进connectionsPool连接池中
*/
publicConnectionPool(){
CreateConnectionPool(poolSize);
}
/**
*获取连接记录当前连接个数
*如果连接池还有连接则直接从连接池取连接,如果连接大于最大连接数
*@return
*@throwsSQLException
*/
publicConnectiongetConnection()throwsSQLException{
synchronized(connectionsPool){
if(this.connectionsPool.size()>0){
this.currentCount++;
returnthis.connectionsPool.removeFirst();
}
if(this.currentCount<maxPoolSize){
intbuffer=this.currentCount+minPoolSize;
if(buffer<maxPoolSize||buffer==maxPoolSize){
this.currentCount++;
CreateConnectionPool(minPoolSize);
}else{
this.currentCount++;
CreateConnectionPool(buffer-maxPoolSize);
}
returnthis.connectionsPool.removeFirst();
}
thrownewSQLException("暂无连接可用");
}
}
/**
*创建连接放入连接池中,缓冲连接池
*@paramcount个数
*/
publicvoidCreateConnectionPool(intcount){
try{
for(inti=0;i<count;i++){
this.connectionsPool.addLast(this.createConnection());
this.currentCount++;
}
}catch(SQLExceptione){
thrownewExceptionInInitializerError(e);
}
}
/**
*释放连接方法
*把用完的连接重新放回连接池中
*@paramconn
*/
publicvoidfree(Connectionconn){
this.connectionsPool.addLast(conn);
}
/**
*创建连接
*@returnwarpedConnection
*@throwsSQLException
*@authortension
*/
privateConnectioncreateConnection()throwsSQLException{
ConnectionrealConn=DriverManager.getConnection(url,user,password);
ConnectionHandlerproxy=newConnectionHandler(this);
returnproxy.bind(realConn);
}
}
这个就是所谓的连接池了,简单,没有现在主流的那么NB,供学习
ConnectionHandler
packageorg.tension.framework.common.das;
importjava.lang.reflect.InvocationHandler;
importjava.lang.reflect.Method;
importjava.lang.reflect.Proxy;
importjava.sql.Connection;
/**
*连接池的代理类
*用于处理Connection的colse方法,把连接放回连接池
*@authortension
*2012-09-12
*/
classConnectionHandlerextendsDataSourceimplementsInvocationHandler{
/**真正的连接对象*/
privateConnectionrealConnection;
/**代理的连接对象*/
privateConnectionwarpedConnection;
/**连接池*/
privateConnectionPoolconn;
/**当前用户使用的次数*/
privateintcurrentUserCount=0;
/**
*默认构造方法
*@paramconn连接池
*/
ConnectionHandler(ConnectionPoolconn){
this.conn=conn;
}
/**
*java.sql.Connection的代理方法
*@paramrealConnwarpedConnection代理后的对象
*@return
*/
Connectionbind(ConnectionrealConn){
this.realConnection=realConn;
this.warpedConnection=(Connection)Proxy.newProxyInstance(this
.getClass().getClassLoader(),newClass[]{Connection.class},
this);
returnwarpedConnection;
}
/**
*方法拦截
*如果为close方法的话不直接调用真正Connection的close方法
*如果使用次数小于5次的话就放回连接池中否则关闭这个连接
*/
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)
throwsThrowable{
if("close".equals(method.getName())){
this.currentUserCount++;
if(maxUseCount==0||this.currentUserCount<maxUseCount)
this.conn.connectionsPool.addLast(this.warpedConnection);
else{
this.realConnection.close();
this.conn.currentCount--;
}
}
returnmethod.invoke(this.realConnection,args);
}
}
Connection的代理,主要是修改colse方法
user-config.xml
<?xmlversion="1.0"encoding="UTF-8"standalone="no"?>
<application>
<modulename="DataSource">
<groupname="default">
<configValuekey="DriverClass">oracle.jdbc.driver.OracleDriver</configValue>
<configValuekey="Url">jdbc:oracle:thin:@tension:1521:ORCL</configValue>
<configValuekey="UserName">xxx</configValue>
<configValuekey="Password">ooo</configValue>
<configValuekey="PoolSize">1</configValue><!--初始大小-->
<configValuekey="MaxUseCount">0</configValue><!--最大连接数使用次数-->
<configValuekey="MaxPoolSize">3</configValue><!--最大连接数-->
<configValuekey="MinPoolSize">2</configValue><!--每次增长-->
<configValuekey="Transaction-Isolation">ISOLATION_READ_COMMITTED</configValue><!--事物隔离级别-->
</group>
</module>
</application>