Mybatis - итерация ключа / значения HashMap, который принадлежит ArrayList - PullRequest
0 голосов
/ 03 июля 2019

У меня есть проект, который должен обрабатывать персонал динамической сортировки для SQL.

Я пытаюсь использовать список карт, который содержит комментарии сортировки, с помощью которых можно сохранить порядок сортировки и цели сортировки

Java-код: часть сортировки комманд:

List<Map<String, String>> sort = new ArrayList<>();

// the key is the field of table which i want to sort
// and the value here is the sort order (asc/desc) 
Map<String, String> map1 = new HashMap<>();
map1.put("publish_time", "desc");
sort.add(map1);

Map<String, String> map2 = new HashMap<>();
map2.put("id", "asc");
sort.add(map2);

Часть Mapper

List<Doc> selectByQuery(DocParam param, Paging paging, List<Map<String, String>> sort);

XML-код: первая попытка:

select * from doc
where
1 = 1
<if test="sort != null and sort.size() > 0">
      order by
      <trim suffixOverrides=",">
        <foreach collection="sort" item="item" >
          <foreach collection="item" index="key" item="value" separator=",">
            #{key} #{value}
          </foreach>
        </foreach>
      </trim>
    </if>

вторая попытка:

<if test="sort != null and sort.size() > 0">
      order by
      <trim suffixOverrides=",">
        <foreach collection="sort" item="item" >
          <foreach collection="item.keys" item="key" open=" " close=" " separator=" " >
            <![CDATA[   ${key} #{item[${key}]}   ]]>
          </foreach>
        </foreach>
      </trim>
    </if>

окончательная версия sql, которую я предполагаю построитьmybatis выглядит примерно так:

select * from doc
where 1 = 1
order by
publish_time desc,
id asc

, но появляются следующие сообщения об ошибках: при первой попытке:

org.springframework.jdbc.UncategorizedSQLException: 
### Error querying database.  Cause: java.sql.SQLException: sql injection violation, syntax error: syntax error, error in :'rder by
       ? ?', expect QUES, actual QUES pos 381, line 31, column 10, token QUES : 
select * from doc
where 1 = 1
order by
? ? ,
? ?

при второй попытке:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'item' not found. Available parameters are [param, paging, sort, param3, param1, param2]
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:77)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
    at com.sun.proxy.$Proxy96.selectList(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:230)
    at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:139)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:76)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)

1 Ответ

0 голосов
/ 03 июля 2019
  • Эти значения должны быть выведены как литералы, поэтому вы должны использовать ${}. См. FAQ .
  • separator выводится между каждым элементом, поэтому вам нужно указать separator="," для обоих <foreach /> и не нужно <trim />.
  • Поскольку HashMap не поддерживает порядок входа, вы должны использовать LinkedHashMap.
order by
<foreach collection="sort" item="item" separator=",">
  <foreach collection="item" index="key" item="value"
    separator=",">
    ${key} ${value}
  </foreach>
</foreach>
...