【问题标题】:How to get JDBC connection id?如何获取 JDBC 连接 ID?
【发布时间】:2012-11-04 01:50:56
【问题描述】:

我需要使用 Connection 对象获取 JDBC 连接 ID(UUID)。有没有办法获取连接ID?

【问题讨论】:

  • 什么是 JDBC 连接 ID (UUID),据我所知没有这样的东西。如果您在谈论特定的 JDBC 驱动程序或数据库系统,请指定。
  • 当我连接到数据库时,他们在论文中维护了一个唯一的 ID。假设如果我的 sql 服务器重新启动意味着我现有的连接对象抛出错误。如果我能够获得该唯一 ID,我就可以检查条件并重新连接
  • 这个有更新吗?我想获取每个数据库连接的标识符。

标签: jdbc database-connection


【解决方案1】:

好吧,如果您说的是“sql-connection to sql-server”,那么 jdbc 对此没有标准工具。这是 jdbc:mysql 的手工示例(注意 - 反射和受限字符):

    private long getJdbcConnectionId(Connection conn) {
    long cid = 0;
    try {
        Field f_conn__conn = conn.getClass().getSuperclass().getDeclaredField("_conn");
        f_conn__conn.setAccessible(true);
        Object o_conn__conn = f_conn__conn.get(conn);
        Field f_conn__conn__conn = o_conn__conn.getClass().getSuperclass().getDeclaredField("_conn");
        f_conn__conn__conn.setAccessible(true);
        Object o_conn__conn__conn = f_conn__conn__conn.get(o_conn__conn);
        Field f_connectionId = o_conn__conn__conn.getClass().getSuperclass().getDeclaredField("connectionId");
        f_connectionId.setAccessible(true);
        cid = f_connectionId.getLong(o_conn__conn__conn);
        f_connectionId.setAccessible(false);
        f_conn__conn__conn.setAccessible(false);
        f_conn__conn.setAccessible(false);

    } catch (Exception e) {
        e.printStackTrace();
    }
    return cid;
}

【讨论】:

  • @verystrongjoe )))) 它是一个 java,但它使用 java 不推荐(不受限制!!!)字符。所有你需要的 - 用'_'或任何你想要的替换'$'。好的。我自己做
  • 还有一个:我为 Jdbc4connection 类做的。
  • 谢谢。我会试试看。我正在制作应用程序监控解决方案。并且此代码将用于需要识别每个连接的地方。
  • 我收到此代码错误。找不到connectionId。它似乎已更改或具有其他字段名称。
  • @verystrongjoe 可以用另一种方式命名(如果是另一个 SDK)。好消息 - 您的案例中存在层次结构 Connection._conn._conn。尝试通过调试器查看字段
【解决方案2】:

编辑:

这样可以避免编译时耦合,使用反射

import java.sql.Connection;
import java.sql.DriverManager;
...
public String getMysqlConnectionId()
{
    try {
        Connection connection = DriverManager.getConnection("jdbc:mysql://host:3306/schema", "myuser", "mypassword");

        Class<?> clazz = Class.forName("com.mysql.jdbc.MySQLConnection");

        Object o = connection.unwrap(clazz);

        return (String) clazz.getMethod("getId").invoke(o).toString();
    } catch ( Exception e ) {
        return e.getMessage();
    }
}

通过将您的 java.sql.Connection 对象转换为 com.mysql.jdbc.MySQLConnection 并使用 getId()

import java.sql.Connection;
import java.sql.DriverManager;
import com.mysql.jdbc.MySQLConnection;
...
public long getMysqlConnectionId()
{
    Connection connection = DriverManager.getConnection("jdbc:mysql://host:3306/schema", "myuser", "mypassword");

    // would throw a ClassCastException in case this is not a mysql one, of course
    return ((MySQLConnection) connection).getId();
}

但这有点在编译时将您的项目与 MySQL 严重耦合

注意:当我为此投票时,我不会被冒犯,这是当之无愧的 ;-)

<!-- pom.xml -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>x.y.z</version>
</dependency>

其他一些人显然正在使用connection.unwrap(com.mysql.jdbc.MySQLConnection),这可能感觉更合适一些,但并未消除与com.mysql 的编译时耦合 https://github.com/prestodb/presto/issues/9425

【讨论】:

    【解决方案3】:

    这是我如何获取 Oracle SID 的示例:

        public int getConnectionSid() {
        try {
            if (connection == null || connection.isClosed())                
                return -1;            
            if (connectionSid == -1) {                
                try { 
                    Method method = connection.getClass().getDeclaredMethod("getSessionId", null);
                    method.setAccessible(true);
                    connectionSid = (Integer)method.invoke(nativeConnection, null);                    
                    method.setAccessible(false);
                } catch (NoSuchMethodException e) {
                    return -1;
                } catch (IllegalAccessException e) {
                    return -1;
                } catch (InvocationTargetException e) {
                    return -1;
                }
            }
            return connectionSid;
        } catch (SQLException e) {            
            return -1;
        }
    

    【讨论】:

    • 什么是原生连接?
    • nativeConnection 是 java.sql.Connection 对象。我忘了提到连接只是 java.sql.Connection 的一个包装器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-27
    • 2017-11-09
    • 2015-03-25
    • 2015-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多