둘러보기 생략.
 

쿼리서비스 사용시 listordredmap에서 date 타입 처리

쿼리서비스 사용시에 별도로 리턴 vo를 주지 않으면,

listordredmap으로 자동 컨버젼 되는데요.

이때 date type에 시간이 나오지가 않습니다. 날짜만 나오는것 같습니다. 시간은 0시 0분 0초 이렇게 표시됩니다.

혹시 어떤방식으로 처리하는지 알고 싶습니다.

감사합니다.

첨부 파일날짜파일 크기조회수최근 다운로드
jdbc-date-test.zip2010-06-227.33 MB413 주 2 일 전

Re] 쿼리서비스 사용시 listordredmap에서 date 타입 처리

별도 Result Mapping을 정의하지 않은 경우 QueryService는 ListOrderedMap의 List 형태로 결과를 리턴하게 됩니다. 그리고, 조회 결과 칼럼의 타입이 DATE일 경우 ListOrderedMap에 java.sql.Date 객체 형태로 저장되므로 Date 객체를 그냥 print할 경우 Date 객체 내에 구현된 toString()에 의해 YYYY-MM-DD 형태의 값만 추출되게 됩니다. 즉, 이것은 QueryService 처리 로직에 의해서가 아닌 Java Date 객체의 toString() 메소드 구현때문에 발생하는 것입니다.
만일 시,분,초도 같이 추출하시고자 하면 다음과 같은 2가지 방법을 사용할 수 있습니다.

  1. 쿼리문 정의시 DATE 타입의 칼럼에 대해 to_char를 이용하여 명시적으로 포맷 정의
  2. <query id="findUsersWithToChar" isDynamic="false">
        <statement>
            SELECT to_char(REG_DATE,'yyyy-mm-dd hh24:mi:ss') REG_DATE
    	FROM TBL_USERS
        </statement>
    </query>
    

    위와 같이 쿼리문을 정의하였을 경우 결과값 추출 로직은 다음과 같이 구성할 수 있습니다.

    // 1. 테스트 코드
    Collection results = queryService.find("findUsersWithToChar", new Object[] {});
    assertEquals(4, results.size());
    
    Iterator rtItr = results.iterator();
    while (rtItr.hasNext()) {
        ListOrderedMap map = (ListOrderedMap) rtItr.next();
        System.out.println(map.get("reg_date"));
    }
    // 2. 테스트 결과
    2009-01-20 12:57:04
    
  3. 해당 Date 객체로부터 getTime()을 이용하여 long 타입의 시간 정보(milliseconds) 추출 후 변경
  4. <query id="findUsers" isDynamic="false">
        <statement>
            SELECT REG_DATE FROM TBL_USERS
        </statement>
    </query>
    

    위와 같이 쿼리문을 정의하였을 경우 결과값 추출 로직은 다음과 같이 구성할 수 있습니다.

    // 1. 테스트 코드
    Collection results = queryService.find("findUsers", new Object[] {});
    assertEquals(4, results.size());
    
    Iterator rtItr = results.iterator();
    while (rtItr.hasNext()) {
        ListOrderedMap map = (ListOrderedMap) rtItr.next();
        System.out.println(((Date)map.get("reg_date")).getTime());
    }
    // 2. 테스트 결과
    1232377200000
    

두번째 방법의 경우 long 타입의 데이터(milliseconds)에서 계산을 통해 날짜 정보를 얻어내야 하는 로직이 추가되어야 하므로 첫번째 방법을 사용하시는 것이 간단하리라고 생각합니다.

추가 답변입니다.

Oracle에서 컬럼타입이 DATE인 경우, to_char를 이용하여 시,분,초도 같이 추출하실 수 있습니다.
컬럼타입이 TIMESTAMP인 경우, to_char 사용하지 않고 아래와 같은 방법을 통해 날짜와 시간 정보를 추출할 수 있습니다.

1. DateUtils 클래스에 아래와 같이 메소드를 정의하여 사용한다.
public static final String DATE_FORMAT_NOW = "yyyy-MM-dd HH:mm:ss";

public static String getTimeFromDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_NOW);
return sdf.format(date.getTime());
}

2. DAO 클래스에 아래와 같이 날짜와 시간 정보를 추출해 낸다.
Timestamp time = (Timestamp)map.get("releaseDate");
System.out.println(DateUtils.getTimeFromDate((Timestamp)map.get("releaseDate")));

첨부파일 참고

디폴트 쿼리 서비스나 리아 쿼리 서비스나 모두 Date type column으로부터 값을 읽어오는 경우,
시분초 정보를 가져올수가 없습니다.

이건 Anyframe 쿼리 서비스를 사용하지 않고 JDBC programming 을 통해 확인해봐도
동일한 현상입니다.
Timestamp type column으로부터 시분초 정보를 가져올수 있습니다.

첨부파일로 보내드리는 테스트케이스 내용을 참고하시기 바랍니다.

Gauce QueryService에서 시분초정보 나오는 이유

1. 디폴트 QueryService와 MiPlatform QueryService의 경우,
ResultSet의 db column type, 즉 Date type을 그대로 적용하여 값을 가져오기때문에 시분초 정보를 못가져 오는 것이 맞습니다.
(이게 정상적인 케이스입니다. )

2. GauceQueryService의 경우,
ResultSet의 db column type, 즉 Date type을 그대로 적용해서 값을 읽어오지 않고 Gauce 자체 type 정보를 통해 값을
가져오는데 이때 Date 타입에 해당하는 Gauce type이 없고, 디폴트로 적용된 String 타입으로 값을 읽어오게 됩니다.
(이게 비정상적인 케이스입니다.)

즉, 아까보내드린 테스트케이스에서 아래 부분처럼 getString type으로 읽어내면 시분초 정보가 나오게 됩니다.

System.out.println("DATE : " + rs.getDate(1).getTime());
System.out.println("DATE : " + rs.getString(1));

현재 Anyframe 4.x.x 버전부터는 GauceQueryService를 지원하지 않고 있습니다.
디폴트 QueryService와 MiPlatform QueryService의 경우와 같이 Date type인 경우 시분초 정보를 못읽어오는 것이
정상적이므로 시분초 정보가 필요한 경우 Timestamp 컬럼 타입을 사용하시기를 권고해드립니다.

감사합니다.