Posted on 2012-09-15 17:49
張力 閱讀(300)
評(píng)論(0) 編輯 收藏
最近一直想自己封裝下jdbc,寫個(gè)orm,在此拿出來(lái)分享分享我的代碼,讓高人指點(diǎn)指點(diǎn),共同進(jìn)步,也做個(gè)備份
先上代碼
DataSource.java
package org.tension.framework.common.das;
import java.io.InputStream;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* 數(shù)據(jù)源
* @author tension
*
*/
public class DataSource {
protected static String driverClassName;
protected static String url;
protected static String user;
protected static String password;
protected static int poolSize;
protected static int maxUseCount;
protected static int maxPoolSize;
protected static int minPoolSize;
protected static String transaction_Isolation;
static{
try {
InputStream ips = DataSource.class.getClassLoader().getResourceAsStream("user-config.xml");
SAXReader reader = new SAXReader();
Document doc = null;
doc = reader.read(ips);
Element root = doc.getRootElement();
Element module = root.element("module");
Element group = module.element("group");
Iterator<?> configValue = group.elementIterator("configValue");
while(configValue.hasNext()){
Element e = (Element) configValue.next();
String key = e.attributeValue("key");
String value = e.getText();
if("DriverClass".equalsIgnoreCase(key)){
driverClassName = value;
}else if("Url".equalsIgnoreCase(key)){
url = value;
}else if("UserName".equalsIgnoreCase(key)){
user = value;
}else if("Password".equalsIgnoreCase(key)){
password = value;
}else if("PoolSize".equalsIgnoreCase(key)){
poolSize = Integer.valueOf(value);
}else if("MaxUseCount".equalsIgnoreCase(key)){
maxUseCount = Integer.valueOf(value);
}else if("MaxPoolSize".equalsIgnoreCase(key)){
maxPoolSize = Integer.valueOf(value);
}else if("MinPoolSize".equalsIgnoreCase(key)){
minPoolSize = Integer.valueOf(value);
}else if("Transaction-Isolation".equalsIgnoreCase(key)){
transaction_Isolation = value;
}
}
Class.forName(driverClassName);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
}
至于為什么沒(méi)有去實(shí)現(xiàn)DataSource接口,我覺(jué)得我暫時(shí)不用它,所有沒(méi)有去實(shí)現(xiàn)
ConnectionPool.java
package org.tension.framework.common.das;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
/**
*
* 2012-9-12
*
* @author <a href="mailto:429810818@qq.com">tension</a>
*
*/
public class ConnectionPool extends DataSource{
/**當(dāng)前連接數(shù)*/
int currentCount = 0;
LinkedList<Connection> connectionsPool = new LinkedList<Connection>();
/**
* 默認(rèn)構(gòu)造方法,一次性獲得poolSize個(gè)連接放進(jìn)connectionsPool連接池中
*/
public ConnectionPool() {
CreateConnectionPool(poolSize);
}
/**
* 獲取連接記錄當(dāng)前連接個(gè)數(shù)
* 如果連接池還有連接則直接從連接池取連接,如果連接大于最大連接數(shù)
* @return
* @throws SQLException
*/
public Connection getConnection() throws SQLException {
synchronized (connectionsPool) {
if (this.connectionsPool.size() > 0){
this.currentCount++;
return this.connectionsPool.removeFirst();
}
if(this.currentCount < maxPoolSize){
int buffer = this.currentCount + minPoolSize;
if (buffer < maxPoolSize || buffer == maxPoolSize) {
this.currentCount++;
CreateConnectionPool(minPoolSize);
}else{
this.currentCount++;
CreateConnectionPool(buffer - maxPoolSize);
}
return this.connectionsPool.removeFirst();
}
throw new SQLException("暫無(wú)連接可用");
}
}
/**
* 創(chuàng)建連接放入連接池中,緩沖連接池
* @param count 個(gè)數(shù)
*/
public void CreateConnectionPool(int count){
try {
for (int i = 0; i < count; i++) {
this.connectionsPool.addLast(this.createConnection());
this.currentCount++;
}
} catch (SQLException e) {
throw new ExceptionInInitializerError(e);
}
}
/**
* 釋放連接方法
* 把用完的連接重新放回連接池中
* @param conn
*/
public void free(Connection conn) {
this.connectionsPool.addLast(conn);
}
/**
* 創(chuàng)建連接
* @return warpedConnection
* @throws SQLException
* @author tension
*/
private Connection createConnection() throws SQLException {
Connection realConn = DriverManager.getConnection(url, user, password);
ConnectionHandler proxy = new ConnectionHandler(this);
return proxy.bind(realConn);
}
}
這個(gè)就是所謂的連接池了,簡(jiǎn)單,沒(méi)有現(xiàn)在主流的那么NB,供學(xué)習(xí)
ConnectionHandler
package org.tension.framework.common.das;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
/**
* 連接池的代理類
* 用于處理Connection的colse方法,把連接放回連接池
* @author tension
* 2012-09-12
*/
class ConnectionHandler extends DataSource implements InvocationHandler{
/**真正的連接對(duì)象 */
private Connection realConnection;
/**代理的連接對(duì)象 */
private Connection warpedConnection;
/**連接池*/
private ConnectionPool conn;
/**當(dāng)前用戶使用的次數(shù)*/
private int currentUserCount = 0;
/**
* 默認(rèn)構(gòu)造方法
* @param conn 連接池
*/
ConnectionHandler(ConnectionPool conn) {
this.conn = conn;
}
/**
* java.sql.Connection的代理方法
* @param realConn warpedConnection 代理后的對(duì)象
* @return
*/
Connection bind(Connection realConn) {
this.realConnection = realConn;
this.warpedConnection = (Connection) Proxy.newProxyInstance(this
.getClass().getClassLoader(), new Class[] { Connection.class },
this);
return warpedConnection;
}
/**
* 方法攔截
* 如果為close方法的話不直接調(diào)用真正Connection的close方法
* 如果使用次數(shù)小于5次的話就放回連接池中否則關(guān)閉這個(gè)連接
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
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--;
}
}
return method.invoke(this.realConnection, args);
}
}
Connection的代理,主要是修改colse方法
user-config.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<application>
<module name="DataSource">
<group name="default">
<configValue key="DriverClass">oracle.jdbc.driver.OracleDriver</configValue>
<configValue key="Url">jdbc:oracle:thin:@tension:1521:ORCL</configValue>
<configValue key="UserName">xxx</configValue>
<configValue key="Password">ooo</configValue>
<configValue key="PoolSize">1</configValue><!-- 初始大小 -->
<configValue key="MaxUseCount">0</configValue> <!-- 最大連接數(shù) 使用次數(shù)-->
<configValue key="MaxPoolSize">3</configValue> <!-- 最大連接數(shù) -->
<configValue key="MinPoolSize">2</configValue><!-- 每次增長(zhǎng) -->
<configValue key="Transaction-Isolation">ISOLATION_READ_COMMITTED</configValue><!-- 事物隔離級(jí)別 -->
</group>
</module>
</application>