首页 > 数据库 >多条件查询 (数据库字段数据逗号拼接)

多条件查询 (数据库字段数据逗号拼接)

时间:2022-09-30 18:47:11浏览次数:42  
标签:name IFNULL 数据库 逗号 拼接 subscribeName foreach login LIKE

问题描述:
源代码只有单一条件,即只需输入一个人名进行查找并返回结果即可,因此,只需要动态Sql同时使用like关键字,使用concat函数将%与动态数据拼接即可实现模糊查找功能。
仔细观察,这里的匹配为两种方式的匹配,即是否and该column取决于login_id或name的匹配,若两者之一满足条件(使用or关键字),那种这个数据就会最后显示出来,这一点也为我们后续的实现增加了难度。

  <!-- 原始查询   -->
            <if test="subscribeName.length != 0 and subscribeName!=null and subscribeName != 'null'">
                AND (IFNULL(s.login_id,'') LIKE
                    CONCAT('%',#{subscribeName},'%')
                OR IFNULL(l.name,'') LIKE
                    CONCAT('%',#{subscribeName},'%'))  
            </if>

  

原因分析:
首先我们从数据输入着手,观察接口可知原本为String类型的subscribeName,当多订阅人输入时,就变成了一个内部带英文逗号分隔的长字符串。为了保证可读性我们仍在xml文件中的sql语句修改。

要实现所有姓名的依次匹配,使用foreach进行一个遍历,遍历的数据来源为在foreach头部使用spilit将subscribeName分隔的数组。

在姓名分割时需要注意的是,如果用户错误输入了些空字段,要求我们具有健壮性依然能返回想要的结果,大致思想是replace方法或者trim方法,但实际上trim更优,我们后文讨论

解决方案:
方案一:foreach+in

在foreach中使用in来精准匹配,这是最开始想到的方法。虽然丧失了模糊查找的功能,但是这种方法最直观也容易理解,网上的资料也大多是使用in关键字。这种方法下我们使用两个foreach分别服务login_id和name。

<!--  使用in的查询   -->
            <if test="subscribeName!='' and subscribeName!=null and subscribeName != 'null'">
            and IFNULL(s.login_id,'')  in
            <foreach collection="subscribeName.split(',')" item="subscribeName" separator="," open="(" close=")">
                #{subscribeName}
            </foreach>
            or IFNULL(l.name,'')  in
            <foreach collection="subscribeName.split(',')" item="subscribeName" separator="," open="(" close=")">
                #{subscribeName}
            </foreach>
            </if>       

  

方案二: foreach+like+replaceAll

在每一轮遍历中,仍然使用concat拼接,进行模糊查找,使用两个foreach服务两个匹配方法,但不同之处在于foreach体的separator此时为or。
同时,我们在spilit分割前使用replaceAll将字符串中的所有空格去除掉

<!-- foreach内模糊查询like,同时使用replace除去所有空字段   -->
            <if test="subscribeName!='' and subscribeName!=null and subscribeName != 'null'">
                AND (IFNULL(s.login_id,'') LIKE
                <foreach collection="subscribeName.replaceAll('[\\[\\] ]','').split(',')" open="(" separator="or" close=")" item="subscribeName">
                    CONCAT('%',#{subscribeName},'%')
                </foreach>
                OR (IFNULL(l.name,'')) LIKE
                <foreach collection="subscribeName.replaceAll('[\\[\\] ]','').split(',')" open="(" separator="or" close=")" item="subscribeName">
                    CONCAT('%',#{subscribeName},'%'))
                </foreach>
            </if>     

  

方案三:foreach+like+trim

仔细想想,其实方案二的replaceAll存在不足之处,那就是我们在测试时往往只用随便随便起的名字,而实际上如果真的有外文名输入,那么空格若被一并去除,就会造成难以阅读的现象。
改进方法就是在每一轮foreach,使用trim将字段的首尾空格去掉即可。

<!-- 要在foreach语句里面使用trim    -->
            <if test="subscribeName!='' and subscribeName!=null and subscribeName != 'null'">
                AND (IFNULL(s.login_id,'') LIKE
                <foreach collection="subscribeName.split(',')" open="(" separator="or" close=")" item="subscribeName">
                    CONCAT('%',trim(#{subscribeName}),'%')
                </foreach>
                OR (IFNULL(l.name,'')) LIKE
                <foreach collection="subscribeName.split(',')" open="(" separator="or" close=")" item="subscribeName">
                    CONCAT('%',trim(#{subscribeName}),'%'))
                </foreach>
            </if>

 场景描述:

分页查询:复选框传多个查询条件,数据库字段说逗号拼接的  这种场景。

标签:name,IFNULL,数据库,逗号,拼接,subscribeName,foreach,login,LIKE
From: https://www.cnblogs.com/zhihongming/p/16745828.html

相关文章