mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
改进PreparedStatementCache
git-svn-id: http://code.alibabatech.com/svn/druid/trunk@916 b9813039-fb51-4c41-a8b9-e21c2acb5095
This commit is contained in:
@@ -41,6 +41,7 @@ import com.alibaba.druid.VERSION;
|
||||
import com.alibaba.druid.filter.Filter;
|
||||
import com.alibaba.druid.logging.Log;
|
||||
import com.alibaba.druid.logging.LogFactory;
|
||||
import com.alibaba.druid.pool.PoolablePreparedStatement.PreparedStatementKey;
|
||||
import com.alibaba.druid.pool.vendor.InformixExceptionSorter;
|
||||
import com.alibaba.druid.pool.vendor.MSSQLValidConnectionChecker;
|
||||
import com.alibaba.druid.pool.vendor.MockExceptionSorter;
|
||||
@@ -725,7 +726,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
if (poolingPeakTime <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return new Date(poolingPeakTime);
|
||||
}
|
||||
|
||||
@@ -1090,7 +1091,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public long getErrorCount() {
|
||||
return this.errorCount.get();
|
||||
}
|
||||
@@ -1137,6 +1138,31 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
|
||||
buf.append("\n}");
|
||||
|
||||
if (this.isPoolPreparedStatements()) {
|
||||
buf.append("\n\n[");
|
||||
for (int i = 0; i < poolingCount; ++i) {
|
||||
ConnectionHolder conn = connections[i];
|
||||
if (conn != null) {
|
||||
if (i != 0) {
|
||||
buf.append(",");
|
||||
}
|
||||
buf.append("\n\t{ID:");
|
||||
buf.append(System.identityHashCode(conn));
|
||||
buf.append(", poolStatements:[");
|
||||
PreparedStatementPool pool = conn.getStatementPool();
|
||||
for (Map.Entry<PreparedStatementKey, PreparedStatementHolder> entry : pool.getMap().entrySet()) {
|
||||
buf.append("\n\t\t{reuseCount:");
|
||||
buf.append(entry.getValue().getReusedCount());
|
||||
buf.append(",sql:\"");
|
||||
buf.append(entry.getKey().getSql());
|
||||
buf.append("\"");
|
||||
}
|
||||
buf.append("}");
|
||||
}
|
||||
}
|
||||
buf.append("\n]");
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -37,10 +37,9 @@ public class PoolableCallableStatement extends PoolablePreparedStatement impleme
|
||||
|
||||
private CallableStatement stmt;
|
||||
|
||||
public PoolableCallableStatement(PoolableConnection conn, CallableStatement stmt, PreparedStatementKey key,
|
||||
String sql) throws SQLException{
|
||||
super(conn, stmt, key, sql);
|
||||
this.stmt = stmt;
|
||||
public PoolableCallableStatement(PoolableConnection conn, PreparedStatementHolder holder) throws SQLException{
|
||||
super(conn, holder);
|
||||
this.stmt = (CallableStatement) holder.getStatement();
|
||||
}
|
||||
|
||||
public CallableStatement getCallableStatementRaw() {
|
||||
|
||||
@@ -89,7 +89,7 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
}
|
||||
|
||||
if (holder.isPoolPreparedStatements()) {
|
||||
this.holder.getStatementPool().put(stmt);
|
||||
this.holder.getStatementPool().put(stmt.getPreparedStatementHolder());
|
||||
stmt.clearResultSet();
|
||||
holder.removeTrace(stmt);
|
||||
stmt.setClosed(true); // soft set close
|
||||
@@ -110,8 +110,8 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
void closePoolableStatement() {
|
||||
PreparedStatementPool statmentPool = holder.getStatementPool();
|
||||
if (statmentPool != null) {
|
||||
for (PreparedStatement stmt : statmentPool.getMap().values()) {
|
||||
JdbcUtils.close(stmt);
|
||||
for (PreparedStatementHolder holder : statmentPool.getMap().values()) {
|
||||
JdbcUtils.close(holder.getStatement());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,15 +155,15 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
|
||||
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M1);
|
||||
|
||||
PreparedStatement stmt = null;
|
||||
PreparedStatementHolder stmtHolder = null;
|
||||
|
||||
if (holder.isPoolPreparedStatements()) {
|
||||
stmt = holder.getStatementPool().get(key);
|
||||
stmtHolder = holder.getStatementPool().get(key);
|
||||
}
|
||||
|
||||
if (stmt == null) {
|
||||
if (stmtHolder == null) {
|
||||
try {
|
||||
stmt = conn.prepareStatement(sql);
|
||||
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql));
|
||||
} catch (SQLException ex) {
|
||||
handleException(ex);
|
||||
}
|
||||
@@ -171,9 +171,9 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
holder.getDataSource().incrementPreparedStatementCount();
|
||||
}
|
||||
|
||||
holder.getDataSource().initStatement(stmt);
|
||||
holder.getDataSource().initStatement(stmtHolder.getStatement());
|
||||
|
||||
PoolablePreparedStatement rtnVal = new PoolablePreparedStatement(this, stmt, key, sql);
|
||||
PoolablePreparedStatement rtnVal = new PoolablePreparedStatement(this, stmtHolder);
|
||||
|
||||
holder.addTrace(rtnVal);
|
||||
|
||||
@@ -187,15 +187,15 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
|
||||
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M2);
|
||||
|
||||
PreparedStatement stmt = null;
|
||||
PreparedStatementHolder stmtHolder = null;
|
||||
|
||||
if (holder.isPoolPreparedStatements()) {
|
||||
stmt = holder.getStatementPool().get(key);
|
||||
stmtHolder = holder.getStatementPool().get(key);
|
||||
}
|
||||
|
||||
if (stmt == null) {
|
||||
if (stmtHolder == null) {
|
||||
try {
|
||||
stmt = conn.prepareStatement(sql, resultSetType, resultSetConcurrency);
|
||||
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, resultSetType, resultSetConcurrency));
|
||||
} catch (SQLException ex) {
|
||||
handleException(ex);
|
||||
}
|
||||
@@ -203,9 +203,9 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
holder.getDataSource().incrementPreparedStatementCount();
|
||||
}
|
||||
|
||||
holder.getDataSource().initStatement(stmt);
|
||||
holder.getDataSource().initStatement(stmtHolder.getStatement());
|
||||
|
||||
PoolablePreparedStatement rtnVal = new PoolablePreparedStatement(this, stmt, key, sql);
|
||||
PoolablePreparedStatement rtnVal = new PoolablePreparedStatement(this, stmtHolder);
|
||||
|
||||
holder.addTrace(rtnVal);
|
||||
|
||||
@@ -219,15 +219,15 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
|
||||
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M3);
|
||||
|
||||
PreparedStatement stmt = null;
|
||||
PreparedStatementHolder stmtHolder = null;
|
||||
|
||||
if (holder.isPoolPreparedStatements()) {
|
||||
stmt = holder.getStatementPool().get(key);
|
||||
stmtHolder = holder.getStatementPool().get(key);
|
||||
}
|
||||
|
||||
if (stmt == null) {
|
||||
if (stmtHolder == null) {
|
||||
try {
|
||||
stmt = conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
|
||||
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
|
||||
} catch (SQLException ex) {
|
||||
handleException(ex);
|
||||
}
|
||||
@@ -235,9 +235,9 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
holder.getDataSource().incrementPreparedStatementCount();
|
||||
}
|
||||
|
||||
holder.getDataSource().initStatement(stmt);
|
||||
holder.getDataSource().initStatement(stmtHolder.getStatement());
|
||||
|
||||
PoolablePreparedStatement rtnVal = new PoolablePreparedStatement(this, stmt, key, sql);
|
||||
PoolablePreparedStatement rtnVal = new PoolablePreparedStatement(this, stmtHolder);
|
||||
|
||||
holder.addTrace(rtnVal);
|
||||
|
||||
@@ -248,16 +248,16 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
|
||||
checkOpen();
|
||||
|
||||
PreparedStatement stmt = null;
|
||||
PreparedStatementHolder stmtHolder = null;
|
||||
|
||||
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M4);
|
||||
if (holder.isPoolPreparedStatements()) {
|
||||
stmt = holder.getStatementPool().get(key);
|
||||
stmtHolder = holder.getStatementPool().get(key);
|
||||
}
|
||||
|
||||
if (stmt == null) {
|
||||
if (stmtHolder == null) {
|
||||
try {
|
||||
stmt = conn.prepareStatement(sql, columnIndexes);
|
||||
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, columnIndexes));
|
||||
} catch (SQLException ex) {
|
||||
handleException(ex);
|
||||
}
|
||||
@@ -265,9 +265,9 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
holder.getDataSource().incrementPreparedStatementCount();
|
||||
}
|
||||
|
||||
holder.getDataSource().initStatement(stmt);
|
||||
holder.getDataSource().initStatement(stmtHolder.getStatement());
|
||||
|
||||
PoolablePreparedStatement rtnVal = new PoolablePreparedStatement(this, stmt, key, sql);
|
||||
PoolablePreparedStatement rtnVal = new PoolablePreparedStatement(this, stmtHolder);
|
||||
|
||||
holder.addTrace(rtnVal);
|
||||
|
||||
@@ -278,16 +278,16 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
|
||||
checkOpen();
|
||||
|
||||
PreparedStatement stmt = null;
|
||||
PreparedStatementHolder stmtHolder = null;
|
||||
|
||||
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M5);
|
||||
if (holder.isPoolPreparedStatements()) {
|
||||
stmt = holder.getStatementPool().get(key);
|
||||
stmtHolder = holder.getStatementPool().get(key);
|
||||
}
|
||||
|
||||
if (stmt == null) {
|
||||
if (stmtHolder == null) {
|
||||
try {
|
||||
stmt = conn.prepareStatement(sql, columnNames);
|
||||
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, columnNames));
|
||||
} catch (SQLException ex) {
|
||||
handleException(ex);
|
||||
}
|
||||
@@ -295,9 +295,9 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
holder.getDataSource().incrementPreparedStatementCount();
|
||||
}
|
||||
|
||||
holder.getDataSource().initStatement(stmt);
|
||||
holder.getDataSource().initStatement(stmtHolder.getStatement());
|
||||
|
||||
PoolablePreparedStatement rtnVal = new PoolablePreparedStatement(this, stmt, key, sql);
|
||||
PoolablePreparedStatement rtnVal = new PoolablePreparedStatement(this, stmtHolder);
|
||||
|
||||
holder.addTrace(rtnVal);
|
||||
|
||||
@@ -308,16 +308,16 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
|
||||
checkOpen();
|
||||
|
||||
PreparedStatement stmt = null;
|
||||
PreparedStatementHolder stmtHolder = null;
|
||||
|
||||
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.M6);
|
||||
if (holder.isPoolPreparedStatements()) {
|
||||
stmt = holder.getStatementPool().get(key);
|
||||
stmtHolder = holder.getStatementPool().get(key);
|
||||
}
|
||||
|
||||
if (stmt == null) {
|
||||
if (stmtHolder == null) {
|
||||
try {
|
||||
stmt = conn.prepareStatement(sql, autoGeneratedKeys);
|
||||
stmtHolder = new PreparedStatementHolder(key, conn.prepareStatement(sql, autoGeneratedKeys));
|
||||
} catch (SQLException ex) {
|
||||
handleException(ex);
|
||||
}
|
||||
@@ -325,9 +325,9 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
holder.getDataSource().incrementPreparedStatementCount();
|
||||
}
|
||||
|
||||
holder.getDataSource().initStatement(stmt);
|
||||
holder.getDataSource().initStatement(stmtHolder.getStatement());
|
||||
|
||||
PoolablePreparedStatement rtnVal = new PoolablePreparedStatement(this, stmt, key, sql);
|
||||
PoolablePreparedStatement rtnVal = new PoolablePreparedStatement(this, stmtHolder);
|
||||
|
||||
holder.addTrace(rtnVal);
|
||||
|
||||
@@ -342,15 +342,15 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
|
||||
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.Precall_1);
|
||||
|
||||
CallableStatement stmt = null;
|
||||
PreparedStatementHolder stmtHolder = null;
|
||||
|
||||
if (holder.isPoolPreparedStatements()) {
|
||||
stmt = (CallableStatement) holder.getStatementPool().get(key);
|
||||
stmtHolder = holder.getStatementPool().get(key);
|
||||
}
|
||||
|
||||
if (stmt == null) {
|
||||
if (stmtHolder == null) {
|
||||
try {
|
||||
stmt = conn.prepareCall(sql);
|
||||
stmtHolder = new PreparedStatementHolder(key, conn.prepareCall(sql));
|
||||
} catch (SQLException ex) {
|
||||
handleException(ex);
|
||||
}
|
||||
@@ -358,9 +358,9 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
holder.getDataSource().incrementPreparedStatementCount();
|
||||
}
|
||||
|
||||
holder.getDataSource().initStatement(stmt);
|
||||
holder.getDataSource().initStatement(stmtHolder.getStatement());
|
||||
|
||||
PoolableCallableStatement rtnVal = new PoolableCallableStatement(this, stmt, key, sql);
|
||||
PoolableCallableStatement rtnVal = new PoolableCallableStatement(this, stmtHolder);
|
||||
|
||||
holder.addTrace(rtnVal);
|
||||
|
||||
@@ -372,16 +372,16 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
int resultSetHoldability) throws SQLException {
|
||||
checkOpen();
|
||||
|
||||
CallableStatement stmt = null;
|
||||
PreparedStatementHolder stmtHolder = null;
|
||||
|
||||
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.Precall_2);
|
||||
if (holder.isPoolPreparedStatements()) {
|
||||
stmt = (CallableStatement) holder.getStatementPool().get(key);
|
||||
stmtHolder = holder.getStatementPool().get(key);
|
||||
}
|
||||
|
||||
if (stmt == null) {
|
||||
if (stmtHolder == null) {
|
||||
try {
|
||||
stmt = conn.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
|
||||
stmtHolder = new PreparedStatementHolder(key, conn.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
|
||||
} catch (SQLException ex) {
|
||||
handleException(ex);
|
||||
}
|
||||
@@ -389,9 +389,9 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
holder.getDataSource().incrementPreparedStatementCount();
|
||||
}
|
||||
|
||||
holder.getDataSource().initStatement(stmt);
|
||||
holder.getDataSource().initStatement(stmtHolder.getStatement());
|
||||
|
||||
PoolableCallableStatement rtnVal = new PoolableCallableStatement(this, stmt, key, sql);
|
||||
PoolableCallableStatement rtnVal = new PoolableCallableStatement(this, stmtHolder);
|
||||
|
||||
holder.addTrace(rtnVal);
|
||||
|
||||
@@ -402,16 +402,16 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
|
||||
checkOpen();
|
||||
|
||||
CallableStatement stmt = null;
|
||||
PreparedStatementHolder stmtHolder = null;
|
||||
|
||||
PreparedStatementKey key = new PreparedStatementKey(sql, getCatalog(), MethodType.Precall_3);
|
||||
if (holder.isPoolPreparedStatements()) {
|
||||
stmt = (CallableStatement) holder.getStatementPool().get(key);
|
||||
stmtHolder = holder.getStatementPool().get(key);
|
||||
}
|
||||
|
||||
if (stmt == null) {
|
||||
if (stmtHolder == null) {
|
||||
try {
|
||||
stmt = conn.prepareCall(sql, resultSetType, resultSetConcurrency);
|
||||
stmtHolder = new PreparedStatementHolder(key, conn.prepareCall(sql, resultSetType, resultSetConcurrency));
|
||||
} catch (SQLException ex) {
|
||||
handleException(ex);
|
||||
}
|
||||
@@ -419,9 +419,9 @@ public class PoolableConnection implements PooledConnection, Connection {
|
||||
holder.getDataSource().incrementPreparedStatementCount();
|
||||
}
|
||||
|
||||
holder.getDataSource().initStatement(stmt);
|
||||
holder.getDataSource().initStatement(stmtHolder.getStatement());
|
||||
|
||||
PoolableCallableStatement rtnVal = new PoolableCallableStatement(this, stmt, key, sql);
|
||||
PoolableCallableStatement rtnVal = new PoolableCallableStatement(this, stmtHolder);
|
||||
holder.addTrace(rtnVal);
|
||||
|
||||
return rtnVal;
|
||||
|
||||
@@ -43,27 +43,26 @@ import com.alibaba.druid.pool.PreparedStatementPool.MethodType;
|
||||
*/
|
||||
public class PoolablePreparedStatement extends PoolableStatement implements PreparedStatement {
|
||||
|
||||
private PreparedStatement stmt;
|
||||
private final PreparedStatementKey key;
|
||||
private final String sql;
|
||||
private final PreparedStatementHolder holder;
|
||||
private final PreparedStatement stmt;
|
||||
private final String sql;
|
||||
|
||||
private int defaultMaxFieldSize;
|
||||
private int defaultMaxRows;
|
||||
private int defaultQueryTimeout;
|
||||
private int defaultFetchDirection;
|
||||
private int defaultFetchSize;
|
||||
private int currentMaxFieldSize;
|
||||
private int currentMaxRows;
|
||||
private int currentQueryTimeout;
|
||||
private int currentFetchDirection;
|
||||
private int currentFetchSize;
|
||||
private int defaultMaxFieldSize;
|
||||
private int defaultMaxRows;
|
||||
private int defaultQueryTimeout;
|
||||
private int defaultFetchDirection;
|
||||
private int defaultFetchSize;
|
||||
private int currentMaxFieldSize;
|
||||
private int currentMaxRows;
|
||||
private int currentQueryTimeout;
|
||||
private int currentFetchDirection;
|
||||
private int currentFetchSize;
|
||||
|
||||
public PoolablePreparedStatement(PoolableConnection conn, PreparedStatement stmt, PreparedStatementKey key,
|
||||
String sql) throws SQLException{
|
||||
super(conn, stmt);
|
||||
this.stmt = stmt;
|
||||
this.key = key;
|
||||
this.sql = sql;
|
||||
public PoolablePreparedStatement(PoolableConnection conn, PreparedStatementHolder holder) throws SQLException{
|
||||
super(conn, holder.getStatement());
|
||||
this.stmt = holder.getStatement();
|
||||
this.holder = holder;
|
||||
this.sql = holder.getKey().sql;
|
||||
|
||||
// Remember the defaults
|
||||
defaultMaxFieldSize = stmt.getMaxFieldSize();
|
||||
@@ -77,7 +76,11 @@ public class PoolablePreparedStatement extends PoolableStatement implements Prep
|
||||
currentFetchDirection = defaultFetchDirection;
|
||||
currentFetchSize = defaultFetchSize;
|
||||
}
|
||||
|
||||
|
||||
public PreparedStatementHolder getPreparedStatementHolder() {
|
||||
return holder;
|
||||
}
|
||||
|
||||
public void setFetchSize(int rows) throws SQLException {
|
||||
currentFetchSize = rows;
|
||||
super.setFetchSize(rows);
|
||||
@@ -108,7 +111,7 @@ public class PoolablePreparedStatement extends PoolableStatement implements Prep
|
||||
}
|
||||
|
||||
public PreparedStatementKey getKey() {
|
||||
return key;
|
||||
return holder.getKey();
|
||||
}
|
||||
|
||||
public PreparedStatement getRawPreparedStatement() {
|
||||
@@ -783,8 +786,8 @@ public class PoolablePreparedStatement extends PoolableStatement implements Prep
|
||||
|
||||
public static class PreparedStatementKey {
|
||||
|
||||
protected final String sql;
|
||||
protected final String catalog;
|
||||
private final String sql;
|
||||
private final String catalog;
|
||||
|
||||
protected final MethodType methodType;
|
||||
|
||||
@@ -822,6 +825,10 @@ public class PoolablePreparedStatement extends PoolableStatement implements Prep
|
||||
return true;
|
||||
}
|
||||
|
||||
public String getSql() {
|
||||
return sql;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int catalogHashCode = catalog == null ? 0 : catalog.hashCode();
|
||||
int sqlHashCode = sql.hashCode();
|
||||
|
||||
@@ -17,20 +17,36 @@ package com.alibaba.druid.pool;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
import com.alibaba.druid.pool.PoolablePreparedStatement.PreparedStatementKey;
|
||||
|
||||
/**
|
||||
* @author wenshao<szujobs@hotmail.com>
|
||||
*/
|
||||
public final class PreparedStatementHolder<T extends PreparedStatement> {
|
||||
public final class PreparedStatementHolder {
|
||||
|
||||
private final T statement;
|
||||
private final PreparedStatementKey key;
|
||||
private final PreparedStatement statement;
|
||||
private int useCount = 0;
|
||||
|
||||
public PreparedStatementHolder(T stmt){
|
||||
super();
|
||||
public PreparedStatementHolder(PreparedStatementKey key, PreparedStatement stmt){
|
||||
this.key = key;
|
||||
this.statement = stmt;
|
||||
}
|
||||
|
||||
public T getStatement() {
|
||||
public PreparedStatement getStatement() {
|
||||
return statement;
|
||||
}
|
||||
|
||||
public PreparedStatementKey getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public void incrementReusedCount() {
|
||||
useCount++;
|
||||
}
|
||||
|
||||
public int getReusedCount() {
|
||||
return useCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
package com.alibaba.druid.pool;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.druid.pool.PoolablePreparedStatement.PreparedStatementKey;
|
||||
import com.alibaba.druid.util.LRUCache;
|
||||
@@ -25,26 +26,36 @@ import com.alibaba.druid.util.LRUCache;
|
||||
*/
|
||||
public class PreparedStatementPool {
|
||||
|
||||
private final LRUCache<PreparedStatementKey, PreparedStatement> map;
|
||||
private final Map<PreparedStatementKey, PreparedStatementHolder> map;
|
||||
|
||||
public PreparedStatementPool(int maxSize){
|
||||
map = new LRUCache<PreparedStatementKey, PreparedStatement>(maxSize);
|
||||
if (maxSize < 0) {
|
||||
map = new HashMap<PreparedStatementKey, PreparedStatementHolder>(maxSize);
|
||||
} else {
|
||||
map = new LRUCache<PreparedStatementKey, PreparedStatementHolder>(maxSize);
|
||||
}
|
||||
}
|
||||
|
||||
public static enum MethodType {
|
||||
M1, M2, M3, M4, M5, M6, Precall_1, Precall_2, Precall_3
|
||||
}
|
||||
|
||||
public PreparedStatement get(PreparedStatementKey key) {
|
||||
return map.remove(key);
|
||||
public PreparedStatementHolder get(PreparedStatementKey key) {
|
||||
PreparedStatementHolder holder = map.remove(key);
|
||||
|
||||
if (holder != null) {
|
||||
holder.incrementReusedCount();
|
||||
}
|
||||
|
||||
return holder;
|
||||
}
|
||||
|
||||
public void put(PoolablePreparedStatement poolableStatement) {
|
||||
PreparedStatementKey key = poolableStatement.getKey();
|
||||
map.put(key, poolableStatement.getRawPreparedStatement());
|
||||
public void put(PreparedStatementHolder holder) {
|
||||
PreparedStatementKey key = holder.getKey();
|
||||
map.put(key, holder);
|
||||
}
|
||||
|
||||
public LRUCache<PreparedStatementKey, PreparedStatement> getMap() {
|
||||
public Map<PreparedStatementKey, PreparedStatementHolder> getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,15 +76,7 @@ public class DataSourceTest3 extends TestCase {
|
||||
|
||||
conn.close();
|
||||
|
||||
{
|
||||
Exception error = null;
|
||||
try {
|
||||
dataSource.setPoolPreparedStatements(false);
|
||||
} catch (Exception ex) {
|
||||
error = ex;
|
||||
}
|
||||
Assert.assertNotNull(error);
|
||||
}
|
||||
dataSource.setPoolPreparedStatements(false);
|
||||
}
|
||||
|
||||
public void test_error_2() throws Exception {
|
||||
|
||||
@@ -18,6 +18,8 @@ import junit.framework.TestCase;
|
||||
|
||||
import com.alibaba.druid.mock.MockCallableStatement;
|
||||
import com.alibaba.druid.pool.PoolableCallableStatement;
|
||||
import com.alibaba.druid.pool.PoolablePreparedStatement.PreparedStatementKey;
|
||||
import com.alibaba.druid.pool.PreparedStatementHolder;
|
||||
|
||||
public class PoolableCallableStatementTest extends TestCase {
|
||||
|
||||
@@ -26,7 +28,7 @@ public class PoolableCallableStatementTest extends TestCase {
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
raw = new MockCallableStatement(null, null);
|
||||
stmt = new PoolableCallableStatement(null, raw, null, null) {
|
||||
stmt = new PoolableCallableStatement(null, new PreparedStatementHolder(new PreparedStatementKey("", null, null), raw)) {
|
||||
|
||||
protected SQLException checkException(Throwable error) throws SQLException {
|
||||
if (error instanceof SQLException) {
|
||||
|
||||
@@ -14,6 +14,8 @@ import junit.framework.TestCase;
|
||||
|
||||
import com.alibaba.druid.mock.MockPreparedStatement;
|
||||
import com.alibaba.druid.pool.PoolablePreparedStatement;
|
||||
import com.alibaba.druid.pool.PreparedStatementHolder;
|
||||
import com.alibaba.druid.pool.PoolablePreparedStatement.PreparedStatementKey;
|
||||
|
||||
public class PoolablePreparedStatementTest extends TestCase {
|
||||
|
||||
@@ -22,7 +24,7 @@ public class PoolablePreparedStatementTest extends TestCase {
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
raw = new MockPreparedStatement(null, null);
|
||||
stmt = new PoolablePreparedStatement(null, raw, null, null) {
|
||||
stmt = new PoolablePreparedStatement(null, new PreparedStatementHolder(new PreparedStatementKey("", null, null), raw)) {
|
||||
|
||||
protected SQLException checkException(Throwable error) throws SQLException {
|
||||
if (error instanceof SQLException) {
|
||||
|
||||
@@ -5,8 +5,8 @@ import junit.framework.TestCase;
|
||||
import org.junit.Assert;
|
||||
|
||||
import com.alibaba.druid.mock.MockPreparedStatement;
|
||||
import com.alibaba.druid.pool.PoolablePreparedStatement;
|
||||
import com.alibaba.druid.pool.PoolablePreparedStatement.PreparedStatementKey;
|
||||
import com.alibaba.druid.pool.PreparedStatementHolder;
|
||||
import com.alibaba.druid.pool.PreparedStatementPool;
|
||||
import com.alibaba.druid.pool.PreparedStatementPool.MethodType;
|
||||
|
||||
@@ -96,8 +96,9 @@ public class PreparedStatementKeyTest extends TestCase {
|
||||
|
||||
public void test_contains() throws Exception {
|
||||
PreparedStatementKey k1 = new PreparedStatementKey("x1", "c1", MethodType.M1);
|
||||
PreparedStatementPool pool = new PreparedStatementPool();
|
||||
pool.put(new PoolablePreparedStatement(null, new MockPreparedStatement(null, null), k1, null));
|
||||
PreparedStatementPool pool = new PreparedStatementPool(10);
|
||||
MockPreparedStatement raw = new MockPreparedStatement(null, null);
|
||||
pool.put(new PreparedStatementHolder(k1, raw));
|
||||
Assert.assertTrue(pool.get(k1) != null);
|
||||
Assert.assertTrue(pool.get(k1) == null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user