次のようなクエリがあると想像してください
SELECT * from table1 a, table2 b where (WHATEVER)
両方のテーブルの列名が同じである場合があります。だから私はそれを介してデータにアクセスするのはいいだろうが
resultSet.getString("a.columnName");
resultSet.getString("b.columnName");
しかし、これは私に裏目に出て、何も得られません。私はAPIを読みましたが、彼らは実際にこのケースについて話をしていません。そのような機能ベンダーは依存していますか?
JDBCは、クエリで指定された名前で列に名前を付けるだけです。テーブル名などはわかりません。
次の2つのオプションがあります。
オプション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の呼び出しの列positionを参照してください。
resultSet.getString(1);
resultSet.getString(2);
JDBC APIはone-basedインデックスを使用することに注意してください-つまり、1
からカウントします(0
からではなくJavaインデックス)、最初の列に1
、2番目の列に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);
}
}
OK、resultSet.getString("a.columnName");
のようなメソッドはないようで、SQLレベルで列にエイリアスを作成する必要がありますが、getTableName(iCol)
メソッドがあるので、Java.sql.ResultSet
そのような機能を追加します。
SQLレベルでエイリアスを使用できます。次に、インデックスによってデータを取得します。 (しかし、このアプローチはメンテナンスを本当に悪夢にします)
SELECT a.column, b.column FROM table1 a, table2 b
String value = rs.getString(1);
私が持っていた1つのアイデアは、getTableName(iCol)
を使用して重複する名前の列のテーブル名を取得し、正しい列を指す独自のキーのハッシュを(テーブル名のプレフィックスで)ラップすることですインデックスを作成し、列値をそのように参照します。これには、設定の開始時にメタデータを最初にループする必要があります。これに関して私が見る唯一の問題は、テーブル名もエイリアスしているということです。 sqlステートメントを作成するときに自分で管理せずにjdbcからこれらのテーブル名エイリアスを取得する方法をまだ見つけていません。この解決策は、構文上の見返りがどのようになるかによって異なります。