通过JDBC“ping”数据库的最佳方法是什么?

我正在尝试确定通过JDBC ping数据库的最佳方法。 “最好”是指快速和低开销。 例如,我考虑过执行此操作:

"SELECT 1 FROM DUAL" 

但我相信DUAL表是特定于Oracle的,我需要更通用的东西。

请注意, Connection有一个isClosed()方法,但javadoc声明这不能用于测试连接的有效性。

是的,这只是Oracle,但在JDBC中没有通用的方法。

大多数连接池实现都有一个配置参数,您可以在其中指定将用于ping的SQL,从而推动Responsiblity找出如何对用户执行此操作。

这似乎是最好的方法,除非有人为此提出一个小帮助工具(当然,它排除了使用可能更快的非基于SQL的方法,如Oracle的内部ping函数 )

使用JDBC 4,您可以使用Connection Interface中的isValid(int) ( JavaDoc )。 这基本上为您做了试用声明。

我也不知道通用的解决方案。 对于IBM在iSeries上的UDB(可能还有其他DB2系统),它将是

 select 1 from SYSIBM.SYSDUMMY1; 

您可以尝试从连接元数据中获取db名称并执行匹配的sql staement。 例如

 Connection con = null; Statement st = null; ResultSet rs = null; try { con = dataSource.getConnection(); String dbProductName = con.getMetaData().getDatabaseProductName(); Statement st = con.createStatement(); if ( "PostgreSQL".equalsIgnoreCase(dbProductName) ) { rs = st.executeQuery("select version();"); } else if ( "Oracle".equalsIgnoreCase(dbProductName) ) { rs = st.executeQuery("select 1 from dual"); } else { ... } } catch ( Exception ex ) { System.out.prinln("DB not reachable"); } finally { // close statement, connection etc. ... } 

我可能会在这个上午餐,但你可以简单地执行一些无意义的查询,例如:

 SELECT * FROM donkey_giraffe_87 

我不太了解JDBC的error handling,但也许您可以检查数据库是否至少告诉您该表不存在。 如果JDBC的错误代码是特定于供应商的,那么Spring Framework有一些实用程序可以将这些代码映射到更有意义的exception。

MySQL有一个很好的机制,在这个SO答案中有记录 。 从答案:

 "/* ping */ SELECT 1" 

这实际上会导致驱动程序向服务器发送ping并返回假的,轻量级的结果集。

话虽如此, @ eckes的答案是最好的(使用JDBC 4的Connection.isValid(int) )。

只需发出以下查询就足够了

 SELECT 1 

你能不能简单地执行

 SELECT 1 

没有针对大多数数据库的FROM子句?