Mybatis 动态SQL

动态 SQL

MyBatis 的核心就是能够对 SQL 语句进行灵活的操作,甚至还可以通过表达式进行判断,对 SQL 语句进行灵活 的拼装,组成最终的想要执行的 SQL,这就是动态 SQL 的含义。 例如,在进行复杂查询时,查询条件可能是多个,也可能是一个,也就是说,查询条件不确定。需要根据查询条 件,来确定最终执行的 SQL 语句。

使用 mybatis 的动态 SQL 时,需要标签元素的支持,最常用的为 where 元素和 if 元素

  • mapper.xml
<select id="queryUserByItemName" parameterType="userVo" resultType="user"> select * from user join item on user.user_id=item.user_id <where> <if test="item!=null and item.name!=null and item.name!=''"> and item.name=#{item.name} </if> <if test="cname!=null and cname!=''"> and user.cname like #{cname} </if> </where> </select>

程序解析:配置动态 SQL 时,要用 where 标签转换成 where 关键字,不要把 where 关键字写死在 SQL 中,因 为如果 SQL 中的条件判断都不成立,就没有后面的过滤条件,如果 where 关键字写死在 SQL 语句中反而出错。而使 用 where 标签,由 MyBatis 框架在解析时判断是否需要在 SQL 中加入 where 关键字。 if 标签中的判断,首先判断是否不为 null,然后再判断是否不为空,判断空时使用两个单引号,并且单引号中间 不能有空格。过滤条件的拼接关键字 and、or 等一定要写死在 SQL 中,MyBatis 框架不会为 SQL 拼接 and、or 等 关键字,但是如果 where 关键字后出现了 and 或者 or 关键字,MyBatis 反而会去掉这个关键字。例如上面程序中, 第一个 if 判断成立,SQL 语句会变成 where and item.name=? ,此时 MyBatis 就会去掉这个关键字

引用 SQL 片段

在 mapper.xml 配置文件中,如果存在大量的复杂查询,而且查询条件相同,那么则可以把查询条件抽取成一个 SQL 片段,在其他 SQL中引用该片段即可。

  • mapper.xml 配置文件
<!-- 定义 SQL 片段 --> <sql id="userQuery"> <where> <if test="item!=null and item.name!=null and item.name!=''"> and item.name=#{item.name} </if> <if test="cname!=null and cname!=''"> user.cname like #{cname} </if> </where> </sql> <!-- 根据商品名称查询,引用 SQL 片段 --> <select id="queryUserByItemName" parameterType="userVo" resultType="user"> select * from user join item on user.user_id=item.user_id <include refid="userQuery" /> </select>

程序解析:通过 SQL 片段的定义,不仅可以减少 mapper.xml 配置文件的书写,而且方便程序人员的开发。

使用 foreach 遍历

在进行复杂 SQL 查询时,往往会遇到这样一种情况,对于某个列的值,好几个值都符合条件,使用 SQL 书写格 式如下:

where column='value1' or column='value2' or column='value3'

执行此 SQL 时传入的参数就需要是个集合,在 MyBatis 中,对于这种情况的处理,使用 foreach 元素解决。 foreach 标签用于遍历传入的集合,属性如下:

  1. collection:指定要遍历的集合对象
  2. item:定义标识指向每次遍历时得到的对象
  3. open:开始遍历时要拼接的字符串
  4. close:结束遍历时要拼接的字符串
  5. separator:遍历两个对象中间要拼接的字符串
  • Mapper 接口定义
public List<User> queryUserByIds(List<Integer> idList);
  • mapper.xml 配置文件
<select id="queryUserByIds" parameterType="list" resultMap="userMap"> select * from user <where> <foreach collection="list" item="value" separator=" or "> user_id=#{value} </foreach> </where> </select>
  • 测试程序:
@Test public void testQueryUserByIds() throws Exception{ List<Integer> idList = new ArrayList<>(); idList.add(13); idList.add(14); idList.add(15); UserMapper mapper = session.getMapper(UserMapper.class); List<User> userList = mapper.queryUserByIds(idList); for (User userObj : userList) { System.out.println(userObj.getCname()); } }

程序解析:如果 List 集合中不存在元素,上面 mapper.xml 配置文件中定义的 foreach 则不会执行,最终执行 的 SQL 为:select * from user。对上面的 SQL 进行更改为另一种格式,使用 in的方式 如下图所示:

  • mapper.xml 配置文件
<select id="queryUserByIds" parameterType="list" resultMap="userMap"> select * from user <where> <foreach collection="list" item="value" open="user_id in (" separator="," close=")"> #{value} </foreach> </where> </select>

测试程序同上。


__EOF__

本文作者飞飞很要强
本文链接https://www.cnblogs.com/LiPengFeiii/p/15111519.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   飞飞很要强  阅读(97)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示