Derby作为一个纯Java实现的嵌入式DB一直很受Java社区的欢迎,在我们的项目中也用到了。但昨天晚上遇到的一个问题让我对Derby相当失望——Derby实现的ResultSet会将列名中的表名抹掉 具体代码: SQL:

SELECT staff.staffid FROM staff WHERE ...

JDBC:

ResultSet rs = stmt.executeQuery(...);
if(rs.next()){
    String id = rs.getString("staff.id");
}

运行时抛出异常:

Caused by: java.sql.SQLException: 列“staff.staffid”未找到。
	at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.Util.newEmbedSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedConnection.newSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.ConnectionChild.newSQLException(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedResultSet.findColumnName(Unknown Source)
	at org.apache.derby.impl.jdbc.EmbedResultSet.getString(Unknown Source)

如果将select语句中的“staff.staffid”改成“staffid”则不会抛出上述异常。在项目中为了保持数量庞大的SQL语句的正确性和可维护性,一般会将表名、列名定义为常量。这样对于Derby数据库就需要一套特殊的、不带表名的列名常量,给代码维护带来很大的麻烦。不知道Sun将Derby这样实现的原因是什么,这个功能点的实现也不是很麻烦,打算去提交bug