Mybatis中Like 的使用方式以及一些注意点
做一个积极的人
编码、改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 的使用方式以及一些注意点的更多相关文章
- 2017年9月3日 Spring及Mybatis中连接数据库的不同方式
连接数据库用spring和mybatis中使用的方法可以不同,mybaits可以不用写数据库的配置文件 Spring的连接方法 <!-- 读取属性文件(.properties)的内容 --> ...
- Mybatis中映射器实现方式总结
一种是通过XML文件方式(由一个java接口和一个XML文件构成) RoleMapper rm = session.getMapper(RoleMapper.class); List<Role& ...
- mybatis中模糊查询的方式
<!--Mapper.xml中如何进行模糊查询--> <sql id="brand_columns"> id, name, firstChar,brandN ...
- 【转】MyBatis中Like语句使用方式
http://www.cnblogs.com/littleCode/p/3727476.html oracle数据库: SELECT * FROM user WHERE name like CONCA ...
- MyBatis中Like语句使用方式
oracle数据库: SELECT * FROM user WHERE name like CONCAT('%',#{name},'%') 或 SELECT * FROM user WHERE nam ...
- MyBatis中的RowBounds
myBatis中实现分页的方式是采用RowBounds这个类,用法如下,xml语句不变 传入两个参数,strat起始行, limit是当前页显示多少条数据,原理是RowBounds在处理分页时,只是简 ...
- MyBatis mapper文件中的变量引用方式#{}与${}的差别
MyBatis mapper文件中的变量引用方式#{}与${}的差别 #{},和 ${}传参的区别如下:使用#传入参数是,sql语句解析是会加上"",当成字符串来解析,这样相比于$ ...
- MyBatis中主键回填的两种实现方式
主键回填其实是一个非常常见的需求,特别是在数据添加的过程中,我们经常需要添加完数据之后,需要获取刚刚添加的数据 id,无论是 Jdbc 还是各种各样的数据库框架都对此提供了相关的支持,本文我就来和和大 ...
- mybatis中两种取值方式?谈谈Spring框架理解?
1.mybatis中两种取值方式? 回答:Mybatis中取值方式有几种?各自区别是什么? Mybatis取值方式就是说在Mapper文件中获取service传过来的值的方法,总共有两种方式,通过 $ ...
随机推荐
- idea备忘
1.idea 最近打开的文件个数 File->Settings->Editor->General->Editor Tabs->Tab Closing Policy-> ...
- 3dmax联机分布式渲染方法技巧详解
3dmax联机分布式渲染方法技巧详解 \测试环境:win7系统 3DMAX2009 Vray2.0 .首先要保证你的两台电脑能在局域网里互相访问如图: 其他电脑上也一样都能打开对方的电脑! 步! ...
- Java打印素数(质数)
要求:打印 2 - 100000 当中的素数与非素数.(素数定义:在大于1的自然数中,除了1和它本身以外不再有其他因数) 1. 常规方式——对正整数n,如果用2到 之间的所有整数去除,均无法整除,则 ...
- PyTorch Tutorials 2 AUTOGRAD: AUTOMATIC DIFFERENTIATION
%matplotlib inline Autograd: 自动求导机制 PyTorch 中所有神经网络的核心是 autograd 包. 我们先简单介绍一下这个包,然后训练第一个简单的神经网络. aut ...
- 阶段5 3.微服务项目【学成在线】_day18 用户授权_06-方法授权-方法授权测试-无权限异常处理
现在没权限返回的信息 控制台抛出的异常是这个 : 不允许访问,这是Spring Security跑出来的 我们在异常处理器里面打个断点看一下 重新测试,就跳转到了异常捕获类这里. 这是异常的类型 这里 ...
- LeetCode_27. Remove Element
27. Remove Element Easy Given an array nums and a value val, remove all instances of that value in-p ...
- swift 屏幕的翻转 + 状态栏(statusBar)的隐藏
1.状态栏的隐藏 这个问题是基于 UIApplication.shared.isStatusBarHidden = true; 调用居然是无效的…… 现在写下自己的代码,用来备忘吧…… 1.首先需要复 ...
- 生成count位随机数工具类
工具类 import java.util.Random; /** * 生成6位随机数字 */ public class GeneratorCode { /** * * @Title: getCode ...
- 波特词干(Porter Streamming)提取算法无代码单纯理解
最近写东西提到这个算法,要看一下,结果网上都是直接根据代码解释,对于我这种菜鸟在刚开始看一个算法的时候真心不想直接看代码学.奈何都是各种语言的代码,么得办法.先走了一遍,有了大致的了解,翻译成自己的话 ...
- vue-cli2和vue-cli3同时存在
https://blog.csdn.net/Jioho_chen/article/details/90455778 win下 vue-cli2 和 vue-cli3 并存,一起使用开局一张图,内容慢慢 ...