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

时间:2009-05-11 08:50:01

标签: java jdbc

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

"SELECT 1 FROM DUAL"

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

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

8 个答案:

答案 0 :(得分:13)

使用JDBC 4,您可以使用连接接口中的isValid(int)JavaDoc)。这基本上是为你做的试验声明。

某些驱动程序通过向数据库发送正确的伪SQL来实现此功能,而某些驱动程序直接使用低级操作来减少解析开销。

但是要注意超时,一些驱动程序(DB / 400和Oracle Thin)会为每次调用生成一个新的时间线程,这对于大多数池验证方案来说并不是真的可以接受。而Oracle似乎也没有使用预准备语句,所以它依赖于隐式缓存。

答案 1 :(得分:5)

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

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

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

答案 2 :(得分:4)

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

select 1 from SYSIBM.SYSDUMMY1;

答案 3 :(得分:3)

您可以尝试从连接元数据中获取数据库名称并执行匹配的sql staement。 E.g。

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.
   ...
}

答案 4 :(得分:2)

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

"/* ping */ SELECT 1"
     

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

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

答案 5 :(得分:0)

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

SELECT * FROM donkey_giraffe_87

我对JDBC的错误处理知之甚少,但也许您可以查看数据库是否至少告诉您该表不存在。如果JDBC的错误代码是特定于供应商的,那么Spring Framework有一些实用程序可以将这些代码映射到更有意义的异常。

答案 6 :(得分:-1)

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

SELECT 1

答案 7 :(得分:-1)

你能不能简单地执行

SELECT 1

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