做一个积极的人

编码、改bug、提升自己

我有一个乐园,面向编程,春暖花开!

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

使用Springboot简单配置一下Mybatis,然后进行说明。Springboot集成Mybatis这里就不做介绍了。

初始数据

方式一

在Mybatis中的第一种写法:

 <!--有sql注入问题-->
<select id="findUserByLikeName1" parameterType="java.lang.String" resultMap="user">
select * from t_user where name like '%${name}%'
</select>

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

做了个简单的测试:

@Test
public void findUserByLikeName1(){
List<User> test = userMapper.findUserByLikeName1("Cloud");
//select * from t_user where name like '%Cloud%'
System.out.println(test.size());// 查出一条 List<User> test1 = userMapper.findUserByLikeName1("' or '1=1");
//select * from t_user where name like '%' or '1=1%'
// 分析: '1=1%' 成立
System.out.println(test1.size());// 查出了全部数据
}

注意:排序的字段也容易出现这个问题,在使用的时候也一定要注意。

order by ${orderBy}

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

方式二

在Mybatis中的第二种写法:

 <!--直接在代码中拼接%, 不存在sql注入-->
<select id="findUserByLikeName2" parameterType="java.lang.String" resultMap="user">
select * from t_user where name like #{name,jdbcType=VARCHAR}
</select>

在代码中加上%

@Test
public void findUserByLikeName2(){
String name = "Cloud";
List<User> test = userMapper.findUserByLikeName2("%" +name+"%");
// select * from t_user where name like ?
// %Cloud%(String)
System.out.println(test.size());
}

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

方式三

在Mybatis中的第三种写法:

 <!--concat Mysql和 Oracle区别 ,不存在sql注入-->
<select id="findUserByLikeName3" parameterType="java.lang.String" resultMap="user">
select * from t_user where name like concat('%',#{name,jdbcType=VARCHAR},'%')
</select>

测试:

@Test
public void findUserByLikeName3(){
String name = "Cloud";
List<User> test = userMapper.findUserByLikeName3(name);
// select * from t_user where name like concat('%',?,'%')
// Cloud(String)
System.out.println(test.size());
}

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

小注意

当使用方式三的时候,如果查询的关键字就是% ,那情况会是什么? 初始化数据中name有9条数据中包含%

查询的sql如下:

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

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

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

①在代码中进行转义

@Test
public void findUserByLikeName3(){
String name = "%";
name = name.replaceAll("_", "\\\\_");
name = name.replaceAll("%", "\\\\%"); List<User> test = userMapper.findUserByLikeName3(name);
System.out.println(test.size());
}

②使用ESCAPE

<select id="findUserByLikeName4" parameterType="java.lang.String" resultMap="user">
select * from t_user where name like concat('%',#{name,jdbcType=VARCHAR},'%') ESCAPE '/'
</select>

测试:

@Test
public void findUserByLikeName4(){
// replaceAll("%", "/%").replaceAll("_", "/_")
String name = "%";
List<User> test = userMapper.findUserByLikeName4(name);
System.out.println(test.size());// 查到全部
List<User> test1 = userMapper.findUserByLikeName4("/" +name);
System.out.println(test1.size());//查到匹配%的记录
}

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

小总结

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

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

2、上面这三种模糊查询,都是使用%关键字%,这种方式是不会走索引的,大数据量时候有查询效率问题

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

说明:网上有一些优化like的查询的,但是亲测后没啥用

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

1、业务上不允许输入这些字符,直接过滤(前台、后台过滤)

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

备注: 由于本人能力有限,文中若有错误之处,欢迎指正。

Mybatis中Like 的使用方式以及一些注意点的更多相关文章

  1. 2017年9月3日 Spring及Mybatis中连接数据库的不同方式

    连接数据库用spring和mybatis中使用的方法可以不同,mybaits可以不用写数据库的配置文件 Spring的连接方法 <!-- 读取属性文件(.properties)的内容 --> ...

  2. Mybatis中映射器实现方式总结

    一种是通过XML文件方式(由一个java接口和一个XML文件构成) RoleMapper rm = session.getMapper(RoleMapper.class); List<Role& ...

  3. mybatis中模糊查询的方式

    <!--Mapper.xml中如何进行模糊查询--> <sql id="brand_columns"> id, name, firstChar,brandN ...

  4. 【转】MyBatis中Like语句使用方式

    http://www.cnblogs.com/littleCode/p/3727476.html oracle数据库: SELECT * FROM user WHERE name like CONCA ...

  5. MyBatis中Like语句使用方式

    oracle数据库: SELECT * FROM user WHERE name like CONCAT('%',#{name},'%') 或 SELECT * FROM user WHERE nam ...

  6. MyBatis中的RowBounds

    myBatis中实现分页的方式是采用RowBounds这个类,用法如下,xml语句不变 传入两个参数,strat起始行, limit是当前页显示多少条数据,原理是RowBounds在处理分页时,只是简 ...

  7. MyBatis mapper文件中的变量引用方式#{}与${}的差别

    MyBatis mapper文件中的变量引用方式#{}与${}的差别 #{},和 ${}传参的区别如下:使用#传入参数是,sql语句解析是会加上"",当成字符串来解析,这样相比于$ ...

  8. MyBatis中主键回填的两种实现方式

    主键回填其实是一个非常常见的需求,特别是在数据添加的过程中,我们经常需要添加完数据之后,需要获取刚刚添加的数据 id,无论是 Jdbc 还是各种各样的数据库框架都对此提供了相关的支持,本文我就来和和大 ...

  9. mybatis中两种取值方式?谈谈Spring框架理解?

    1.mybatis中两种取值方式? 回答:Mybatis中取值方式有几种?各自区别是什么? Mybatis取值方式就是说在Mapper文件中获取service传过来的值的方法,总共有两种方式,通过 $ ...

随机推荐

  1. mac电脑如何快速显示桌面及切换应用

    使用mac电脑时,我们习惯打开很多应用,文档等等.如果打开应用非常多,需要操作桌面,却不知如何快速返回桌面和切换应用时,操作就非常不便了,下面简单介绍mac电脑系统如何快速显示桌面及切换应用? 工具/ ...

  2. OpenTK学习笔记(2)-工作窗口的三种方法创建方法(winfrom下类的形式创建)

    参考资料: https://www.codeproject.com/Articles/1167212/OpenGL-with-OpenTK-in-Csharp-Part-Initialize-the- ...

  3. 分享CSS3里box-shadow属性的使用方法,包括内阴影box-shadow:inset

    一.box-shadow语法 box-shadow: none | inset(可选值,不设置,为外投影,设置,为内投影) x-offset(阴影水平偏移量,正方向为right) y-offset(阴 ...

  4. Windows 自动定时执行任务的方法

    windows 自动定时执行任务的几种实现方法   Task Schedul Windows自动定时执行任务,常见的方法有三种: Windows 任务计划程序 Windows Service SQL ...

  5. 手把手教你MyEclipseUML建模(上)

    手把手教你MyEclipseUML建模(上) 转 https://blog.csdn.net/qq_37939251/article/details/83444359 1.用UML 1建模 MyEcl ...

  6. Android:修改连接到AP端显示的设备名

    一.Android系统代码中实现设备名分配 1. \frameworks\base\services\core\java\com\android\server\ConnectivityService. ...

  7. 网站url路径优化方法完全讲解 (url优化、基于tp5、API接口开发)

    url优化可是网站开发的必备高阶技能,先看本实例优化前后效果比较: (同为调用前台模块下的index控制器下的index方法) 优化前:www.tp5.com/tp5/public/index.php ...

  8. pyecharts绘画优美图形

    常用图形:柱形图-折线图-饼图-散点图 from pyecharts import Line, Bar, Pie, EffectScatter # 数据 attr =["衬衫", ...

  9. 【转】Selenium-xpath详解

    1.XPATH是什么 XPATH是一门在XML文档中查找信息的语言,XPATH可用来在XML文档中对元素和属性进行遍历,主流的浏览器都支持XPATH,因为HTML页面在DOM中表示为XHTML文档.X ...

  10. 【425】堆排序方法(二叉堆)优先队列(PQ)

    参考:漫画:什么是二叉堆? 大根堆 小根堆 参考:漫画:什么是堆排序? 参考:漫画:什么是优先队列? 参考:[video]视频--第14周10--第8章排序10--8.4选择排序3--堆排序2--堆调 ...