Mybatis之旅第五篇-动态SQL
一、引言
在之前的CRUD例子中,都是一些很简单的SQL,然而实际的业务开发中会有一些复杂的SQL,我们经常需要拼接SQL,拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。Mybatis个一个强大特性--动态SQL,这一特性可以彻底摆脱这种痛苦。
二、if标签
现在有如下查询:
<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
WHERE sex = #{sex} AND username LIKE
'%${username}%'
</select>
当我们带入两个参数时,返回结果不会有问题,可是当我们只带入姓名,不带入性别时,结果就不合理,因为sex带入的null,作为查询条件就过滤了结果,这个时候我们需要if标签。
改造sql:
<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
WHERE 1=1
<if test="sex!=null and sex !=''">
AND sex = #{sex}
</if>
<if test="username!=null and username!=''">
AND username like
'%${username}%'
</if>
</select>
将接口和方法都加入其中
@Test
public void testQueryUserByWhere() {
// mybatis和spring整合,整合之后,交给spring管理
SqlSession sqlSession = this.sqlSessionFactory.openSession();
// 创建Mapper接口的动态代理对象,整合之后,交给spring管理
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 使用userMapper执行根据条件查询用户
User user = new User();
//user.setSex("1");
user.setUsername("张");
List<User>list = userMapper.queryUserByWhere(user);
for (User u : list) {
System.out.println(u);
}
// mybatis和spring整合,整合之后,交给spring管理
sqlSession.close();
}
结果:

三、where 标签
where标签会把第一个and忽略,当然如果是or开头的,MyBatis也会把它忽略,此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上。
<select id="queryUserByWhere1" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
<!-- where标签可以自动添加where,同时处理sql语句中第一个and或者or关键字 -->
<where>
<if test="sex!=null">
AND sex = #{sex}
</if>
<if test="username!=null and username!=''">
AND username like
'%${username}%'
</if>
</where>
</select>
四、set 标签
在更新的时候我们也需要像where一样能够进行动态判断,这个时候就使用set标签,set会使最后的逗号忽略,我们就可以动态的更新那些修改了的字段。
如下:
<update id="dynamicSetTest" parameterType="user">
update `user`
<set>
<if test="sex != null">
sex = #{sex},
</if>
<if test="username!=null and username!=''">
username = #{username},
</if>
</set>
where id = #{id}
</update>
测试:
@Test
public void dynamicSetTest() {
SqlSession sqlSession = this.sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
//user.setSex("1");
user.setUsername("袁大大");
user.setId(26);
userMapper.dynamicSetTest(user);
sqlSession.commit();
sqlSession.close();
}
五、choose(when,otherwise) 标签
choose的作用类似Java语言中的switch,可以解决我们只想选择一个查询条件的情况。
如下:
<select id="selectUserByChoose" resultType="user" parameterType="user">
select id, username, birthday, sex, address FROM `user`
<where>
<choose>
<when test="id !='' and id != null">
id=#{id}
</when>
<when test="username !='' and username != null">
and username like #{username}
</when>
<otherwise>
and sex=#{sex}
</otherwise>
</choose>
</where>
</select>
这个写法很容易理解,与switch相同,匹配成功后就会跳出。
六、trim 标签
trim标记是一个格式化的标记,可以完成set或者是where标记的功能,怎么用呢:
增加prefix前缀,去掉第一个prefixoverride中内容。
增加suffix后缀,去掉最后一个suffixoverride中内容。
通过trim可以解决where 与set 问题
<select id="selectUserByUsernameAndSex" resultType="user" parameterType="user">
select * from user
<!-- <where>
<if test="username != null">
username=#{username}
</if> <if test="username != null">
and sex=#{sex}
</if>
</where> -->
<trim prefix="where" prefixOverrides="and | or">
<if test="username != null">
and username=#{username}
</if>
<if test="sex != null">
and sex=#{sex}
</if>
</trim>
</select>
先增加where,并去掉第一个and 或者or ,替换了where if 写法。
<!-- 根据 id 更新 user 表的数据 -->
<update id="updateUserById" parameterType="com.ys.po.User">
update user u
<!-- <set>
<if test="username != null and username != ''">
u.username = #{username},
</if>
<if test="sex != null and sex != ''">
u.sex = #{sex}
</if>
</set> -->
<trim prefix="set" suffixOverrides=",">
<if test="username != null and username != ''">
u.username = #{username},
</if>
<if test="sex != null and sex != ''">
u.sex = #{sex},
</if>
</trim> where id=#{id}
</update>
增加set,并去掉最后一个逗号,替换了set if写法。
七、SQL片段
写sql时经常会出现一些重复片段,我们可以进行提取,这样可以做到重用。
先使用sql进行声明:
<!-- 声明sql片段 -->
<sql id="userFields">
id, username, birthday, sex, address
</sql>
使用include refid:
<select id="queryUserBySqlWhere" parameterType="user" resultType="user">
<!-- SELECT id, username, birthday, sex, address FROM `user` -->
<!-- 使用include标签加载sql片段;refid是sql片段id -->
SELECT <include refid ="userFields"/> FROM `user`
<!-- where标签可以自动添加where关键字,同时处理sql语句中第一个and关键字 -->
<where>
<if test="sex != null">
AND sex = #{sex}
</if>
<if test="username != null and username != ''">
AND username LIKE
'%${username}%'
</if>
</where>
</select>
八、foreach标签
当我们向sql传递数组或List,mybatis使用foreach解析。
foreach标签,进行遍历
collection:遍历的集合,这里是QueryVo的ids属性
item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致
open:在前面添加的sql片段
close:在结尾处添加的sql片段
separator:指定遍历的元素之间使用的分隔符
<select id="queryUserByIds" parameterType="com.yuanqinnan.pojo.QueryVo" resultType="user">
SELECT * FROM `user`
<where>
<foreach collection="ids" item="item" open="id IN (" close=")"
separator=",">
#{item}
</foreach>改造QueryVo:
@Data
public class QueryVo {
private User user;
private List<Integer> ids;
}测试方法:
@Test
public void queryUserByIds(){
SqlSession sqlSession = this.sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
QueryVo user = new QueryVo();
List<Integer>ids = new ArrayList<>();
ids.add(1);
ids.add(10);
ids.add(24);
user.setIds(ids);
List<User> list = userMapper.queryUserByIds(user);
for (User u : list) {
System.out.println(u);
}
sqlSession.close();
}结果

动态sql其实是一个拼接过程,我们掌握上面这些标签,就能完成mybatis的动态sql
Mybatis之旅第五篇-动态SQL的更多相关文章
- mybatis 详解(五)------动态SQL
前面几篇博客我们通过实例讲解了用mybatis对一张表进行的CRUD操作,但是我们发现写的 SQL 语句都比较简单,如果有比较复杂的业务,我们需要写复杂的 SQL 语句,往往需要拼接,而拼接 SQL ...
- Mybatis学习总结(五)——动态sql
MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦.拼接的时候要确保不能忘了必要的空格,还要注意省掉 ...
- MyBatis基础入门《十七》动态SQL
MyBatis基础入门<十七>动态SQL 描述: >> 完成多条件查询等逻辑实现 >> 用于实现动态SQL的元素主要有: > if > trim > ...
- Mybatis之旅第三篇-SqlMapConfig.xml全局配置文件解析
一.前言 刚换工作,为了更快的学习框架和了解业务,基本每天都会加班,导致隔了几天没有进行总结,心里总觉得不安,工作年限越长越感到学习的重要性,坚持下去!!! 经过前两篇的总结,已经基本掌握了mybat ...
- mybatis基础系列(三)——动态sql
本文是Mybatis基础系列的第三篇文章,点击下面链接可以查看前面的文章: mybatis基础系列(二)--基础语法.别名.输入映射.输出映射 mybatis基础系列(一)--mybatis入门 动态 ...
- MyBatis学习(三)、动态SQL语句
三.动态SQL语句 有些时候,sql语句where条件中,需要一些安全判断,例如按某一条件查询时如果传入的参数是空,此时查询出的结果很可能是空的,也许我们需要参数为空时,是查出全部的信息.使用Orac ...
- MyBatis知多少(25)动态SQL
使用动态查询是MyBatis一个非常强大的功能.有时你已经改变WHERE子句条件的基础上你的参数对象的状态.在这种情况下的MyBatis提供了一组可以映射语句中使用,以提高SQL语句的重用性和灵活性的 ...
- Java数据持久层框架 MyBatis之API学习七(动态 SQL详解)
对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...
- Mybatis之旅第六篇-关联查询
一.引言 通过动态SQL我们可以进行复杂SQL的编写,但之前的例子都是单表查询,在实际开发中,当然不可能都是单表,很多时候我们需要进行关联多表查询(有些公司为了性能还是尽量的使用单表查询),表与表之间 ...
随机推荐
- 终端字形logo
网上有很多的项目都有一个自己的字形logo,而我也在开发一个小的项目,也想要生成一个终端字形的logo,于是找到这款小工具,分享给大家:FIGlet “FIGlet is a program for ...
- Centos7下安装MySql
1.安装MariaDB 安装命令 yum -y install mariadb mariadb-server 安装完成MariaDB,首先启动MariaDB systemctl start maria ...
- Python入门、练手、视频资源汇总,拿走别客气!
摘要:为方便朋友,重新整理汇总,内容包括长期必备.入门教程.练手项目.学习视频. 一.长期必备. 1. StackOverflow,是疑难解答.bug排除必备网站,任何编程问题请第一时间到此网站查找. ...
- css 实现文字自动换行切同行元素高度自适应
1.实现div行内布局所有行跟随最大高度自适应 html代码样例: <div class="row-single"> <div class="colsp ...
- Maven学习(一)-- Maven入门
摘自:http://www.cnblogs.com/xdp-gacl/p/3498271.html 一.Maven的基本概念 Maven(翻译为"专家","内行" ...
- Java高并发之无锁与Atomic源码分析
目录 CAS原理 AtomicInteger Unsafe AtomicReference AtomicStampedReference AtomicIntegerArray AtomicIntege ...
- PHP开发基础知识
PHP的学习 PHP脚本以<?php 开始 ?>结束 <?php //此处写代码 ? > php默认文件扩展名.php php文件通常包含HTML标签以及一些PHP脚本代码 “ ...
- SSM-MyBatis-01:IDEA的安装,永久注册和简单的MyBatis用例
一,IDEA的安装和永久注册 1.安装: 那到安装包,下一步,选路径,上面可以选操作系统64/32位,下面是程序的默认打开方式,可以不必勾选,也可以全选 路径一定不包含中文,重点 2.永久注册: 将此 ...
- http请求 405错误 方法不被允许 (Method not allowed)
由于自己疏忽,导致请求错误405,然后前端数据传输没错,百度大都说跟post提交方式有关,改成get还是报错,检查才知道,controller中忘记写@requestMapping("/XX ...
- SSH概念及常用操作汇总
工作有一段时间了,经常用SSH登录远程机器,但对原理一直不是很了解,所以查阅了一些资料,写个小结. 一. SSH是什么? SSH的全称是Secure Shell, 是一种“用来在不安全的网络上安全地运 ...