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 标签用于遍历传入的集合,属性如下:
- collection:指定要遍历的集合对象
- item:定义标识指向每次遍历时得到的对象
- open:开始遍历时要拼接的字符串
- close:结束遍历时要拼接的字符串
- 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>
测试程序同上。
原文地址:https://www.cnblogs.com/LiPengFeiii/p/15111519.html
- Cloudera Navigator介绍与安装
- [LeetCode]String主题系列{第5,6题}
- CDH内存调拨过度警告分析
- Ztorg:从 root 到 SMS
- [LeetCode]Math主题系列{第7,9,13,273题}
- 被忽视的攻击面:Python package 钓鱼
- [LeetCode]LinkedList主题系列{第2题}
- [LeetCode]HashTable主题系列{第3题}
- 如何使用Oozie API接口向Kerberos集群提交Java程序
- [LeetCode]Array主题系列{35,39,40,48题}
- 如何使用Sqoop2
- [LeetCode]Array主题系列{1,11,15,16,18,26,27,31,33,34题}
- Bwapp漏洞平台答案全解-A1(第三篇)
- pom.xml配置文件中所有标签及作用简单描述
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 2020-10-02:golang如何写一个插件?
- Kubernetes 1.19.0——健康性检查
- leetcode栈之用两个栈实现队列
- Ui Automator 框架和Ui Automator Viewer你会用吗?附送「必备adb命令」拿走不谢 !
- 3分钟短文:Laravel模型读数据的那个“障眼法”
- 你有一份面试题要查收
- @RequestParam,@RequestBody,@PathVariable注解区别
- linux centos 查看cpu是否开启超线程虚拟化和配置信息
- DDD领域驱动设计实战(三)- 理解实体
- 如何理解 Go 中的反射
- Kubernetes 1.19.0——网络
- 如何用VSCode实现一个vue.js项目?
- 网页轮播图案例
- leetcode栈之用队列实现栈
- 3分钟短文:无私分享!Laravel模型使用2个小技巧