gpt4 book ai didi

java - MyBatis 收集 Map.Entry 和 Map.entrySet() 时出错

转载 作者:行者123 更新时间:2023-12-01 21:47:54 24 4
gpt4 key购买 nike

假设我们有 MyBatis 3.3.0 和 MyBatis-Spring 1.2.3 以及一个简单的选择查询...

<select id="testSelect" parameterType="map" resultType="Integer">
select 1 from dual where
<foreach collection="properties" index="index" item="item" separator=" and ">
1 = #{id} AND 'a' = #{item.key,jdbcType=VARCHAR} AND 'b' = #{item.value,jdbcType=VARCHAR}
</foreach>
</select>

(如果给定的 id 为 1 并且集合中给定的所有关键属性均为“a”且所有值均为“b”,则应简单返回 1)

...这使得一个简单的TestMapper接口(interface)方法...

Integer testSelect(Map<String, Object> arguments);

...我们用这个测试方法对其进行测试...

@Test
public void test_for_bug() {

final Map<String, Object> parameters = new HashMap<>();
parameters.put("id", 1);

final Map<String, String> entries = new HashMap<>();
entries.put("a", "b");
parameters.put("properties", entries.entrySet());

final Integer result = this.testMapper.testSelect(parameters);

assertThat(result).isEqualTo(1);

}

...我们将收到以下错误...

Type handler was null on parameter mapping for property '__frch_item_0.value'. It was either not specified and/or could not be found for the javaType / jdbcType combination specified.

原因似乎是调用 item.value结果调用 value字符串本身的属性。不幸的是,我不知道为什么。

替换 entries.entrySet()Collection定制Entry对象(具有 keyvalue 属性)工作正常。同样奇怪的是:这似乎只发生在 <collection> 内,给出 Map.Entry直接作为参数,例如...

<select id="testSelect" parameterType="map" resultType="Integer">
select 1 from dual where 'b' = #{entry.value,jdbcType=VARCHAR}
</select>

...还有...

@Test
public void test_for_bug() {

final Map<String, String> entries = new HashMap<>();
entries.put("a", "b");

final Map<String, Object> parameters = new HashMap<>();
parameters.put("entry", entries.entrySet().iterator().next());

final Integer result = this.testMapper.testSelect(parameters);

assertThat(result).isEqualTo(1);

}

...有效。

有人知道 Map.EntrySet 的问题出在哪里吗?有机会以某种方式修复它吗?当然,创建解决方法很容易,但恕我直言,不需要它。

最佳答案

似乎处理此问题的正确方法(已提交文档更新)如下(因为开发人员在几个版本前进行了一些更改):

<select id="testSelect" parameterType="map" resultType="Integer">
select 1 from dual where
<foreach collection="properties" index="index" item="item" separator=" and ">
1 = #{id} AND 'a' = #{index,jdbcType=VARCHAR} AND 'b' = #{item,jdbcType=VARCHAR}
</foreach>
</select>

原因是 <foreach> Iterables 的行为有点不同/ArraysMaps (和 Iteratable<Map.Entry> 对象):

  • 对于 IterableArray , index是当前迭代的次数,item是本次迭代中从 Iterable 检索到的元素。
  • 对于 Map (或Iterable<Map.Entry>)index是当前条目的键,item 是当前条目的 value

这解释了为什么 item.value对于Map<String, String>实际上导致 String.value ( value 已经是 String - 它有一个名为 char array 的私有(private) value 成员,因此 MyBatis 尝试访问 String.value - 并失败,因为 char array 不是映射类型)。

关于java - MyBatis 收集 Map.Entry 和 Map.entrySet() 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35717551/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com