SELECT Result Set의 컬럼 순서를 지키며 반환 받는 법

kai6666·2022년 12월 23일
0

TIL. Java

목록 보기
21/21

문제

SELECT 구문으로 테이블의 데이터를 불러오는 로직을 짰는데, 모든 데이터가 불러오지기는 하나 포스트맨의 Response 내용을 보면 알 수 있듯 칼럼의 순서가 뒤죽박죽인 문제가 생겼다. 서치를 해보니 스택오버플로우에 이 현상에 관한 질문이 이미 있다.

https://stackoverflow.com/questions/17229418/jsonobject-why-jsonobject-changing-the-order-of-attributes

답변 내용과 JSON 공식 문서를 보면,

  • JSONObject: 순서 없이 값을 저장함
  • JSONArray: 순서를 지키며 값을 저장함

기존의 구현 코드를 보면 아래와 같다.

Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql);
int colCount = rs.getMetaData().getColumnCount();
JSONArray resultSet = new JSONArray();
try {
	while (rs.next()) {
	JSONObject obj = new JSONObject();
    	for(int i = 1; i <= colCount; i++) {
			System.out.println(rs.getMetaData().getColumnName(i) + rs.getString(i));
			obj.put(rs.getMetaData().getColumnName(i), rs.getString(i));
		}
		resultSet.put(obj);
	}

데이터베이스의 row를 전부 for문으로 칼럼 순서대로 JsonObject에 담고, 하나의 row를 전부 담으면 JSONArray에 담는다. 이런 방식이기 때문에 row의 순서는 지켜지는데, 각각의 칼럼에 상응하는 값은 JSONObject에 담았기 때문에 순서가 지켜지지 않았던 것이다.


해결

Request로 받는 SELECT 쿼리는 데이터베이스내 어떤 테이블이든 구문을 수행할 수 있어야 하고, 반환되는 데이터의 양도 정해져 있지 않다. 따라서 rs.getString(컬럼명,값)과 같은 방식으로 반환 값을 직접 설정하는 방법은 기각이다. 이 로직이 요구하는 사항은

  • 키-밸류 구조로 저장 가능하여야 한다.
  • 순서가 지켜져야 한다.
  • 복수 건의 데이터를 한 번에 반환해야 하기 때문에 길이가 자유로이 늘었다 줄 수 있어야 한다.

위의 점들을 고려했을 때, 각 ResultSet은 키-밸류로 값을 저장하고 입력 순서를 지켜주는 LinkedHashMap에 담고 이것들을 한꺼번에 반환하기 위해 ArrayList에 담기로 하였다. 수정한 코드는 아래와 같다.

Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(sql);
int colCount = rs.getMetaData().getColumnCount();
List<LinkedHashMap> resultSet = new ArrayList<LinkedHashMap>(){};
try {
	while (rs.next()) {
	LinkedHashMap map = new LinkedHashMap();
    	for(int i = 1; i <= colCount; i++) {
			System.out.println(rs.getMetaData().getColumnName(i) + rs.getString(i));
			map.put(rs.getMetaData().getColumnName(i), rs.getString(i));
		}
		resultSet.add(map);
	}


결과

위와 같이 로직을 변경해주니 데이터베이스의 칼럼과 행 순서를 따르는 쿼리 결과를 받아볼 수 있었다.

profile
성장 아카이브

0개의 댓글