簡體   English   中英

JDBC ResultSet 獲取帶有表別名的列

[英]JDBC ResultSet get columns with table alias

想象一下我有一個類似的查詢

SELECT * from table1 a, table2 b where (WHATEVER)

也許兩個表都有相同的列名。 所以我認為通過訪問數據會很好

resultSet.getString("a.columnName");
resultSet.getString("b.columnName");

但這對我適得其反,我一無所獲。 我閱讀了 API,但他們並沒有真正談論這個案例。 此類功能是否依賴於供應商?

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 使用基於一個的索引 - 即它們從1計數(而不是像 java 索引那樣從0 ),因此對第一列使用1 ,對第二列使用2 ,等等


我會推薦選項 1,因為引用命名列更安全:有人可能會更改查詢中列的順序,它會默默地破壞您的代碼(您將訪問錯誤的列但不知道),但如果他們更改列名稱,您至少會在運行時收到“無此類列”異常。

ResultSetMetadata.getColumnLabel() 就是你所需要的

(編輯)示例示例,如 bharal 在評論中所述

SELECT * from table1 a, table2 b where (WHATEVER)

ResultSetMetaData rsmd = rset.getMetaData();
rsmd.getColumnLabel(1);

使用列別名,如:

SELECT A.ID 'A_ID', B.ID 'B_ID' FROM TABLE1 AS A, TABLE2 AS B...

並指定您要檢索的所有列(這是一個很好的做法)。

如果您使用的是 MySQL,只需添加

&useOldAliasMetadataBehavior=true

到您的 connectionString。

之后你可以使用這個小助手:

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);
    }

}

好吧,似乎沒有像resultSet.getString("a.columnName");這樣的方法resultSet.getString("a.columnName"); 並且您必須在 sql 級別為您的列添加別名,但是由於有一個getTableName(iCol)方法,我希望java.sql.ResultSet添加這樣一個功能。

把你的sql改成

SELECT a.*, b.* from table1 a, table2 b where (WHATEVER)

比您可以通過表別名從結果集讀取

resultSet.getString("a.columnName");
resultSet.getString("b.columnName");

您可以在 SQL 級別使用別名。 然后按索引檢索數據。 (但這種方法會使維護成為真正的噩夢)

SELECT a.column, b.column FROM table1 a, table2 b

String value = rs.getString(1);

我的一個想法是使用getTableName(iCol)來獲取重復命名列的表名,然后包裝您自己的鍵的散列(帶有表名前綴),它將指向正確的列索引,並且以這種方式引用您的列值。 這將需要在開始時通過元數據進行初始循環以進行設置。 我看到的唯一問題是您還為表名設置了別名。 我還沒有找到一種從 jdbc 獲取這些表名別名的方法,而無需在構建 sql 語句時自己管理它。 這個解決方案將取決於你的語法回報。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM