欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-09 17:21:41
...

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

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

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

一、MyBatis实现模糊查询

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

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

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

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

数据库stundet表结构如下:

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

student表内容如下:

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

映射文件内容为:

<?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>

测试程序及结果:

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

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

解决方案一、(贼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)修改测试程序为:

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

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

解决方案二、使用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)修改测试程序为:

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

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

<?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>
但不能使用单引号进行拼接,下面的情况是失败的
MyBatis学习笔记-06.MyBatis实现模糊查询的三种方式以及在MyBatis中#{}和${}的区别

解决方案三、使用${}进行接值,注:不管有多少个参数需传入,传入参数的类型必须为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学习笔记-06.MyBatis实现模糊查询的三种方式以及在MyBatis中#{}和${}的区别

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

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

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

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

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

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