通过mybatis提供的各种标签方法实现动态拼接sql。

  需求:根据性别和名字查询用户

  查询sql:

  SELECT id, username, birthday, sex, address FROM `user` WHERE sex = 1 AND username LIKE '%张%'

一、if标签

1.1 Mapper.xml文件

  UserMapper.xml配置sql,如下:

<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
WHERE sex = #{sex} AND username LIKE
'%${username}%'
</select>

1.2 Mapper接口

  /**
* 根据条件查询用户
* @param user
* @return
*/
List<User> queryUserByWhere(User user);

1.3 测试方法

  @Test
public void testQueryUserByWhere() throws Exception {
// mybatis和spring整合,整合之后,交给spring管理
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建Mapper接口的动态代理对象,整合之后,交给spring管理
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 使用userMapper执行根据条件查询用户
User user = new User();
user.setSex("男");
user.setUsername("张");
List<User> list = userMapper.queryUserByWhere(user);
for (User user2 : list) {
System.out.println(user2);
}
// mybatis和spring整合,整合之后,交给spring管理
sqlSession.close();
}

1.4 效果

  

  如果注释掉 user.setSex("男"),测试结果如下图:

  

  测试结果二很显然不合理。

  按照之前所学的,要解决这个问题,需要编写多个sql,查询条件越多,需要编写的sql就更多了,显然这样是不靠谱的。

  解决方案,使用动态sql的if标签

1.5 使用if标签

  改造UserMapper.xml,如下:

<!-- 根据条件查询用户 -->
<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>

1.6 效果

  

  测试OK

  注意:判断是否为空字符串时,单(双)引号里面不能填空格,否则会报错

  

二、Where标签

  上面的sql还有where 1=1 这样的语句,很麻烦

  可以使用where标签进行改造

  改造UserMapper.xml,如下

  <!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT id, username, birthday, sex, address FROM `user`
<!-- where标签可以自动添加where,同时处理sql语句中第一个前AND关键字 -->
<where>
<if test="sex!=null and sex != ' '">
AND sex = #{sex}
</if>
<if test="username!=null and username != ''">
AND username LIKE
'%${username}%'
</if>
</where>
</select>

三、sql片段

  Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的。

  把上面例子中的id, username, birthday, sex, address提取出来,作为sql片段,如下:

<!-- 声明sql片段 -->
<sql id="userFields">
id, username, birthday, sex, address
</sql> <!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
SELECT <include refid="userFields"/> FROM `user`
<!-- where标签可以自动添加where,同时处理sql语句中第一个前AND关键字 -->
<where>
<if test="sex!=null and sex != ' '">
AND sex = #{sex}
</if>
<if test="username!=null and username != ''">
AND username LIKE
'%${username}%'
</if>
</where>
</select>

  如果要使用别的Mapper.xml配置的sql片段,可以在refid前面加上对应的Mapper.xml的namespace

  

四、foreach标签

  向sql传递数组或List,mybatis使用foreach解析

  需求:根据多个id查询用户信息

  查询sql:SELECT * FROM user WHERE id IN (1,10,24)

4.1 改造QueryVo

public class QueryVo {
// 包含其他的pojo
private User user; private List<Integer> ids; get/set...
}

4.2 Mapper.xml文件

  UserMapper.xml添加sql:

<!-- 根据ids查询用户 -->
<select id="queryUserByIds" parameterType="queryVo" resultType="user">
SELECT * FROM `user`
<where>
<!-- foreach标签,进行遍历 -->
<!-- collection:遍历的集合,这里是QueryVo的ids属性 -->
<!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->
<!-- open:在前面添加的sql片段 -->
<!-- close:在结尾处添加的sql片段 -->
<!-- separator:指定遍历的元素之间使用的分隔符 -->
<foreach collection="ids" item="item" open="id IN (" close=")"
separator=",">
#{item}
</foreach>
</where>
</select>

4.3 Mapper接口

  在UserMapper接口中添加方法:

    /**
* 根据ids查询用户
* @param queryVo
* @return
*/
List<User> queryUserByIds(QueryVo queryVo);

4.4 测试方法

    @Test
public void testQueryUserByIds() throws Exception {
// mybatis和spring整合,整合之后,交给spring管理
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建Mapper接口的动态代理对象,整合之后,交给spring管理
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
QueryVo queryVo = new QueryVo(); List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(10);
ids.add(16);
queryVo.setIds(ids);
List<User> list = userMapper.queryUserByIds(queryVo);
for (User user : list) {
System.out.println(user);
} // mybatis和spring整合,整合之后,交给spring管理
sqlSession.close();
}

  效果:

  

Mybatis学习笔记(六) —— 动态sql的更多相关文章

  1. MyBatis:学习笔记(4)——动态SQL

    MyBatis:学习笔记(4)——动态SQL

  2. Mybatis学习笔记之---动态sql中标签的使用

    动态Sql语句中标签的使用 (一)常用标签 1.<if> if标签通常用于WHERE语句中,通过判断参数值来决定是否使用某个查询条件, 他也经常用于UPDATE语句中判断是否更新某一个字段 ...

  3. 1.3(Mybatis学习笔记)动态SQL

    一.<if> 使用<if>可以根据具体情况来拼接SQL语句,使其更加灵活更加适应我们的需求. <if>的标签体中是需要拼接的语句,满足条件才会将其进行拼接. < ...

  4. Mybatis学习笔记14 - 动态sql之foreach标签

    一.查询给定集合中员工id对应的所有员工信息 示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; import ...

  5. Mybatis学习笔记10 - 动态sql之if判断

    示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; import java.util.List; public ...

  6. Mybatis学习笔记13 - 动态sql之set标签

    示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; public interface EmployeeMapp ...

  7. Mybatis学习笔记12 - 动态sql之choose(when otherwise)标签

    choose (when, otherwise):分支选择:带了break的swtich-case 示例代码: 接口定义: package com.mybatis.dao; import com.my ...

  8. Mybatis学习笔记11 - 动态sql之trim标签

    trim标签体中是整个字符串拼串后的结果.prefix="" 前缀: prefix给拼串后的整个字符串加一个前缀prefixOverrides="" 前缀覆盖: ...

  9. MyBatis:学习笔记(4)——动态SQL

    MyBatis:学习笔记(4)——动态SQL 如果使用JDBC或者其他框架,很多时候需要你根据需求手动拼装SQL语句,这是一件非常麻烦的事情.MyBatis提供了对SQL语句动态的组装能力,而且他只有 ...

随机推荐

  1. Markdown编辑器及图床推荐

    Typora和自动图床工具 Typora 地址 ,极致简洁,界面很漂亮,最重要的是所见即所得 百度云搬运 密码:xi01 自动图床工具 需要七牛云做图床,感谢作者,详见博客 使用方法,只需两步即可完成 ...

  2. JavaScript toLowerCase() 方法

    定义和用法 toLowerCase() 方法用于把字符串转换为小写. 语法 stringObject.toLowerCase() 返回值 一个新的字符串,在其中 stringObject 的所有大写字 ...

  3. 关于c#里的集合的,结构体,枚举的定义,解释与应用

    那么先写一下 集合 . 集合和数组很相似,数组里的类型是必须同一类型,固定长度.然而集合里的可以是不同类型,不固定长度的.所以集合运用的灵活度要更高一些. 要使用集合,必须先引用命名空间:using ...

  4. iOS 隐藏App图标

    1.在进入Info.plist文件 2.在Info.plist文件中新添加一项,把Key值设置为SBAppTags,在Type选项中选取Array 3.在Array中新添加一项Item0,Type类型 ...

  5. 算法Sedgewick第四版-第1章基础-2.1Elementary Sortss-006归并排序(Mergesort)

    一. 1.特点 (1)merge-sort : to sort an array, divide it into two halves, sort the two halves (recursivel ...

  6. JavaPersistenceWithHibernate第二版笔记-第七章-003Mapping an identifier bag(@OrderColumn、@ElementCollection、@CollectionTable、、)

    一.结构 二.代码 1. package org.jpwh.model.collections.listofstrings; import org.jpwh.model.Constants; impo ...

  7. Java-马士兵设计模式学习笔记-工厂模式-简单工厂

    一.概述 1.目标:要控制任意类型交通工具的生产模式 2.目标有两层意思(1)任意类型 (2)生产模式,所以对应的,要这两个层面上抽象(Movable,VehicleFactory),利用接口,实现多 ...

  8. 100198H Royal Federation

    传送门 题目大意 国家有N个城市,任意城市可以到达任意城市,是一棵树.国王要给这些城市分省份.每个省份最少M个城市,最多3M个城市.每个省有一个首府,首府不一定是这个省的城市,只是首府到这个省各个城市 ...

  9. Git 之 github分享代码

    作为一个技术人员还是脱离不了屌丝的本质,所以每天都是逛逛github,看看别人有什么好的项目,自己可以给他挑挑bug也可以提供自己的水平,但是别人不那怎么才能给别人贡献代码呢?那就是fork了.... ...

  10. Java50道经典习题-程序48 数字加密

    题目:某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下:每位数字都加上5,然后用和除以10的余数代替该数字,再将第一位和第四位交换,第二位和第三位交换.分析:例如原始 ...