我正在尝试确定通过JDBC ping数据库的最佳方法。 “最好”的意思是快速和低开销。例如,我考虑过执行此操作:
"SELECT 1 FROM DUAL"
但我相信DUAL表是特定于Oracle的,我需要更通用的东西。
请注意,Connection
有一个isClosed()
方法,但javadoc声明这不能用于测试连接的有效性。
答案 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子句?