MyBatis学习笔记-06.MyBatis实现模糊查询的三种方式以及在MyBatis中#{}和${}的区别
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}%' 传递 字符串"元"
相当于'%'元'%',肯定是报错的
上一篇: mybatis中模糊查询的使用以及一些细节问题的注意事项
下一篇: 某表模糊查询