Mybatis高级查询
1.1. 需求
- 做员工高级查询,根据用户输入的条件来查询,通常需要动态的拼接SQL:
- 页面功能
<table border="1" align="center" cellspacing="0" width="400px"> <form action="跳转后台controller地址" method="post"> 员工姓名:<input type="text" name="name"> 员工年龄:<select name="ageIndex"> <option value="1">18以下(不包含18)</option> <option value="2">18-30(不包含30)</option> <option value="3">30-50(不包含50)</option> <option value="4">50以上(包含50)</option> </select> <input type="submit" value="查询"> </form> </table> |
3.目前传参可以直接使用名称来传递,但是如果后期条件增多,这种方式就不是太好,所以会封装一个查询条件的对象,还需要去准备一个带有条件的查询方法。例如:empQuery,findAll(empQuery,query)
1.2. 实现
- 准备一个条件查询的类
package cn.itsource.zy.query;
/** * 创建一个query包 * 设置需要查询的条件 * 员工查询对象 * 封装需要的查询条件 */ public class EmpQuery { //用于接收前端页面传递的参数 private String name; private Integer ageIndex; 提供get和set方法 } |
- 定义映射器接口,在接口中定义方法,并在service中定义,controller层调用
mapper:
service:
controller:
页面:
|
- 编写Mapper映射文件
<!-- 带有自定义条件的查询语句 empQuery 同样需要设置别名 在app...Con...xml中设置cn.itsource.zy.query --> <select id="findAll" parameterType="empQuery" resultType="Emp"> select * from emp <!--在下面添加查询的条件--> </select> |
- 完善查询条件
注意:
- <if>标签:
(1) 作用:
① 用于判断条件是否满足,满足就拼接sql,不满足不拼接
② 会自动加上空格,避免造成sql语法错误
<!-- 在下面添加查询的条件 需要判断有没有传递name这个参数,如果没有传递,则应该判断是否加条件 这是根据具体的条件查询 --> <if test="name!=null and name!=''"> where name=#{name} </if> |
(2) 注意:
① 如果参数是字符串类型,那么需要判断null和空字符串【去空白】;
② 如果参数是数值类型,只需要判断null值;
<if test='name != null and !"".equals(name.trim())'> where name=#{name} </if> |
- 模糊查询:
方案1:直接用#,日志中发现值并没有替换,所有不能直接使用#
and (name like '%#{keywords}%' or password like '%#{keywords}%')
方案2:使用$符号,测试成功,但是可能会出现SQL注入
and (name like '%${keywords}%' or password like '%${keywords}%')
方案3:用mysql中字符串拼接函数concat,测试成功,也不会出现SQL注入,建议使用
<!--模糊匹配查询-->
<if test="name!=null and name!=''">
where name like concat('%',#{name},'%')
</if>
- 如果有特殊符号:
(1) 在xml的转义字符:
① 符号:<【<】、<=【<=】、>【>】、>=【>=】、&【&】、'【'】 、 "【"】
② 【gt -> greater than(大于 )lt -> less than(小于)】
(2) 或者可以用CDATA代码段:
① 大于等于 <![CDATA[ >= ]]>
② 小于等于 <![CDATA[ <= ]]>
<!--当选项有多个是,需要判断,采用choose when--> <if test="ageIndex!=null"> <choose> <!-- 使用特殊符号表示大小于符号 如: < < > > --> <when test="ageIndex==1"> where age < 18 </when> <when test="ageIndex==2"> <![CDATA[where age >= 18 and age < 30]]> </when> </choose> </if> |
- <where>标签:
(1) 问题:以上拼接方式在多个条件时,会有多余的where条件,导致查询的语法错误,就使用where标签解决
(2) 作用:
① 拼接了一个where
② 忽略第一个多余的and 或者 or
③ 自动加空格
<where> <!--模糊匹配查询--> <if test="name!=null and name!=''"> <!--添加and表示多条件 但在使用where标签时,会自动省略,替换为where--> and name like concat('%',#{name},'%') </if> <if test="ageIndex!=null"> <choose> <when test="ageIndex==1"> and age < 18 </when> <when test="ageIndex==2"> <![CDATA[and age >= 18 and age < 30]]> </when> </choose> </if> </where> |
- 如果语句被多个地方调用可以使用<sql>抽取和<include>调用
(1) 使用<sql>抽取:
<sql id="address">
<if test='address != null and !"".equals(address.trim())'>
and address like CONCAT('%',trim(#{address}),'%')
</if>
</sql>
(2) 使用<include>调用:
<include refid="address"></include>
2. 将查询条件回显到前台页面展示
|
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?