JDBC ResultSet 获取具有表别名的列
Posted
技术标签:
【中文标题】JDBC ResultSet 获取具有表别名的列【英文标题】:JDBC ResultSet get columns with table alias 【发布时间】:2011-11-05 15:28:50 【问题描述】:想象一下我有一个类似的查询
SELECT * from table1 a, table2 b where (WHATEVER)
可能两个表具有相同的列名。所以我认为通过
访问数据会很好resultSet.getString("a.columnName");
resultSet.getString("b.columnName");
但这适得其反,我什么也得不到。我阅读了 API,但他们并没有真正谈论这个案例。这样的功能供应商是否依赖?
【问题讨论】:
【参考方案1】:JDBC 将通过查询中指定的内容简单地命名列 - 它不知道表名等。
你有两个选择:
选项1:在查询中以不同的方式命名列,即
SELECT
a.columnName as columnNameA,
b.columnName as columnNameB,
...
from table1 a, table2 b where (WHATEVER)
然后在您的 java 代码中引用列别名:
resultSet.getString("columnNameA");
resultSet.getString("columnNameB");
选项 2:在调用 JDBC API 时参考列位置:
resultSet.getString(1);
resultSet.getString(2);
注意 JDBC API 使用 one-based 索引 - 即它们从 1
开始计数(不像 java 索引那样从 0
开始计数),所以在第一列使用 1
,@ 987654327@ 第二列等
我会推荐选项 1,因为引用命名列更安全:有人可能会更改查询中列的顺序,它会默默地破坏您的代码(您将访问错误的列但不知道),但如果他们更改列名,您至少会在运行时获得“没有这样的列”异常。
【讨论】:
好吧,看来我将不得不忘记漂亮的 * 并命名所有内容并使用额外的映射。【参考方案2】:ResultSetMetadata.getColumnLabel() 是你需要的
(编辑) 示例示例,如 bharal 在评论中所述
SELECT * from table1 a, table2 b where (WHATEVER)
ResultSetMetaData rsmd = rset.getMetaData();
rsmd.getColumnLabel(1);
【讨论】:
你可以通过示例代码 sn-p 编辑答案 使用 SQLite JDBC 驱动程序,这只会给我列名,例如username
,而不是完整的 a.username
。有没有办法得到a
,表别名?【参考方案3】:
使用列别名,例如:
SELECT A.ID 'A_ID', B.ID 'B_ID' FROM TABLE1 AS A, TABLE2 AS B...
并指定您要检索的所有列(这是一个很好的做法)。
【讨论】:
【参考方案4】:如果您使用的是 mysql,只需添加
&useOldAliasMetadataBehavior=true
到您的连接字符串。
之后你就可以使用这个小助手了:
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
public class ResultSetHelper
private final Map<String, Integer> columnMap;
public ResultSetHelper(ResultSet rs) throws SQLException
this.columnMap = new HashMap<>();
ResultSetMetaData md = rs.getMetaData();
int columnCount = md.getColumnCount();
for (int index = 1; index <= columnCount; index++)
String columnName = md.getColumnLabel(index);
if (!columnMap.containsKey(columnName))
columnMap.put(columnName, index);
String tableAlias = md.getTableName(index);
if (tableAlias != null && !tableAlias.trim().isEmpty())
columnMap.put(tableAlias + "." + columnName, index);
public Integer getColumnIndex(String columnName)
return columnMap.get(columnName);
public Integer getColumnIndex(String tableAlias, String columnName)
return columnMap.get(tableAlias + "." + columnName);
【讨论】:
【参考方案5】:好的,好像没有resultSet.getString("a.columnName");
这样的方法
你必须在 sql 级别为你的列加上别名,
但因为有一个 getTableName(iCol)
方法我希望大家
java.sql.ResultSet
添加这样的功能。
【讨论】:
【参考方案6】:您可以在 SQL 级别使用别名。 然后通过索引检索数据。 (但这种方法会使维护成为一场真正的噩梦)
SELECT a.column, b.column FROM table1 a, table2 b
String value = rs.getString(1);
【讨论】:
【参考方案7】:我的一个想法是使用getTableName(iCol)
来获取重复命名列的表名,然后包装您自己的键的散列(带有表名前缀),它将指向正确的列索引,并以这种方式引用您的列值。这将需要在开始时通过元数据进行初始循环来设置。我看到的唯一问题是您也在给表名起别名。我还没有找到一种从 jdbc 获取这些表名别名的方法,而无需在构建 sql 语句时自行管理。这个解决方案将取决于你的语法回报。
【讨论】:
@Bohemian - 您可以使用 ResultSetMetaData::getTableName(int) 函数来获取表名。不过,我不确定结果是否取决于 jdbc 实现。 docs.oracle.com/javase/7/docs/api/java/sql/…【参考方案8】:把你的sql改成
SELECT a.*, b.* from table1 a, table2 b where (WHATEVER)
你可以通过表别名从resulset中读取
resultSet.getString("a.columnName");
resultSet.getString("b.columnName");
【讨论】:
以上是关于JDBC ResultSet 获取具有表别名的列的主要内容,如果未能解决你的问题,请参考以下文章
在Postgres中加入两个表后如何为具有相同名称的列提供别名