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传过来的值的方法,总共有两种方式,通过 $ ...
随机推荐
- oracle的表分区
(1.) 表空间及分区表的概念 表空间: 是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中,但主要存放的是表, 所以称作表空间. 分区表: 当表中的数据量不断增大,查询数据的速度就 ...
- OpenJudge计算概论-大象喝水
/*========================================================= 大象喝水 总时间限制: 1000ms 内存限制: 65536kB 描述 一只大象 ...
- opencv常见示例
1.批量转换灰度图并保存 #include <iostream> #include <opencv2/opencv.hpp> #include <string> u ...
- springboot 之JPA
1.添加pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...
- HTTP连接详解
- hadoop在windows上的配置文件
core-site.xml <configuration> <property> <name>hadoop.tmp.dir</name> <val ...
- zabbix3.4配置windowsAD登录
转载自:[https://zabbix.com/documentation/3.4/zh/manual/web_interface/frontend_sections/administration/a ...
- Docker镜像的构建(五)
目录 构建镜像 1.使用 commit 命令构建 1.1 运行一个要进行修改的容器 1.2 安装 Apache 软件包 1.3 提交定制容器 2.使用 Dockerfile 构建 2.1 我们的第一个 ...
- 【VS开发】Windows平台下Makefile学习笔记
作者:朱金灿 来源:http://blog.csdn.net/clever101 决心学习Makefile,一方面是为了解决编译开源代码时需要跨编译平台的问题(发现一些开源代码已经在使用VS2010开 ...
- 用Inno setup制作以管理员权限启动的安装包
inno setup制作的安装包,默认是不需要管理员权限启动的.我们制作安装包,往往需要做一些设置工作,这些设置工作可能用到管理员权限.使用Resource Hacker修改inno setup资源, ...