MyBatis学习笔记-06.MyBatis实现模糊查询的三种方式以及在MyBatis中#{}和${}的区别

本文介绍了在MyBatis中实现模糊查询的三种方法,包括直接使用`like`,利用`concat`函数以及使用`${}`。同时详细阐述了`#{}`和`${}`的区别,`#{}`能防止SQL注入并自动进行类型转换,而`${}`则直接拼接SQL,不进行类型转换,可能导致SQL注入问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MyBatis进行数据库查询时,有的业务需要进行模糊查询,按我们正常的逻辑进行模糊查询,会发现这是个坑,现将问题以及实现方式整理如下:

本过程采用Log4j进行记录,y通过日志记录方便查看sql语句。Log4j配置请查看学习笔记05

环境搭建请参考之前的笔记,本过程对实现模糊查询的三种方式进行重点标注。

一、MyBatis实现模糊查询

在数据库中,我们书写模糊查询的sql为

select * from 某表 where 某字段 like '%某某某%'

查询 某表 中 某字段中 包含 某某某 的数据

本例我们以在学生表查询学生姓名中 包含 “元”的学生,按照上述sql书写方式进行书写

数据库stundet表结构如下:


student表内容如下:


映射文件内容为:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yuan.model.Student">
	<select id="queryByLikeName" parameterType="string" resultType="com.yuan.model.Student">
		select * from student where sname like '%#{sname}%'
	</select>
</mapper>

测试程序及结果:


毫无疑问报了异常,那原因是什么呢?这里我们暂不写原因,先说明解决方案,后介绍原因。

解决方案一、(贼low的方案,不推荐)

(1)修改映射文件中的sql为:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yuan.model.Student">
	<select id="queryByLikeName" parameterType="string" resultType="com.yuan.model.Student">
		select * from student where sname like #{sname}
	</select>
</mapper>

(2)修改测试程序为:


在前台手动给添加 %某某%,不推荐。(那写这条干啥?毕竟也是可以解决我们存在的问题)

解决方案二、使用sql指令的concat进行拼接【mysql、oracle可用,但需两次拼接,sql server 不可用,附大神写的sql指令concat介绍】本例使用mysql

(1)修改映射文件中的sql为:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yuan.model.Student">
	<select id="queryByLikeName" parameterType="string" resultType="com.yuan.model.Student">
		select * from student where sname like concat('%',#{sname},'%')
	</select>
</mapper>

(2)修改测试程序为:


当然 这种格式也是可以运行成功的,相当于直接拼接

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yuan.model.Student">
	<select id="queryByLikeName" parameterType="string" resultType="com.yuan.model.Student">
		select * from student where sname like "%"#{sname}"%"
	</select>
</mapper>
但不能使用单引号进行拼接,下面的情况是失败的

解决方案三、使用${}进行接值,注:不管有多少个参数需传入,传入参数的类型必须为map。

(1)修改映射文件中的sql为:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yuan.model.Student">
	<select id="queryByLikeName" parameterType="map" resultType="com.yuan.model.Student">
		select * from student where sname like '%${sname}%'
	</select>
</mapper>

(2)修改测试程序为:


二、在MyBatis中#{}和${}的区别

#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。

在我们使用#{}进行接值的时候,如果是string类型的值 则自动加上引号'',所以在上文中我们这么写

select * from student where sname like '%#{sname}%'   传递 字符串"元"

相当于'%'元'%',肯定是报错的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值