본문으로 바로가기

[자바]23. ResultSet 을 Java VO 타입 을 JSON 형식으로 변환하기

category Language/자바 2022. 1. 25. 18:41
728x90
반응형
SMALL

동료분의 참된 지식으로 인해 해당 문제를 돌파할수 있었다... 

그분께는 스타벅스 커피로 혼쭐을 내줘야겠다.

	List<TB_IF_FOIS002VO> list = new ArrayList();
    
	try(Connection conn = DbcpConnection.getConnection();
	  PreparedStatement psmt =conn.prepareStatement("SELECT * FROM TB_IF_FOIS002 LIMIT 1000")) 
      {
	  
	  ResultSet rs = psmt.executeQuery();
      
     	 while(rs.next()) { 
      	TB_IF_FOIS001VO vo =TB_IF_FOIS001VO.builder().idx(rs.getInt("idx"))
	 		 .flight_pk(rs.getString("flight_pk")) .sch_date(rs.getString("sch_date"))
	 		 .fp_id(rs.getString("fp_id")) 
             .build();
             list.add(vo);
     }
	  
	  } catch (Exception e) { e.printStackTrace();
	  logger.error("JDBC 쿼리문이 실패하였습니다."); 
      }finally { //closeJDBC(); } return list;
	  
	  }

SQL 에서 꺼내온 결과값을 ResultSet에 저장하고 미리 세팅해둔 FoisSendVO의 자바타입으로 변경하여 

배열에 넣는 작업을 하고있다.

ResultSet 의 결과물을 FoisSendVO 로 변환하는 과정에서 문제가 발생한다.

일일이 Builder 패턴 또는 자바Bean 패턴을 이용해서 필드의 개수만큼 직접 넣어줘야 하는 번거로움이 있다.

Builder 패턴
FoisSendVO.builder().seq(rs.getInt("seq")).unitSystemId(rs.getInt("unitSystemId"))....................

Bean 패턴
FoisSendVO vo = new FoisSendVO();
vo.setIdx(rs.getInt("idx"));
vo.setFlight_pk(rs.getInt("flight_pk"));
vo.setSch_date(rs.getInt("sch_date"));
vo.setFp_id(rs.getInt("fp_id"));
.
.
.

자바 VO의 필드의 개수가 적으면 문제가 없겠지만 개수가 몇백 단위로 많아진다면 문제가 생긴다.

개발자가 직접 코드에 기입해야되는 번거로움이 생긴다.

 

ResultSet의 결과물을 원하는 자바VO타입으로 전환해주는 함수를 이용하자

	  public void setField(Field field, ResultSet rs, Object targetObject) {
	        String type = field.getType().toString().toLowerCase();
	        if (type.contains(".")) {
	            type = type.substring(type.lastIndexOf('.') + 1, type.length());
	        }

	        try {
	            switch (type) {
	                case "integer":
	                    field.set(targetObject, rs.getInt(field.getName()));
	                    break;
	                case "double":
	                    field.set(targetObject, rs.getDouble(field.getName()));
	                    break;
	                case "localdatetime":
	                    Timestamp timestamp = rs.getTimestamp(field.getName());
	                    LocalDateTime localDateTime = timestamp.toLocalDateTime();
	                    field.set(targetObject, localDateTime);
	                    break;
	                default:
	                    //String
	                    field.set(targetObject, rs.getString(field.getName()));
	            }
	        } catch (Exception e) {
	            return;
	        }
	    }

필드 타입은 4가지로 생성해두었으며 이 외로 쓰이는 타입이 있으면 추가로 구현해주면 된다.

 

이전 while(rs.next()) 문 안에 달라진 코드를 확인해보자

	while(rs.next()) {
		TB_IF_FOIS001VO vo = new TB_IF_FOIS001VO();
		Field[] fields = vo.getClass().getDeclaredFields();
			for(Field field : fields) {
			      field.setAccessible(true);

			      setField(field, rs, vo);
			}
             System.out.println(mapper.writeValueAsString(vo));
                        
		    list.add(vo);          
    }

 

다른 받는 파트에서 해당 위의 코드인 getParsingData()를 사용하여 결과값을 확인해보면

List<TB_IF_FOIS001VO> list = foisDBConnection.getParsingData001();
logger.info(list.toString());
[TB_IF_FOIS001VO(idx=1, flight_pk=0, sch_date=b, fp_id=c, sch_time=null, eta=null, eta_date=null, etd_date=null, etd=null, ata_date=null, ata=null, atd_date=null, atd=null, sta_date=null, sta=null, ap_icao=null, fp_msg_type=null, ac_id=null, source=null, ac_type=null, ac_sub_type=null, reg_irr_cls=null, fp_link=null, shared_stat=null, fp_mst=null, int_dom_cls=null, nat=null, al_icao=null, al_iata=null, fp_iata=null, ap_dep_iata=null, ap_arr_iata=null, irr_code_kal=null, irr_code_aar=null, via01=null, via02=null, via03=null, via04=null, via05=null, via06=null, via07=null, via08=null, via09=null, via10=null, ssr=null, aftn_send_chk=null, fp_type=null, stand_arr=null, stand_dep=null, rway_arr=null, rway_dep=null, cancel_yn=null, div_yn=null, return_yn=null, upd_last_date=null, upd_last_id=null, status_remark=null, fp_rule=null, fpl_yn=null, ac_type_iata=null, ac_sub_type_iata=null, fp_no=null, ap_div=null, dep_msg_source=null, dep_status=null, arr_msg_source=null, arr_status=null, al_gd_pk=0, gd_agency=null, al_link=null, al_link_date=null)]

DB에 있는값을 자바VO타입으로 잘 매핑되서 출력되는것을 확인할수가 있다.

 

추가로

여기서 자바 VO타입을 JSON 형식으로 변경시켜줘보자.

List<TB_IF_FOIS001VO> list = foisDBConnection.getParsingData001();

ObjectMapper mapper =new ObjectMapper()
					.configure(SerializationFeature.INDENT_OUTPUT, true) //JSON 형식으로 이쁘게 나와라
					.setSerializationInclusion(JsonInclude.Include.NON_NULL); //NULL 값은 키값들은 제외해라 

logger.info(list.toString());

JSON 형식으로 예쁘게 잘 나온것을 확인할수가 있으며 NULL을 갖고있는 것들은 제외되었음을 확인해볼수 있었다.

{
  "idx" : 1,
  "flight_pk" : 0,
  "sch_date" : "b",
  "fp_id" : "c",
  "al_gd_pk" : 0
}
728x90
반응형
LIST