如何在Mybatis中使用用户定义的Map

时间:2017-12-10 06:12:25

标签: java spring postgresql hashmap mybatis

我创建了一个实现Map的Class。这会将所有键转换为大写,并防止重复

public class UCaseMap<T> implements Map<String, T> { }

现在,每当我在Mybatis中使用它时,它都将该类视为POJO

<select id="selectQuestions" parameterType="map" resultType="com.quiz.utils.UCaseMap">

以下是错误消息

### Error querying database.  Cause: java.lang.IllegalArgumentException: No obj found for 'QUESTION_ID' available keys []
### The error may exist in file [D:\Development\Workspace\QuizCreator\target\classes\com\quiz\mapper\impl\QuizMapper.xml]
### The error may involve com.quiz.mapper.QuizMapper.selectQuestions
### The error occurred while handling results
### SQL: SELECT  QUESTION_ID, QUESTION, ANSWER_EXPLANATION,     CATEGORY, SUB_CATEGORY   FROM M_QUESTION   WHERE    DELETEFLAG = 0    AND CATEGORY = ?                       ORDER BY RANDOM()                  LIMIT ?
### Cause: java.lang.IllegalArgumentException: No obj found for 'QUESTION_ID' available keys [], mergedContextConfiguration = [MergedContextConfiguration@91161c7 testClass = TestQuizService, locations = '{classpath:dispatcher-servlet.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]], class annotated with @DirtiesContext [false] with mode [null], method annotated with @DirtiesContext [false] with mode [null].

你知道mybatis如何将该课程视为普通的地图吗?像这样:

<select id="selectQuestions" parameterType="map" resultType="map">

我正在使用:

  • mybatis 3.4.1
  • mybatis-spring 1.3.0
  • postgres 9.1-901-1.jdbc4
  • spring 4.3.2
  • java 8和tomcat 8

1 个答案:

答案 0 :(得分:0)

应该可行,我尝试了以下自定义地图实现:

public class CustomMap<T> extends HashMap<String, T>{

    @Override
    public boolean containsKey(Object key) {
        String uKey = key.toString().toUpperCase();
        return super.containsKey(uKey);
    }

    @Override
    public T put(String key, T value) {
        String uKey = key.toUpperCase();
        if ( containsKey(uKey)){
            return super.get(uKey);
        }else{
            return super.put(uKey, value);
        }

    }

}

以下select

    <select id="getCountriesAsCustomMap" resultType="info.sanaulla.model.CustomMap">
        SELECT 
            c.code,
            c.name,
            c.continent,
            c.region
        FROM country c
    </select>

我有一个JUnit测试:

@Test
public void test_getCountriesAsCustomMap(){
    List<Map<String, Object>> countries = countryService.getCountriesAsCustomMap();
    System.out.println(countries);
}

这给了我输出:

{
  CODE=AFG, CONTINENT=clob2: 'Asia', 
  NAME=clob1: 'Afghanistan', REGION=clob3: 'Southern and Central Asia'
}

所以自定义地图应该有用。