From 3c1acd06b810aa3d03c16c0572722bb9662acea0 Mon Sep 17 00:00:00 2001 From: wenshao Date: Sat, 10 Dec 2016 21:18:36 +0800 Subject: [PATCH] DruidDataSource add initVariable & initGlobalVariable support. --- .../druid/pool/DruidAbstractDataSource.java | 100 ++++++++++++++++-- .../druid/pool/DruidConnectionHolder.java | 20 +++- .../druid/pool/DruidPooledConnection.java | 20 +++- .../druid/test/RaspberryPiMySqlTest.java | 38 ++++++- 4 files changed, 164 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java index 6e7a1fc195..eb10e03e08 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java +++ b/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java @@ -62,11 +62,7 @@ import com.alibaba.druid.stat.JdbcSqlStat; import com.alibaba.druid.stat.JdbcStatManager; import com.alibaba.druid.support.logging.Log; import com.alibaba.druid.support.logging.LogFactory; -import com.alibaba.druid.util.DruidPasswordCallback; -import com.alibaba.druid.util.Histogram; -import com.alibaba.druid.util.JdbcUtils; -import com.alibaba.druid.util.StringUtils; -import com.alibaba.druid.util.Utils; +import com.alibaba.druid.util.*; /** * @author wenshao [szujobs@hotmail.com] @@ -252,6 +248,9 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements protected ScheduledExecutorService destroyScheduler; protected ScheduledExecutorService createScheduler; + protected boolean initVariants = false; + protected boolean initGlobalVariants = false; + public DruidAbstractDataSource(boolean lockFair){ lock = new ReentrantLock(lockFair); @@ -859,6 +858,22 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements this.userCallback = userCallback; } + public boolean isInitVariants() { + return initVariants; + } + + public void setInitVariants(boolean initVariants) { + this.initVariants = initVariants; + } + + public boolean isInitGlobalVariants() { + return initGlobalVariants; + } + + public void setInitGlobalVariants(boolean initGlobalVariants) { + this.initGlobalVariants = initGlobalVariants; + } + /** * Retrieves the number of seconds the driver will wait for a Statement object to execute. If the limit * is exceeded, a SQLException is thrown. @@ -1477,6 +1492,14 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements long connectStartNanos = System.nanoTime(); long connectedNanos, initedNanos, validatedNanos; + + Map variables = initVariants + ? new HashMap() + : null; + Map globalVariables = initGlobalVariants + ? new HashMap() + : null; + try { conn = createPhysicalConnection(url, physicalConnectProperties); connectedNanos = System.nanoTime(); @@ -1485,7 +1508,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements throw new SQLException("connect error, url " + url + ", driverClass " + this.driverClass); } - initPhysicalConnection(conn); + initPhysicalConnection(conn, variables, globalVariables); initedNanos = System.nanoTime(); validateConnection(conn); @@ -1510,7 +1533,7 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements createTimespan += nano; } - return new PhysicalConnectionInfo(conn, connectStartNanos, connectedNanos, initedNanos, validatedNanos); + return new PhysicalConnectionInfo(conn, connectStartNanos, connectedNanos, initedNanos, validatedNanos, variables, globalVariables); } protected void setCreateError(Throwable ex) { @@ -1543,6 +1566,10 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements } public void initPhysicalConnection(Connection conn) throws SQLException { + initPhysicalConnection(conn, null, null); + } + + public void initPhysicalConnection(Connection conn, Map variables, Map globalVariables) throws SQLException { if (conn.getAutoCommit() != defaultAutoCommit) { conn.setAutoCommit(defaultAutoCommit); } @@ -1564,13 +1591,16 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements } Collection initSqls = getConnectionInitSqls(); - if (initSqls.size() == 0) { + if (initSqls.size() == 0 + && variables == null + && globalVariables == null) { return; } Statement stmt = null; try { stmt = conn.createStatement(); + for (String sql : initSqls) { if (sql == null) { continue; @@ -1578,6 +1608,36 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements stmt.execute(sql); } + + if (JdbcConstants.MYSQL.equals(dbType)) { + if (variables != null) { + ResultSet rs = null; + try { + rs = stmt.executeQuery("show variables"); + while (rs.next()) { + String name = rs.getString(1); + Object value = rs.getObject(2); + variables.put(name, value); + } + } finally { + JdbcUtils.close(rs); + } + } + + if (globalVariables != null) { + ResultSet rs = null; + try { + rs = stmt.executeQuery("show global variables"); + while (rs.next()) { + String name = rs.getString(1); + Object value = rs.getObject(2); + globalVariables.put(name, value); + } + } finally { + JdbcUtils.close(rs); + } + } + } } finally { JdbcUtils.close(stmt); } @@ -1838,18 +1898,32 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements private long connectedNanos; private long initedNanos; private long validatedNanos; + private Map vairiables; + private Map globalVairiables; + + public PhysicalConnectionInfo(Connection connection // + , long connectStartNanos // + , long connectedNanos // + , long initedNanos // + , long validatedNanos) { + this(connection, connectStartNanos, connectedNanos, initedNanos,validatedNanos, null, null); + } public PhysicalConnectionInfo(Connection connection // , long connectStartNanos // , long connectedNanos // , long initedNanos // - , long validatedNanos) { + , long validatedNanos + , Map vairiables + , Map globalVairiables) { this.connection = connection; this.connectStartNanos = connectStartNanos; this.connectedNanos = connectedNanos; this.initedNanos = initedNanos; this.validatedNanos = validatedNanos; + this.vairiables = vairiables; + this.globalVairiables = globalVairiables; } public Connection getPhysicalConnection() { @@ -1875,5 +1949,13 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements public long getConnectNanoSpan() { return connectedNanos - connectStartNanos; } + + public Map getVairiables() { + return vairiables; + } + + public Map getGlobalVairiables() { + return globalVairiables; + } } } diff --git a/src/main/java/com/alibaba/druid/pool/DruidConnectionHolder.java b/src/main/java/com/alibaba/druid/pool/DruidConnectionHolder.java index 569a245aa6..6b976d3f96 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidConnectionHolder.java +++ b/src/main/java/com/alibaba/druid/pool/DruidConnectionHolder.java @@ -32,6 +32,7 @@ import java.sql.Statement; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -68,18 +69,35 @@ public final class DruidConnectionHolder { private int underlyingTransactionIsolation; private boolean underlyingAutoCommit; private boolean discard = false; + + protected final Map variables; + protected final Map globleVariables; public static boolean holdabilityUnsupported = false; public DruidConnectionHolder(DruidAbstractDataSource dataSource, PhysicalConnectionInfo pyConnectInfo) throws SQLException { - this(dataSource, pyConnectInfo.getPhysicalConnection(), pyConnectInfo.getConnectNanoSpan()); + this(dataSource + , pyConnectInfo.getPhysicalConnection() + , pyConnectInfo.getConnectNanoSpan() + , pyConnectInfo.getVairiables() + , pyConnectInfo.getGlobalVairiables()); } public DruidConnectionHolder(DruidAbstractDataSource dataSource, Connection conn, long connectNanoSpan) throws SQLException{ + this(dataSource, conn, connectNanoSpan, null, null); + } + public DruidConnectionHolder(DruidAbstractDataSource dataSource + , Connection conn + , long connectNanoSpan + , Map variables + , Map globleVariables) throws SQLException{ this.dataSource = dataSource; this.conn = conn; this.createNanoSpan = connectNanoSpan; + this.variables = variables; + this.globleVariables = globleVariables; + this.connectTimeMillis = System.currentTimeMillis(); this.lastActiveTimeMillis = connectTimeMillis; diff --git a/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java b/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java index 8b0ab44974..2f95d12309 100644 --- a/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java +++ b/src/main/java/com/alibaba/druid/pool/DruidPooledConnection.java @@ -1192,23 +1192,37 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql. } /** - * @since 1.1.17 + * @since 1.0.17 */ public long getPhysicalConnectNanoSpan() { return this.holder.getCreateNanoSpan(); } /** - * @since 1.1.17 + * @since 1.0.17 */ public long getPhysicalConnectionUsedCount() { return this.holder.getUseCount(); } /** - * @since 1.1.17 + * @since 1.0.17 */ public long getConnectNotEmptyWaitNanos() { return this.holder.getLastNotEmptyWaitNanos(); } + + /** + * @since 1.0.28 + */ + public Map getVariables() { + return this.holder.variables; + } + + /** + * @since 1.0.28 + */ + public Map getGloablVariables() { + return this.holder.globleVariables; + } } diff --git a/src/test/java/com/alibaba/druid/test/RaspberryPiMySqlTest.java b/src/test/java/com/alibaba/druid/test/RaspberryPiMySqlTest.java index 4d6486836b..01bde3084a 100644 --- a/src/test/java/com/alibaba/druid/test/RaspberryPiMySqlTest.java +++ b/src/test/java/com/alibaba/druid/test/RaspberryPiMySqlTest.java @@ -1,7 +1,43 @@ package com.alibaba.druid.test; +import com.alibaba.druid.pool.DruidDataSource; +import com.alibaba.druid.pool.DruidPooledConnection; +import com.alibaba.druid.util.JdbcUtils; +import junit.framework.TestCase; +import org.junit.Assert; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; + /** * Created by wenshao on 10/12/2016. */ -public class RaspberryPiMySqlTest { +public class RaspberryPiMySqlTest extends TestCase { + private DruidDataSource dataSource; + + protected void setUp() throws Exception { + dataSource = new DruidDataSource(); + dataSource.setUrl("jdbc:mysql://raspberrypi_mysql:3306/druid_test_db?allowMultiQueries=true"); + dataSource.setUsername("druid_test"); + dataSource.setPassword("druid_test"); + dataSource.setValidationQuery("SELECT 1"); + dataSource.setTestOnBorrow(true); + dataSource.setTestWhileIdle(true); + dataSource.setInitVariants(true); + dataSource.setInitGlobalVariants(true); + } + + protected void tearDown() throws Exception { + dataSource.close(); + } + + public void test_mysql() throws Exception { + DruidPooledConnection connection = dataSource.getConnection(); + + System.out.println("variables : " + connection.getVariables()); + System.out.println("gloabl variables : " + connection.getGloablVariables()); + + connection.close(); + } }