后端mySQL很容易犯的bug,bug记录解决

场景介绍

我的场景如下

用户可以根据前置课程,编程语言以及相关技术三个字段,以及是否只显示收藏来筛选论文。

且支持搜索功能。

这时候经常出现一个问题。

当搜索框输入内容且搜索时,功能一切正常。

但是当搜索框没有内容的时候,功能出现问题。

给大家看一下我的后端代码

XML 复制代码
    <select id="selectByFilter" resultMap="PaperResultMap">
        select distinct p.*, t.name as teacherName, t.address as teacherAddress,
        t.phone as teacherPhone, t.wechat as teacherWechat, t.qq as teacherQQ, t.email as teacherEmail,
        t.research_direction as teacherResearchDirection, t.avatar as teacherAvatar
        from `paper` p
        left join `paper-sys`.paper_course pc on p.id = pc.paper_id
        left join `paper-sys`.paper_language pl on p.id = pl.paper_id
        left join `paper-sys`.paper_technology pt on p.id = pt.paper_id
        left join `paper-sys`.teacher t on p.teacher_id = t.id
        <where>
            <if test="studentId != null">
                and p.id in (
                select paper_id from `collect` where student_id = #{studentId}
                )
            </if>
            <if test="courseIds != null and courseIds.size() > 0">
                and pc.course_id IN
                <foreach collection="courseIds" item="item" open="(" close=")" separator=",">#{item}</foreach>
            </if>
            <if test="languageIds != null and languageIds.size() > 0">
                and pl.language_id IN
                <foreach collection="languageIds" item="item" open="(" close=")" separator=",">#{item}</foreach>
            </if>
            <if test="technologyIds != null and technologyIds.size() > 0">
                and pl.language_id IN
                <foreach collection="technologyIds" item="item" open="(" close=")" separator=",">#{item}</foreach>
            </if>
            <if test="keyword != null">
                and t.name like concat('%', #{keyword},'%') or p.name like concat('%', #{keyword} , '%')
            </if>
            <if test="id != null">
                and p.id = #{id}
            </if>
        </where>
    </select>

问题分析

我想问题一定出在sql语句上面。

所以我试了一下把sql语句代入后,在数据库直接查询会出现什么结果。

这时候就看出来问题了。

去掉那些if标签的test时是这样

java 复制代码
WHERE (p.id in ( select paper_id from `collect` where student_id = ? ) and t.name like concat('%', ?,'%')) or p.name like concat('%', ? , '%')

在 SQL 里,AND 运算符的优先级高于 OR 运算符。

那么其实我的代码实际执行逻辑和我想象的是不一样的。

这就意味着,只要论文名称(p.name)符合关键字条件,无论 p.id 是否在指定学生收藏的论文 ID 列表里,该论文都会被查询出来,从而导致筛选 studentId 的条件失效。

解决方案

解决方案就非常简单了

只需要给扩上括号就好了。

所以大家在使用and和or的时候一定要注意。

否则可能会发生难以察觉的bug

相关推荐
冰茶丿3 分钟前
状态机在嵌入式系统中的应用:不只是switch-case这么简单
数据库·嵌入式硬件·mongodb
AIHR数智引擎5 分钟前
15%对撞40%:WEF白皮书里的AI组织隐忧
数据库·人工智能·经验分享·职场和发展·aihr
卓怡学长11 分钟前
w261springboot基于web学校课程管理系统
java·数据库·spring boot·spring·intellij-idea
嘉泰姆半导体官方14 分钟前
CXAR41337C 双通道数字音频功放 | 2×20W | EQ+DRC | I²S | MCLK-Less - 嘉泰姆电子
前端·javascript·数据库
不坑老师29 分钟前
怎么在Word中制作汉字书写笔顺——不坑盒子汉字笔顺步骤在小学低段识字教学中的应用
前端·数据库·人工智能·word·excel·office
苍狼唤1 小时前
SQL+C# 增删改查(练习)
数据库·sql·c#
2301_800256111 小时前
第七章 空间存储与索引 知识点梳理-2
数据库·sql·oracle
草莓熊Lotso1 小时前
【Redis 初阶】 从分布式演进背景到环境搭建全解析
数据库·人工智能·redis·分布式·缓存
倔强的石头_1 小时前
优化器为什么敢把你写的 LEFT JOIN 悄悄改掉?-国产化金仓 KES 优化器设计思路拆解
数据库
学习-学习1 小时前
PostgreSQL 19 Beta 值得测吗?并行 Autovacuum、REPACK 到 WAIT FOR LSN 看生产影响
数据库·postgresql