打印attrList的结果为:[{11=32}, {12=33}]
执行:
<select id="searchSkus" resultMap="SkuResultMap">
SELECT DISTINCT s.id, s.sku_name, s.price, s.sku_default_img
FROM sku s
INNER JOIN sku_attr_value sav ON s.id = sav.sku_id
<where>
s.is_deleted = 0
<if test="keyword != null and keyword != ''">
AND s.sku_name LIKE CONCAT('%', #{keyword}, '%')
</if>
<if test="tmId != null and tmId != ''">
AND s.tm_id = #{tmId}
</if>
<if test="attrList != null and !attrList.isEmpty()">
AND (
<foreach collection="attrList" item="pair" separator=" OR ">
(sav.attr_id = #{pair.key} AND sav.value_id = #{pair.value})
</foreach>
)
</if>
</where>
<choose>
<when test="order == '1:asc'">
ORDER BY s.id ASC
</when>
<when test="order == '1:desc'">
ORDER BY s.id DESC
</when>
<when test="order == '2:asc'">
ORDER BY s.price ASC
</when>
<when test="order == '2:desc'">
ORDER BY s.price DESC
</when>
<otherwise>
ORDER BY s.id
</otherwise>
</choose>
LIMIT #{offset}, #{pageSize}
</select>
之后,用idea的mybatis log插件打印出的sql语句为:
SELECT
DISTINCT s.id,
s.sku_name,
s.price,
s.sku_default_img
FROM
sku s
INNER JOIN
sku_attr_value sav
ON s.id = sav.sku_id
WHERE
s.is_deleted = 0
AND s.sku_name LIKE CONCAT('%', '手机', '%')
AND (
(
sav.attr_id = 11
AND sav.value_id = 32
)
OR (
sav.attr_id = 12
AND sav.value_id = 33
)
)
ORDER BY
s.id DESC LIMIT 0,
10;
但将
<if test="attrList != null and !attrList.isEmpty()">
AND (
(sav.attr_id = 11 AND sav.value_id = 32)
OR
(sav.attr_id = 12 AND sav.value_id = 33)
)
</if>
换为:
<if test="attrList != null and !attrList.isEmpty()">
AND (
<foreach collection="attrList" item="pair" separator=" OR ">
(sav.attr_id = #{pair.key} AND sav.value_id = #{pair.value})
</foreach>
)
</if>
之后,打印的sql语句却变成了:
SELECT
DISTINCT s.id,
s.sku_name,
s.price,
s.sku_default_img
FROM
sku s
INNER JOIN
sku_attr_value sav
ON s.id = sav.sku_id
WHERE
s.is_deleted = 0
AND s.sku_name LIKE CONCAT('%', ?, '%')
AND (
(
sav.attr_id = '手机'
AND sav.value_id = null
)
OR (
sav.attr_id = null
AND sav.value_id = null
)
)
ORDER BY
s.id DESC LIMIT null,
0,
10;
这个sql语句完全错了,为什么?难道
<if test="attrList != null and !attrList.isEmpty()">
AND (
(sav.attr_id = 11 AND sav.value_id = 32)
OR
(sav.attr_id = 12 AND sav.value_id = 33)
)
</if>
与
<if test="attrList != null and !attrList.isEmpty()">
AND (
<foreach collection="attrList" item="pair" separator=" OR ">
(sav.attr_id = #{pair.key} AND sav.value_id = #{pair.value})
</foreach>
)
</if>
不等价吗?还是attrList的格式需要更改?
想问下题主,这个attrList里面的对象类型是map吗?
控制台打印下实际的sql,应该很容易看出来是啥问题。
参考这个博客开启控制台sql
引用chatGPT作答,两个代码片段并不完全等价。在第一个代码片段中,SQL语句是硬编码的,检查特定的属性-值对,而在第二个代码片段中,属性-值对是通过foreach循环动态提供的。
根据你得到的第二个代码片段中空的“goodsList”响应,可能是“attrList”参数未正确传递到SQL语句。以下是几个可以检查的问题,以排除此问题:
1.确保在Java代码中正确定义了“attrList”参数,并将其传递给MyBatis mapper方法。
2.检查在传递给mapper方法时,“attrList”参数不为null或为空。
3.确保MyBatis mapper方法正确映射到包含foreach循环的SQL语句。
4.尝试打印MyBatis生成的SQL语句,以查看其是否基于“attrList”参数符合您的预期。
通过检查这些问题,您可能能够确定问题并解决第二个代码片段的问题。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
根据您提供的代码和打印的SQL语句,我认为出现错误的原因是attrList
的格式问题。
在第一个SQL语句中,我们可以看到attrList
是这样的:[{11=32}, {12=33}]
,可以看出是一个由Map组成的List。而在第二个SQL语句中,我们可以看到attrList
被换成了占位符(?
)的形式,也就是说,MyBatis会将它转换为一个含有占位符的字符串,然后再执行SQL语句。
因此,为了让第二个SQL语句能够正确执行,我们需要将attrList
的格式修改为一个List,每个元素是一个Map,其中key表示attr_id,value表示value_id。修改后的attrList
格式应该为:
[
{"key": 11, "value": 32},
{"key": 12, "value": 33}
]
然后在SQL语句中使用#{pair.key}
和#{pair.value}
来获取数据即可,如下所示:
<if test="attrList != null and !attrList.isEmpty()">
AND (
<foreach collection="attrList" item="pair" separator=" OR ">
(sav.attr_id = #{pair.key} AND sav.value_id = #{pair.value})
</foreach>
)
</if>
这样就能够正常执行SQL语句了。
如果我的回答解决了您的问题,请采纳!