Mybatis学习笔记(六) —— 动态sql
通过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的更多相关文章
- MyBatis:学习笔记(4)——动态SQL
MyBatis:学习笔记(4)——动态SQL
- Mybatis学习笔记之---动态sql中标签的使用
动态Sql语句中标签的使用 (一)常用标签 1.<if> if标签通常用于WHERE语句中,通过判断参数值来决定是否使用某个查询条件, 他也经常用于UPDATE语句中判断是否更新某一个字段 ...
- 1.3(Mybatis学习笔记)动态SQL
一.<if> 使用<if>可以根据具体情况来拼接SQL语句,使其更加灵活更加适应我们的需求. <if>的标签体中是需要拼接的语句,满足条件才会将其进行拼接. < ...
- Mybatis学习笔记14 - 动态sql之foreach标签
一.查询给定集合中员工id对应的所有员工信息 示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; import ...
- Mybatis学习笔记10 - 动态sql之if判断
示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; import java.util.List; public ...
- Mybatis学习笔记13 - 动态sql之set标签
示例代码: 接口定义: package com.mybatis.dao; import com.mybatis.bean.Employee; public interface EmployeeMapp ...
- Mybatis学习笔记12 - 动态sql之choose(when otherwise)标签
choose (when, otherwise):分支选择:带了break的swtich-case 示例代码: 接口定义: package com.mybatis.dao; import com.my ...
- Mybatis学习笔记11 - 动态sql之trim标签
trim标签体中是整个字符串拼串后的结果.prefix="" 前缀: prefix给拼串后的整个字符串加一个前缀prefixOverrides="" 前缀覆盖: ...
- MyBatis:学习笔记(4)——动态SQL
MyBatis:学习笔记(4)——动态SQL 如果使用JDBC或者其他框架,很多时候需要你根据需求手动拼装SQL语句,这是一件非常麻烦的事情.MyBatis提供了对SQL语句动态的组装能力,而且他只有 ...
随机推荐
- C#如何生成JSON字符串?(序列化对象)
第一章:C#如何拿到从http上返回JSON数据? 第二章:C#如何解析JSON数据?(反序列化对象) 第三章:C#如何生成JSON字符串?(序列化对象) 第四章:C#如何生成JSON字符串提交给接口 ...
- mahout in Action2.2-给用户推荐图书(1)-直观分析和代码
This chapter covers What recommenders are, within Mahout A first look at a recommender in action ...
- appium如何连接模拟器代码实例
from appium import webdriver def connect(self): self.desired_caps = {} self.desired_caps['platformNa ...
- 巧用cssText属性
给一个HTML元素设置css属性,如 1 2 3 4 var head= document.getElementById("head"); head.style.width = & ...
- oracle创建完实例删除的时候报ORA-01031:insufficient privileges错误,解决办法
创建了一个数据库,想删除确报了一个ORA-01031:insufficient privileges错误 查了好久,总算解决了,原因是我的电脑登录账户不在ORA_DBA系统群组中,添加进去完美删除! ...
- mysql--笔记1
今日内容介绍1.MySQL数据库2.SQL语句=========================================================1 数据库概念 1.1: 什么是数据库 ...
- C++笔记--抽象机制
类 一个类就是一个用户定义类型 一个结构体也是一种类.(成员函数),因为不同的结构体中可能会有相同的名字的成员函数,所以我们在定义成员函数的时候就必须给出有关结构体的名字 void Data::ini ...
- boost库thread.hpp编译警告honored已修复
请浏览:https://svn.boost.org/trac/boost/ticket/7874 #7874: compile warning: thread.hpp:342: warning: ty ...
- [译]Javascript中的错误信息处理(Error handling)
本文翻译youtube上的up主kudvenkat的javascript tutorial播放单 源地址在此: https://www.youtube.com/watch?v=PMsVM7rjupU& ...
- HTML完全使用详解 PDF扫描版
<HTML完全使用详解>根据网页制作的实际特点和目前市场需要,全面系统地介绍了最新的HTML4.01.丰富的实例贯穿全书,能帮助您全面掌握HTML,而且本书所有实例均可直接修改使用,可以提 ...