【mybatis深度历险系列】mybatis中的动态sql
最近一直做项目,博文很长时间没有更新了,今天抽空,学习了一下mybatis,并且总结一下。在前面的博文中,小编主要简单的介绍了mybatis中的输入和输出映射,并且通过demo简单的介绍了输入映射和输出映射,今天这篇博文,小编主要来简单的介绍一下mybatis中的动态sql,有的小伙伴会问,既然有动态sql,那是不是也应该存在静态sql,答案是肯定的。那么什么是静态sql呢,静态sql语句一般用于嵌入式sql应用中,在程序运行之前,sql语句必须是确定的,例如sql语句中涉及的列名和表名必须是存在的,静态sql语句的编译是在应用程序运行前进行的,编译的结果会存储在数据库内容,而后程序进行时,数据库将直接执行编译好的sql语句,降低运行时的开销。所谓的动态sql,是在应用程序运行时被编译和执行的,例如使用DB2的交互式工具CLP访问数据库时,用户输入的sql语句是不确定的,因此sql语句只能被动态的编译,动态的sql的应用较多,常见的CLI和JDBC应用程序都使用动态sql。这篇博文小编主要分三个部分来分别进行介绍,动态sql、sql片段和foreach。
一、动态sql
1.1定义
mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接,组装。
1.2案例需求
用户信息综合查询列表这个statment的定义使用动态sql,对查询条件进行判断,如果输入参数不为空进行查询拼接。
1.3UserMapper.xml
<!-- 用户信息综合查询
#{userCustom.sex}:取出pojo包装对象中性别值
${userCustom.username}:取出pojo对象中用户名称
-->
<select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo"
resultType="com.mybatis.entity.UserCustom">
select * from t_user
<!-- 动态sql查询:where可以自动去掉第一个and -->
<where>
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!='' ">
and sex=#{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!='' ">
and username=#{userCustom.username}
</if>
</if>
</where>
<!-- where sex=#{userCustom.sex} and username LIKE '%${userCustom.username}%' -->
</select>
1.4测试代码
@Test
public void testFindUserList() {
SqlSession sqlSession = sqlSessionFactory.openSession();
//创造查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
// userCustom.setSex("2");
//这里使用动态sql,如果不设置某个值,条件不会拼接sql中
userCustom.setUsername("小");
userQueryVo.setUserCustom(userCustom);
// 创建Usermapper对象,mybatis自动生成mapper代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<UserCustom>list=mapper.findUserList(userQueryVo);
//测试动态sql,属性的非空判断测试
// List<UserCustom>list=mapper.findUserList(null);
System.out.println(list);
sqlSession.commit();
sqlSession.close();
}
二、sql片段
2.1需求
将上边的动态sql判断代码抽取出来,组成一个sql片段,其她的statment中就可以引用sql片段,方便开发。
2.2定义sql片段
<!-- 定义sql片段,Id是唯一标识
建议:是基于单表来定义sql片段,这样的话sql片段的可重用性才高,在sql片段中不要包含where
-->
<sql id="query_user_where" >
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!='' ">
and sex=#{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!='' ">
and username=#{userCustom.username}
</if>
</if>
</sql>
2.3在mapper.xml中定义的statment中引用sql片段
<!-- 用户信息综合查询
#{userCustom.sex}:取出pojo包装对象中性别值
${userCustom.username}:取出pojo对象中用户名称
-->
<select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo"
resultType="com.mybatis.entity.UserCustom">
select * from t_user
<!-- 动态sql查询:where可以自动去掉第一个and -->
<where>
<!-- 引用sql片段的id,如果refid指定的不在本mapper.xml中,需要前边加namespace -->
<include refid="query_user_where"></include>
<!-- 这里可以引用其它的sql片段 -->
</where>
</select>
三、foreach
作用:向sql传递数据或者list,mybatis使用foreach解析,在用户查询列表和查询总数的statment中增加多个id输入查询。
3.1需求:sql语句如下,两种方法:
SELECT * FROM t_user WHERE id=1 OR id=10 OR id=16
SELECT * FROM t_user WHERE id IN(1,10,16)
3.2在输入参数包装类型中添加List<Integer>ids传入多个id
package com.mybatis.entity;
import java.util.List;
/**
*
* @ClassName: UserQueryVo
* @Description: TODO(包装类型)
* @author 丁国华
*
*/
public class UserQueryVo {
public List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
}
3.3mapper.xml代码
<!-- 实现下边的sql拼接
select * from t_user where id=1 OR id=2 OR id=3
-->
<select id="findUserByIds" parameterType="com.mybatis.entity.UserQueryVo"
resultType="com.mybatis.entity.User">
select * from t_user
<where>
<if test="ids!=null">
<!-- 使用foreach遍历ids
collection:指定输入对象的集合属性
item:每个遍历生成对象中
open:开始遍历时拼接的串
close:技术遍历时拼接的串
separator:遍历的两个对象中需要拼接的串
-->
<foreach collection="ids" item="user_id" open="AND (" close=")" separator="or">
id=#{user_id}
</foreach>
</if>
</where>
</select>
select *from t_user where id in(1,2,3)的mapper.xml配置
<select id="findUserByIds" parameterType="com.mybatis.entity.UserQueryVo"
resultType="com.mybatis.entity.User">
select * from t_user
<where>
<if test="ids!=null">
<!--
使用foreach遍历ids
collection:指定输入对象的集合属性
item:每个遍历生成对象中
open:开始遍历时拼接的串
close:技术遍历时拼接的串
separator:遍历的两个对象中需要拼接的串
-->
<!-- 实现“ select * from t_user where id in(1,2,3)”拼接 -->
<foreach collection="ids" item="user_id" open="AND id in (" close=")" separator=",">
id=#{user_id}
</foreach>
</if>
</where>
</select>
userMapper.java代码
public interface UserMapper {
//ids查询用户数据
public List<User> findUserByIds(UserQueryVo userQueryVo);
}
Junit测试代码
@Test
public void findUserByIdsTest() {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建Usermapper对象,mybatis自动生成mapper代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//创造查询条件
UserQueryVo userQueryVo = new UserQueryVo();
//传入多个id
List<Integer> ids=new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(3);
//将ids通过userQueryVo传入statement中
userQueryVo.setIds(ids);
//调用userMapper的代码
List<UserCustom> userList= mapper.findUserList(userQueryVo);
System.out.println(userList);
sqlSession.close();
}
小编寄语:该博文小编主要简单的介绍了mybatis中的动态sql,MyBatis的一个强大的特性之一通常是它的动态 SQL 能力。如果你有使用 JDBC 或其他相似框架的经验,你就明白条件地串联 SQL字符串在一起是多么的痛苦,确保不能忘了空 格或在列表的最后省略逗号。动态 SQL可以彻底处理这种痛苦。通常使用动态SQL不可能是独立的一部分,MyBatis当然使用一种强大的动态SQL语言来改进这种情形,这种语言可以被用在任意映射的SQL语句中。
动态SQL元素和使用JSTL或其他相似的基于XML的文本处理器相似。在MyBatis之前的版本中,有很多的元素需要来了解。MyBatis3大大提升了它们,现在用不到原先一半的元素就能工作了。MyBatis采用功能强大的基于OGNL的表达式来消除其他元素。 小编博文,小编将继续介绍mybatis的相关知识,敬请期待`(*∩_∩*)′。
【mybatis深度历险系列】mybatis中的动态sql的更多相关文章
- 【mybatis深度历险系列】mybatis中的输入映射和输出映射
在前面的博文中,小编介绍了mybatis的框架原理以及入门程序,还有mybatis中开发到的两种方法,原始开发dao的方法和mapper代理方法,今天博文,我们来继续学习mybatis中的相关知识,随 ...
- 【mybatis深度历险系列】mybatis的框架原理+入门程序解析
在前面的博文中,小编介绍了springmvc的相关知识点,在今天这篇博文中,小编将介绍一下mybatis的框架原理,以及mybatis的入门程序,实现用户的增删改查,她有什么优缺点以及mybatis和 ...
- 【mybatis深度历险系列】延迟加载
在前面的博文中,小编主要简单的介绍了mybatis中的高级映射,小伙伴们可以把mybatis和hibernate的因素进行对比,更加有利于理解.今天这篇博文,小编主要来简单介绍一下mybatis中的延 ...
- 【mybatis深度历险系列】深入浅出mybatis中原始dao的开发和mapper代理开发
使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法.mybatis在进行dao开发的时候,涉及到三姐妹,分别是SqlSessionFactoryBuilder ...
- 【mybatis深度历险系列】mybatis中的高级映射一对一、一对多、多对多
学习hibernate的时候,小编已经接触多各种映射,mybatis中映射有到底是如何运转的,今天这篇博文,小编主要来简单的介绍一下mybatis中的高级映射,包括一对一.一对多.多对多,希望多有需要 ...
- Mybatis 系列9-强大的动态sql 语句
[Mybatis 系列10-结合源码解析mybatis 执行流程] [Mybatis 系列9-强大的动态sql 语句] [Mybatis 系列8-结合源码解析select.resultMap的用法] ...
- mybatis中的动态SQL
在实际开发中,数据库的查询很难一蹴而就,我们往往要根据各种不同的场景拼接出不同的SQL语句,这无疑是一项复杂的工作,我们在使用mybatis时,mybatis给我们提供了动态SQL,可以让我们根据具体 ...
- MyBatis基础入门《二十》动态SQL(foreach)
MyBatis基础入门<二十>动态SQL(foreach) 1. 迭代一个集合,通常用于in条件 2. 属性 > item > index > collection : ...
- MyBatis基础入门《十九》动态SQL(set,trim)
MyBatis基础入门<十九>动态SQL(set,trim) 描述: 1. 问题 : 更新用户表数据时,若某个参数为null时,会导致更新错误 2. 分析: 正确结果: 若某个参数为nul ...
随机推荐
- sumo快速运行简单仿真实例详细教程
本文旨在让大家快速的了解sumo,并给出运行一个简单的sumo的例子的教程,进而了解基本sumo工程的架构,使大家对该软件产生兴趣并持续学习下去,刚开始学习仿真的确枯燥,项目"跑起来&quo ...
- TCP/IP学习笔记(二):TCP连接的建立与终止
TCP连接的三次握手: (1)请求短发送一个SYN段指明客户打算连接的服务器的端口,以及初始序号ISN(1415535521),报文段中SYN=1:TCP规定:SYN报文段不能携带数据,但是要消耗一个 ...
- h5视频和音频 -2018/04/16
HTML5 规定了一种通过 video 元素来包含视频的标准方法. 当前video元素支持的三种视频格式: (1)Ogg 带有Theora视频编码和Vorbis音频编码的ogg文件 (2)MPEG4带 ...
- SQL Server 查询性能优化——创建索引原则(二)
三:索引的建立原则 一般来说,建立索引要看数据使用的场景,换句话来说哪些访问数据的SQL语句是常用的,而这些语句是否因为缺少索引(也有可能是索引过多)变的效率低下.但绝不是所有的SQL语句都要建立索引 ...
- 前端之旅HTML与CSS篇之a便签中放入其他块元素会撑大高度的原因
原因:a元素下有一个匿名文本,这个文本外有一个匿名行级盒子,它有的默认vertical-align是baseline的,而且往往因为上文line-height的影响,使它有个line-height,从 ...
- hadoop中集群节点ID不一致( java.io.IOException: Incompatible clusterIDs )
- [HNOI 2018]游戏
Description 题库链接 有 \(n\) 个房间排成一列,编号为 \(1,2,...,n\) ,相邻的房间之间都有一道门.其中 \(m\) 个门上锁,其余的门都能直接打开.现在已知每把锁的钥匙 ...
- [HAOI 2011]Problem c
Description 给n个人安排座位,先给每个人一个1~n的编号,设第i个人的编号为ai(不同人的编号可以相同),接着从第一个人开始,大家依次入座,第i个人来了以后尝试坐到ai,如果ai被占据了, ...
- 【ZOJ 3609】Modular Inverse 最小乘法逆元
The modular modular multiplicative inverse of an integer a modulo m is an integer x such that a-1≡x ...
- ●POJ 2187 Beauty Contest
题链: http://poj.org/problem?id=2187 题解: 计算几何,凸包,旋转卡壳 一个求凸包直径的裸题,旋转卡壳入门用的. 代码: #include<cmath> # ...