mybatis中的动态SQL
在实际开发中,数据库的查询很难一蹴而就,我们往往要根据各种不同的场景拼接出不同的SQL语句,这无疑是一项复杂的工作,我们在使用mybatis时,mybatis给我们提供了动态SQL,可以让我们根据具体的业务逻辑来拼接不同的SQL语句。OK,那么我们今天就来看看如何使用mybatis中的动态SQL。
mybatis中的动态SQL主要包含如下几种元素:if、choose、when、otherwise、trim、where、set以及foreach几种,我们下面分别来看看这几种。
if
if是mybatis动态SQL中的判断元素,这个有点类似于Java中的if语句,不同的是这里的if一般常常和test配合使用。我们来看一个简单的例子:
<select id="getUser" resultMap="u" parameterType="String">
select * from user2
<if test="address!=null and address !=''">
WHERE address LIKE concat('%',#{address},'%')
</if>
</select>
当用户传入的address不为null或者空字符串的时候,我就加上一个where条件,否则就什么条件都不加入。然后我们再来看看我们在UserMapper这个接口中定义的相关方法:
public List<User> getUser(@Param("address") String address);
我们在调用这个方法的时候,如果传入了address参数,那么查询条件中就有address,否则就没有。来看看测试代码:
SqlSession sqlSession = null;
try {
sqlSession = DBUtils.openSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.getUser("西安");
for (User user : list) {
System.out.println(user);
}
sqlSession.commit();
} catch (Exception e) {
System.err.println(e.getMessage());
sqlSession.rollback();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
查询结果:
如果我将查询条件设为空字符串,如下:
SqlSession sqlSession = null;
try {
sqlSession = DBUtils.openSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.getUser("");
for (User user : list) {
System.out.println(user);
}
sqlSession.commit();
} catch (Exception e) {
System.err.println(e.getMessage());
sqlSession.rollback();
} finally {
if (sqlSession != null) {
sqlSession.close();
}
}
小伙伴们注意两个查询结果截图中打印出来的SQL语句的差异。
choose
choose有点类似于Java中的switch,常常配合when和otherwise一起来使用。我们来看一个简单的例子:
<select id="getUser2" resultMap="u">
SELECT * FROM user2 WHERE 1=1
<choose>
<when test="id!=null">
AND id=#{id}
</when>
<when test="address!=null">
AND address=#{address}
</when>
<when test="username!=null">
AND user_name LIKE concat(#{username},'%')
</when>
<otherwise>
AND 10>id
</otherwise>
</choose>
</select>
在查询条件中,如果用户传来了id,那么我就查询该id的数据,如果用户传来了address,那么我就我们添加address的查询条件,如果用户传来了username,那么我就添加username的查询条件,最后如果用户任何一个查询条件都没有添加进来,那么默认查询条件就是查询id小于10的所有数据。
where
在上面的案例中小伙伴们可能都发现了一个问题,就是我们在添加查询条件的时候,在查询条件之前都先添加了where 1=1,然后后面直接在这之后再追加and什么什么的,那么每次这样来写显然有点麻烦,有没有简单一点的方案呢?当然有,我们可以通过where元素,如下:
<select id="getUser3" resultMap="u">
SELECT * FROM user2
<where>
<choose>
<when test="id!=null">
AND id=#{id}
</when>
<when test="address!=null">
AND address=#{address}
</when>
<when test="username!=null">
AND user_name LIKE concat(#{username},'%')
</when>
<otherwise>
AND 10>id
</otherwise>
</choose>
</where>
</select>
这样,只有where元素中有条件成立,才会将where关键字组装到SQL中,这样就比前一种方式简单许多。
trim
trim有点元素替换的意思,还是上面的案例,我们可以将and替换为where,如下:
<select id="getUser4" resultMap="u">
SELECT * FROM user2
<trim prefix="where" prefixOverrides="and">
AND id=1
</trim>
</select>
这个最终执行的sql是SELECT * FROM user2 where id=1。
set
set是我们在更新表的时候使用的元素,通过set元素,我们可以逐字段的修改一条数据,如下:
<update id="update">
UPDATE user2
<set>
<if test="username!=null">
user_name=#{username},
</if>
<if test="password!=null">
password=#{password}
</if>
</set>
WHERE id=#{id}
</update>
在set元素中,如果遇到了逗号,系统会自动将之去除。
foreach
foreach元素用来遍历集合,比如我想查询多个城市的人,我的sql语句可能是这样SELECT * FROM user2 ,我在查询的时候可能只是传入了一个list集合,该集合中有西安和北京两个查询条件,那我如何将这个集合组装成一个sql语句呢?很简单,如下:
WHERE address IN('西安','北京')
<select id="getUserInCities" resultMap="u">
SELECT * FROM user2
WHERE address IN
<foreach collection="cities" index="city" open="(" separator="," close=")" item="city">
#{city}
</foreach>
</select>
collection表示传入的参数中集合的名称,index表示是当前元素在集合中的下标,open和close则表示如何将集合中的数据包装起来,separator表示分隔符,item则表示循环时的当前元素。这样一段配置最终组合成的sql就是SELECT * FROM user2 。
WHERE address IN('西安','北京')
bind
使用bind元素我们可以预先定义一些变量,然后在查询语句中使用,如下:
<select id="getUserByName" resultMap="u">
<bind name="un" value="username+'%'"></bind>
SELECT* FROM user2 WHERE user_name LIKE #{un}
</select>
这个貌似没什么难度,不再赘述。
以上。
本文案例下载:
本文案例GitHub地址https://github.com/lenve/JavaEETest/tree/master/Test27-mybatis9
以上。
参考资料:
《深入浅出MyBatis 技术原理与实战》第五章
关注公众号【江南一点雨】,专注于 Spring Boot+微服务以及前后端分离等全栈技术,定期视频教程分享,关注后回复 Java ,领取松哥为你精心准备的 Java 干货!

mybatis中的动态SQL的更多相关文章
- 【mybatis深度历险系列】mybatis中的动态sql
最近一直做项目,博文很长时间没有更新了,今天抽空,学习了一下mybatis,并且总结一下.在前面的博文中,小编主要简单的介绍了mybatis中的输入和输出映射,并且通过demo简单的介绍了输入映射和输 ...
- 6.Mybatis中的动态Sql和Sql片段(Mybatis的一个核心)
动态Sql是Mybatis的核心,就是对我们的sql语句进行灵活的操作,他可以通过表达式,对sql语句进行判断,然后对其进行灵活的拼接和组装.可以简单的说成Mybatis中可以动态去的判断需不需要某些 ...
- mybatis中的动态SQL语句
有时候,静态的SQL语句并不能满足应用程序的需求.我们可以根据一些条件,来动态地构建 SQL语句. 例如,在Web应用程序中,有可能有一些搜索界面,需要输入一个或多个选项,然后根据这些已选择的条件去执 ...
- mybatis中实现动态SQL
动态SQL语句,也就意味着SQL语句不在是一成不变的而是具有多样性. if if的用法还是跟平常差不多的(不过没有else if也没有else) <update id="modify& ...
- mybatis中的动态SQL(IF Chooes When Where Set ForEach SQL片段)
mapper: public interface BlogMapper { List<Blog> getBlogByIF(Map map); } IF <select id=&quo ...
- 阶段3 1.Mybatis_08.动态SQL_01.mybatis中的动态sql语句-if标签
创建新的工程 复制到新建的项目里面 pom.xml依赖部分复制过来 dao中整理代码 只保留四个查询 映射文件也只保留四个查询方法 增加一个根据条件查询的方法. 由于用了别名,所以parpameter ...
- mybatis 详解------动态SQL
mybatis 详解------动态SQL 目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when,o ...
- Mybatis映射文件动态SQL语句-01
因为在很多业务逻辑复杂的项目中,往往不是简单的sql语句就能查询出来自己想要的数据,所有mybatis引入了动态sql语句, UserMapper.xml <?xml version=" ...
- 使用CASE表达式替代SQL Server中的动态SQL
原文:使用CASE表达式替代SQL Server中的动态SQL 翻译自: http://www.mssqltips.com/sqlservertip/1455/using-the-case-expre ...
随机推荐
- 2019北航oo课程第二单元作业总结..#_#..
学习了之前在写代码是从来没有见过的多线程之后,便迎来了此次电梯作业.说实话,这次作业做得十分的辛苦,虽然在前三次作业中领悟到了java面向对象的精髓,但是再加上了多线程之后,又开始理不清思路,对自己的 ...
- ios12版本以上键盘唤起后,收回页面不回滚问题
最近提测后,发现ios升级到12版本之后,引发了调用确认框的组件之后按钮失效问题. 然后开始了升级复现bug的各种操作,最后发现是完成后键盘收起后,页面没有回滚,因为页面整体被推上了一定高度,导致错位 ...
- 如何使用$.each()与$().each()以及他们的区别
1.首先,说下$.each(Arry/Object,function(index,val){ //index表示下标,val表示下标对应的值 }) 下面是使用$.each()的几种类型,其中arr2与 ...
- 通配符的匹配很全面, 但无法找到元素 'context:property-placeholder' 的声明。
在Spring相应包导入正确的前提下,出现这个异常,是因为我们在引入命名空间的时候,没有正确引入它的DTD解析文件,以上面的context为例,解决办法如下: 在引入 xmlns:context=&q ...
- python学习:字典
字典 1.查询内存地址 a = 10 print(id(a)) b = a print(id(b)) b = 15 print(id(b)) 2. 数据类型 不可变类型:整型.字符串.元组 可变类型: ...
- Apache Maven入门篇(转)
[上篇] 写这个 maven 的入门篇是因为之前在一个开发者会的动手实验中发现挺多人对于 maven 不是那么了解,所以就有了这个想法.这个入门篇分上下两篇.本文着重动手,用 maven 来构建运行 ...
- linux mysql 安装
操作系统 Centos 7.2以上版本 操作系统 centos 7.2以上版本 mysql 版本 mysql-5.7.23-el7-x86_64.tar.gz 1.1 安装准备 1. 创建安装文件存 ...
- ubuntu解压时中文出现乱码
一.乱码类似这样的:╫╩┴╧╖┤╤▌▓т╒╛╦┘╢╚│ 今天遇到需要上传十几G的图片,在wins上压缩成zip格式,在上传到服务器上,结果出现乱码.然后各种百度心塞. 最初查到原因: 这个主要是因为z ...
- js计算指定日期的下一年的日期
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 一个开源的,跨平台的.NET机器学习框架ML.NET
微软在Build 2018大会上推出的一款面向.NET开发人员的开源,跨平台机器学习框架ML.NET. ML.NET将允许.NET开发人员开发他们自己的模型,并将自定义ML集成到他们的应用程序中,而无 ...