在 myBatis-mapping 中通过索引访问列表元素

Accessing list element by index in myBatis-mapping

我在myBatis中有如下映射

<update id="updatePersons" parameterType="Map">
    begin
    <foreach item="fname" collection="fnames" index="index" separator=";">
        update person set age = #{ages}[#{index}] where fname = #{fname}
    </foreach>;
    end;
</update>

它应该更新所有名字与作为参数传递的名字相匹配的人的年龄。

和Java中对应的调用:

Map<String, List<String>> map = new HashMap<>();
List<String> fnames = new ArrayList<>();
List<Integer> ages = new ArrayList<>();
map.put("fnames", fnames);
map.put("ages", ages);
session.update("person.updatePersons", map);

集合 fnamesages 的大小相同。我在 myBatis-mapping 中通过索引访问 ages 的元素有些困难。我已经尝试了括号,如第一个片段中所示。我也试过 #{ages}.get(#index) 但没有任何效果。有可能吗?

#{}PreparedStatement 中的占位符(即 ?),因此表达式 #{ages}[#index}] 被翻译为 ?[?],这不是有效的 SQL语法。
正确的语法是...

<update id="updatePersons">
  begin
  <foreach item="fname" collection="fnames" index="index" separator=";">
    update person set age = #{ages[${index}]} where fname = #{fname}
  </foreach>;
  end;
</update>

#{}${} 的区别见 FAQ entry


尽管在驱动程序支持该语法的情况下这可能有效,但它基本上是一个带有许多占位符的大 PreparedStatement,效率不高,尤其是当列表中有很多项目时。
如果是这种情况,您应该考虑使用批量更新。详情请参阅