헤르메스 LIFE

[Springboot] Springboot 와 Mybatis 설정에서 resultType을 Map 으로 사용 시 문제점. 본문

Spring Boot Framework

[Springboot] Springboot 와 Mybatis 설정에서 resultType을 Map 으로 사용 시 문제점.

헤르메스의날개 2024. 7. 24. 17:21
728x90

개발환경

Springboot 

Mybatis 

JDK 11.x


<!-- src/main/resources/mapper/UserMapper.xml -->
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.group.package.mapper.UserMapper">

    <select id="selectUserRequest" resultMap="Map">
        SELECT id, name FROM users WHERE id = #{id}
    </select>

</mapper>

이와 같은 간단한 쿼리 실행 시 Map 에 담기는 값은 Database 마다 다릅니다.

Oracle, Tibero 는 key 가 대문자로 담기게 됩니다.

List<Map<String, Object>> userList = mapper.selectUserRequest();
for(int i = 0; i < userList.size(); i++) {
    HashMap userMap = (HashMap) userList.get(i);
    
    System.out.println("ID :: " + userMap.get("ID"));
    System.out.println("NAME :: " + userMap.get("NAME"));
}

MS-SQL 은 쿼리 Alias 로 key 가 생성됩니다.

List<Map<String, Object>> userList = mapper.selectUserRequest();
for(int i = 0; i < userList.size(); i++) {
    HashMap userMap = (HashMap) userList.get(i);
    
    System.out.println("ID :: " + userMap.get("id"));
    System.out.println("NAME :: " + userMap.get("name"));
}

PostgreSQL 은 key 소문자로 담기게 됩니다.

List<Map<String, Object>> userList = mapper.selectUserRequest();
for(int i = 0; i < userList.size(); i++) {
    HashMap userMap = (HashMap) userList.get(i);
    
    System.out.println("ID :: " + userMap.get("id"));
    System.out.println("NAME :: " + userMap.get("name"));
}

해결 방법은 

1. 전부 대문자 또는 소문자로 변경하는 방법

public class ParamMap extends ListOrderedMap {

    public Object put(String key, Object value) {
        return upperPut(key, value);
    }

    public Object lowerPut(String key, Object value) {
        // StringUtils.lowerCase 로 key값을 소문자로 변경
        return super.put(StringUtils.lowerCase(key), value);
    }
    
    public Object upperPut(String key, Object value) {
        // StringUtils.upperCase 로 key값을 대문자로 변경
        return super.put(StringUtils.upperCase(ke)), value);
    }
}

문제점은 추가적인 Map Class를 사용해야 한다는 겁니다.

2. org.apache.commons.collections4.map.CaseInsensitiveMap 를 사용하는 방법

<!-- src/main/resources/mapper/UserMapper.xml -->
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.group.package.mapper.UserMapper">

    <select id="selectUserRequest" resultMap="org.apache.commons.collections4.map.CaseInsensitiveMap">
        SELECT id, name FROM users WHERE id = #{id}
    </select>

</mapper>
List<CaseInsensitiveMap<String, Object>> userList = mapper.selectUserRequest();
for(int i = 0; i < userList.size(); i++) {
    CaseInsensitiveMap userMap = (CaseInsensitiveMap) userList.get(i);
    
    System.out.println("ID :: " + userMap.get("id"));
    System.out.println("NAME :: " + userMap.get("name"));
}

 

728x90