programing

JDBC ResultSet 테이블 별칭이 있는 열을 가져옵니다.

newnotes 2023. 3. 26. 11:46
반응형

JDBC ResultSet 테이블 별칭이 있는 열을 가져옵니다.

이런 질문이 있다고 상상해 보세요

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(출처 없음)0java index 등)를 사용합니다.1첫 번째 열에 대해2제2열 등에 대하여


이름 있는 열을 참조하는 것이 더 안전하기 때문에 옵션 1을 권장합니다.다른 사용자가 쿼리의 열 순서를 변경하여 코드가 자동으로 끊어질 수 있습니다(잘못된 열에 액세스하고 있지만 알 수 없음). 그러나 열 이름을 변경하면 실행 시 최소한 "그런 열 없음" 예외가 발생합니다.

ResultSetMetadata.getColumnLabel()이 필요합니다.

(편집) 바랄이 코멘트에 기재한 샘플 예시

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");또한 컬럼의 에일리어스를 SQL 레벨로 지정해야 합니다.단, 이 컬럼에는getTableName(iCol)내가 원하는 방법java.sql.ResultSet이러한 기능을 추가합니다.

SQL 수준에서 별칭을 사용할 수 있습니다.그런 다음 인덱스로 데이터를 가져옵니다.(그러나 이 접근 방식은 유지보수를 정말 어렵게 만듭니다.)

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

String value = rs.getString(1);

제가 생각한 한 가지 아이디어는getTableName(iCol)중복된 이름의 열의 테이블 이름을 가져오려면 올바른 열 인덱스를 가리키는 자체 키의 해시(테이블 이름 접두사)를 래핑하고 열 값을 참조합니다.이렇게 하려면 처음에 메타데이터를 통한 초기 루프가 필요합니다.여기서 유일하게 볼 수 있는 문제는 테이블 이름에도 에일리어스를 붙이고 있다는 것입니다.sql 문을 작성할 때 직접 관리하지 않고 jdbc에서 테이블 이름 별칭을 가져올 수 있는 방법을 아직 찾지 못했습니다.이 솔루션은 구문적으로 얻을 수 있는 이익에 따라 달라집니다.

SQL을 다음과 같이 변경합니다.

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

테이블 에일리어스에 의해 리설셋에서 읽을 수 있는 것보다 더 큰 값입니다.

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

언급URL : https://stackoverflow.com/questions/7224024/jdbc-resultset-get-columns-with-table-alias

반응형