Spring Boot 中Mybatis使用Like的使用方式和注意点

说明

模糊查询在项目中还是经常使用的,本文就简单整理Mybatis中使用Like进行模糊查询的几种写法以及一些常见的问题。

使用Springboot简单配置一下Mybatis,然后进行说明。Springboot集成Mybatis这里就不做介绍了,这里我们主要介绍一下在mybatis配置文件中怎么使用模糊查询。

本地表数据

具体方式

方式一

在Mybatis中的写法:

XML 复制代码
    <select id="queryLists"  parameterType="java.lang.String" resultMap="BaseResultMap">
        select * from stuinfo
        where 1=1
        <if test="name != null and name != ''">
            AND name like '%${name}%'
        </if>
        order by id desc
    </select>

输出以下语句:

这种会有sql注入的问题,需要明白在 Mybatis中 $ 和 # 使用的区别。这种写法也不能加jdbcType=VARCHAR,否则也会报错。

注意:这种方式在实际开发过程中千万要注意,不要写成这样了。

方式二

在Mybatis中的写法:

XML 复制代码
    <select id="queryLists"  parameterType="java.lang.String" resultMap="BaseResultMap">
        select * from stuinfo
        where 1=1
        <if test="name != null and name != ''">
            AND name like #{name,jdbcType=VARCHAR}
        </if>
        order by id desc
    </select>

在代码中加上%

java 复制代码
    @GetMapping("/lists")
    @ResponseBody
    public List<StuInfo> lists(String name){
        return stuInfoService.getLists('%'+name+'%');
    }

输出以下语句:

这种方式在一些项目中也会看到。如果没有使用如Mybatis等ORM框架,直接写sql查询就这样拼接了。

第一种方式和第二种方式基本上一致

方式三

在Mybatis中的写法:

XML 复制代码
    <select id="queryLists"  parameterType="java.lang.String" resultMap="BaseResultMap">
        select * from stuinfo
        where 1=1
        <if test="name != null and name != ''">
            AND name like concat('%', #{name}, '%')
        </if>
        order by id desc
    </select>

输出以下语句:

说明:在实际开发中推荐使用这种方式。

方式四

在Mybatis中的写法:

XML 复制代码
    <select id="queryLists"  parameterType="java.lang.String" resultMap="BaseResultMap">
        select * from stuinfo
        where 1=1
        <if test="name != null and name != ''">
            and POSITION(#{name} IN name) > 0
        </if>
        order by id desc
    </select>

以上写法是在postgresql中的函数:POSITION(#{name} IN name) 在mysql中 请使用: INSTR(name, #{name}) > 0

输出以下语句:

需要注意

当使用方式三的时候,如果查询的关键字就是%, get 请使用%25 url编码 ,那情况会就会变成什么呢! 初始化数据中name有6条数据中包含%。

查询的sql如下:

select * from stuinfo where name like concat('%','%','%')

查出来全部的数据,并不是只包含了%的数据,如果查询也是一样的。

那这种情况肯定是不满足查询需求的,则需要调整。

解决以上问题

代码中处理:

java 复制代码
    @GetMapping("/lists")
    @ResponseBody
    public List<StuInfo> lists(String name){
        name = name.replaceAll("_", "\\\\_");
        name = name.replaceAll("%", "\\\\%");
        return stuInfoService.getLists(name);
    }

在Mybatis中的写法:

XML 复制代码
    <select id="queryLists"  parameterType="java.lang.String" resultMap="BaseResultMap">
        select * from stuinfo
        where 1=1
        <if test="name != null and name != ''">
            AND name like concat('%',#{name,jdbcType=VARCHAR},'%') ESCAPE '\'
        </if>
        order by id desc
    </select>

输出以下语句:

以上两种本质都是对查询的关键字进行了处理,这种处理在代码中可以使用拦截器或者AOP等技术统一处理。

总结

1、不要写方式一的这种模糊查询,容易发生sql注入!

建议使用第三种方式进行模糊查询

2、上面这前三种模糊查询,都是使用%关键字%,这种方式是不会走索引的,大数据量时候有查询效率低,第四中使用字符串包含函数。

看情况,可以使用全文索引;或者使用ES进行

3、注意关键词中有%、_ 这些特殊字符如何处理。

1、业务上不允许输入这些字符,需要通过(前台、后台)进行过滤。

2、使用上面的ESCAPE或者转义。

相关推荐
indexsunny几秒前
互联网大厂Java求职面试实战:基于电商场景的技术问答及解析
java·spring boot·redis·kafka·security·microservices·面试指导
马克Markorg19 分钟前
SpringBoot + LangChain4j 打造企业级 RAG 智能知识库,多工具集成方案
spring boot·向量数据库·rag·qdrant·langchain4j·增强知识检索库
Forget_855039 分钟前
RHEL——LVS模式
java·开发语言·lvs
渣瓦攻城狮1 小时前
互联网大厂Java面试:从数据库连接池到分布式缓存及微服务
java·redis·spring cloud·微服务·hikaricp·数据库连接池·分布式缓存
罗超驿1 小时前
13.1 万字长文,深入解析--抽象类和接口
java·开发语言
A懿轩A1 小时前
【Java 基础编程】Java 面向对象进阶:static/final、抽象类、接口、单例模式
java·开发语言·单例模式
lifallen1 小时前
后缀数组 (Suffix Array)
java·数据结构·算法
逆境不可逃2 小时前
LeetCode 热题 100 之 76.最小覆盖子串
java·算法·leetcode·职场和发展·滑动窗口
I_LPL2 小时前
day35 代码随想录算法训练营 动态规划专题3
java·算法·动态规划·hot100·求职面试
百锦再2 小时前
Java中的日期时间API详解:从Date、Calendar到现代时间体系
java·开发语言·spring boot·struts·spring cloud·junit·kafka