【问题标题】:Get the connected mysql database name (JDBC)获取连接的mysql数据库名(JDBC)
【发布时间】:2014-12-13 23:57:33
【问题描述】:

如何从连接对象中获取数据库名称的名称

try {
    this.ds = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/amger");
} catch (NamingException ne) {
}
Connection conObj = ds.getConnection();

如何从 con 获取数据库名称

【问题讨论】:

  • @almasshaikh "如何从 java.sql.Connection 获取数据库 url?"永远不能与数据库名称相同
  • idea is from url 你能得到数据库名吗?

标签: java mysql jdbc


【解决方案1】:

如果您知道 DB 是 Mysql,您可以在连接上执行 SELECT DATABASE() 并读取其中包含当前数据库名称的结果集。

这里是 DATABASE 函数的description

【讨论】:

  • 您提到“如果您知道 DB 是 Mysql”。是什么让你这么说?
  • 感谢您的意见和指向与@Gord Thompson 方法相关的问题。当涉及到 mysql 时,您的解决方案是最好的。出于便携性的原因,我只接受 Gord Thompson,尽管我知道它可能产生的副作用。非常感谢兄弟
  • 不客气。我提到了“如果您知道 DB 是 Mysql”,因为任何 RDBMS 都可以连接到 JDBC 数据源,但是您的特定问题中有标签 mysql 并且 DATABASE() 是 mysql 特定的函数。我认为这个解决方案可能会有所帮助。
【解决方案2】:

假设您使用 url 作为“jdbc:mysql://localhost/test”

然后执行以下操作:

DatabaseMetaData dmd = connection.getMetaData();
String url = dmd.getURL();
System.out.println(url.substring(url.lastIndexOf("/") + 1));

【讨论】:

  • 如果使用use 命令或通过setCatalog() JDBC API 更改数据库,这将不起作用
  • 同意,但我不认为 OP 提到了同样的事情。
  • 这里的挑战是,虽然不幸的是,DatabaseMetaData 和 Connection 实现在 DB 驱动程序(例如 MySQL 和 Oracle)之间的实现不一致,但 JDBC(以及与 OP 问题更相关)的全部意义在于实现它抽象的(但仍然有效)......不幸的是,对于元数据......它只是不能始终如一地工作 - 需要一些逻辑与 getSchema()、getCatalog() 甚至 getUserName() 的组合。
【解决方案3】:

从 JDBC Connection 对象本身获取数据库名称的最直接的方法可能是通过getCatalog() 方法:

Connection#getCatalog()

但是,正如 Konstantin 在下面的评论中指出的那样,如果通过发出 USE dbname 语句更改当前 MySQL 数据库,则该值不会改变。

getCatalog() 在应用程序中可能仍然有用

  • 不更改数据库,或
  • 通过使用setCatalog() 更改当前数据库以“JDBC 方式”执行操作,

但对于 MySQL,使用 SELECT DATABASE() 总体上似乎更安全。

另请注意,getCatalog() 与实际当前数据库之间的这种潜在差异取决于特定 JDBC 驱动程序的行为。出于好奇,我尝试使用 Microsoft JDBC Driver 4.0 for SQL Server 进行类似的操作,.getCatalog() 确实在运行USE dbname 语句后立即意识到当前数据库的更改。也就是代码

String connectionUrl = "jdbc:sqlserver://localhost:52865;"
        + "databaseName=myDb;" + "integratedSecurity=true";
try (Connection con = DriverManager.getConnection(connectionUrl)) {
    System.out.println(String.format(
            "getCatalog() returns: %s", 
            con.getCatalog()));
    try (Statement s = con.createStatement()) {
        System.out.println("           Executing: USE master");
        s.execute("USE master");
    }
    System.out.println(String.format(
            "getCatalog() returns: %s", 
            con.getCatalog()));
} catch (Exception e) {
    e.printStackTrace(System.out);
}

产生了以下结果:

getCatalog() returns: myDb
           Executing: USE master
getCatalog() returns: master

【讨论】:

  • @Gord Thompson,我同意你的看法。归功于 Konstantin V. Salikhov 的亮点。我对 Konstantin V. Salikhov 方法(SELECT DATABASE())感觉更舒服,尤其是对于 MySQL 特定的解决方案。但是,正如您正确地说“做事”的 JDBC 方式“”; Connection#getCatalog() 将更容易被接受,这是 Java 的强项之一。
  • @KonstantinV.Salikhov 如果存在 JDBC 等效项 (setCatalog),这就是 JDBC api 文档明确表示不使用数据库命令(如 USE)的原因之一。
  • 很遗憾,跨数据库的 DatabaseMetaData 和 Connection 类的实现不一致。当 DatabaseMetaData 相关操作(如 getPrimaryKeys())需要模式名但 getCatalog() 有效(并可用作模式名)时,“getSchema()”的 MySQL“模式”名称为空。不幸的是,这对于 Oracle 来说并非始终如一。
【解决方案4】:

运行

System.out.println(connection.getMetaData().getURL());
  • 将输出粘贴到记事本中
  • 搜索 'databaseName=yourDBName' 的值

【讨论】:

    猜你喜欢
    • 2015-04-01
    • 2013-08-14
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    • 2016-03-09
    相关资源
    最近更新 更多