MyBatis的使用八(动态SQL)
本主要讲述mybatis处理动态sql语句
一. 问题引入
前端展示的数据表格中,查询条件可能不止一个,如何将用户输入的多个查询条件,拼接到sql语句中呢?
DynamicMapper接口声明如下
public interface DynamicMapper {
// 动态查询员工信息
List<Employee> selectEmpDynamic(@Param("emp") Employee emp);
}
如何在DynamicMapper.xml文件中,编写sql语句,使其动态查询呢?
二. 动态SQL查询
1. <if>标签
DynamicMapper.xml文件声明如下
<!--// 动态查询员工信息
List<Employee> selectEmpDynamic(Employee emp);-->
<select id="selectEmpDynamic" resultType="Employee">
select * from t_emp where 1=1
<if test="emp.empName != null and emp.empName != '' ">
and emp_name = #{emp.empName}
</if>
<if test="emp.age != null and emp.age != '' ">
and age = #{emp.age}
</if>
<if test="emp.gender != null and emp.gender != '' ">
and gender = #{emp.gender}
</if>
</select>
测试test
@Test
// 测试动态查询
public void test01(){
SqlSession sqlSession = SQLSessionUtils.getSqlSession();
DynamicMapper mapper = sqlSession.getMapper(DynamicMapper.class);
Employee emp = new Employee(null, "", 23, "");
List<Employee> list = mapper.selectEmpDynamic(emp);
System.out.println(list);
}
运行结果如下
DEBUG 02-05 13:49:28,390 ==> Preparing: select * from t_emp where 1=1 and age = ? (BaseJdbcLogger.java:137)
DEBUG 02-05 13:49:28,432 ==> Parameters: 23(Integer) (BaseJdbcLogger.java:137)
DEBUG 02-05 13:49:28,461 <== Total: 1 (BaseJdbcLogger.java:137)
[Employee{empId=1, empName='张三', age=23, gender='男', dept=null}]
注意:单独使用 < if > 标签时,需要在where后面添加恒成立的条件,例如 1=1,之后在< if >标签中的test写判断条件
2. <where> + <if>标签
DynamicMapper.xml文件声明如下
<select id="selectEmpDynamicTwo" resultType="Employee">
select * from t_emp
<where>
<if test="emp.empName != null and emp.empName != '' ">
and emp_name = #{emp.empName}
</if>
<if test="emp.age != null and emp.age != '' ">
and age = #{emp.age} and
</if>
<if test="emp.gender != null and emp.gender != '' ">
and gender = #{emp.gender}
</if>
</where>
</select>
测试test1
@Test
// 测试动态查询
public void test01(){
SqlSession sqlSession = SQLSessionUtils.getSqlSession();
DynamicMapper mapper = sqlSession.getMapper(DynamicMapper.class);
Employee emp = new Employee(null, "张三", 23, "");
List<Employee> list = mapper.selectEmpDynamic(emp);
System.out.println(list);
}
test1 运行结果如下
DEBUG 02-05 14:00:47,159 ==> Preparing: select * from t_emp WHERE emp_name = ? and age = ? (BaseJdbcLogger.java:137)
DEBUG 02-05 14:00:47,190 ==> Parameters: 张三(String), 23(Integer) (BaseJdbcLogger.java:137)
DEBUG 02-05 14:00:47,211 <== Total: 1 (BaseJdbcLogger.java:137)
[Employee{empId=1, empName='张三', age=23, gender='男', dept=null}]
注意:<where>标签只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,<where>标签也会将它们去除。
但是当DynamicMapper.xml声明如下
<select id="selectEmpDynamic" resultType="Employee">
select * from t_emp
<where>
<if test="emp.empName != null and emp.empName != '' ">
emp_name = #{emp.empName} and
</if>
<if test="emp.age != null and emp.age != '' ">
age = #{emp.age} and
</if>
<if test="emp.gender != null and emp.gender != '' ">
gender = #{emp.gender}
</if>
</where>
</select>
测试test2
@Test
// 测试动态查询
public void test01(){
SqlSession sqlSession = SQLSessionUtils.getSqlSession();
DynamicMapper mapper = sqlSession.getMapper(DynamicMapper.class);
Employee emp = new Employee(null, "张三", 23, "");
List<Employee> list = mapper.selectEmpDynamic(emp);
System.out.println(list);
}
test2 运行结果如下
DEBUG 02-05 14:08:29,175 ==> Preparing: select * from t_emp WHERE emp_name = ? and age = ? and (BaseJdbcLogger.java:137)
DEBUG 02-05 14:08:29,206 ==> Parameters: 张三(String), 23(Integer) (BaseJdbcLogger.java:137)
sql语句出现错误,即<where>标签无法去除SQL子句后面的and或者or。
3. <trim> + <if> 标签
DynamicMapper.xml文件声明如下
<select id="selectEmpDynamic" resultType="Employee">
select * from t_emp
<!--prefix="where" 前缀添加where
suffix="where" 后缀添加where
prefixOverrides="and" 前缀删除and
suffixOverrides="and" 后缀删除and-->
<trim prefix="where" suffixOverrides="and">
<if test="emp.empName != null and emp.empName != '' ">
emp_name = #{emp.empName} and
</if>
<if test="emp.age != null and emp.age != '' ">
age = #{emp.age} and
</if>
<if test="emp.gender != null and emp.gender != '' ">
gender = #{emp.gender}
</if>
</trim>
</select>
注意:<trim>标签的功能比<where>标签的功能更加丰富
test2运行结果如下
DEBUG 02-05 14:14:51,893 ==> Preparing: select * from t_emp where emp_name = ? and age = ? (BaseJdbcLogger.java:137)
DEBUG 02-05 14:14:51,924 ==> Parameters: 张三(String), 23(Integer) (BaseJdbcLogger.java:137)
DEBUG 02-05 14:14:51,943 <== Total: 1 (BaseJdbcLogger.java:137)
[Employee{empId=1, empName='张三', age=23, gender='男', dept=null}]
完美解决and在SQL子句后面的问题。
三. 批量增加【删除】
1. 批量增加
DynamicMapper接口声明如下
public interface DynamicMapper {
// 批量添加emp对象
int insertEmpList(@Param("emps") List<Employee> emps);
}
DynamicMapper.xml文件声明如下
<!--// 批量添加emp对象
int insertEmpList(@Param("emps") List<Employee> emps);-->
<insert id="insertEmpList" >
insert into t_emp values
<foreach collection="emps" item="emp" separator=",">
(null,#{emp.empName},#{emp.age},#{emp.gender},null)
</foreach>
</insert>
2. 批量删除
DynamicMapper接口声明如下
public interface DynamicMapper {
// 批量删除emp对象
int deleteEmpList(@Param("empIds") Integer[] empIds);
}
DynamicMapper.xml文件声明如下
<!--// 批量删除emp对象-->
<!--int deleteEmpList(@Param("empIds") Integer[] empIds);-->
<!--方式1: -->
<delete id="deleteEmpListOne" >
delete from t_emp
where emp_id in
(
<foreach collection="empIds" item="empId" separator=",">
#{empId}
</foreach>
)
</delete> <!--方式2: -->
<delete id="deleteEmpListTwo" >
delete from t_emp
where emp_id in
<foreach collection="empIds" item="empId" separator="," open="(" close=")">
#{empId}
</foreach>
</delete> <!--方式3: -->
<delete id="deleteEmpList" >
delete from t_emp
where
<foreach collection="empIds" item="empId" separator="or">
emp_id = #{empId}
</foreach>
</delete>
注意:< foreach >标签的使用,
collecion:传入的集合【数组】名;
item:集合【数组】中元素的类型;
separator:以指定字符串为分隔符;
open:以指定字符串开始,close:以指定字符串结尾。
MyBatis的使用八(动态SQL)的更多相关文章
- MyBatis学习总结_11_MyBatis动态Sql语句
MyBatis中对数据库的操作,有时要带一些条件,因此动态SQL语句非常有必要,下面就主要来讲讲几个常用的动态SQL语句的语法 MyBatis中用于实现动态SQL的元素主要有: if choose(w ...
- MyBatis:学习笔记(4)——动态SQL
MyBatis:学习笔记(4)——动态SQL
- SSM框架之Mybatis(6)动态SQL
Mybatis(6)动态SQL 1.动态SQL 出现原因:有些时候业务逻辑复杂时,我们的 SQL 是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了 1.1.if标签 我们根据实体类的不 ...
- Spring mybatis源码篇章-动态SQL节点源码深入
通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-动态SQL基础语法以及原理 前话 前文描述到通过mybatis默认的解析驱动类org.apache.ibat ...
- Mybatis系列全解(八):Mybatis的9大动态SQL标签你知道几个?提前致女神!
封面:洛小汐 作者:潘潘 2021年,仰望天空,脚踏实地. 这算是春节后首篇 Mybatis 文了~ 跨了个年感觉写了有半个世纪 ... 借着女神节 ヾ(◍°∇°◍)ノ゙ 提前祝男神女神们越靓越富越嗨 ...
- 深入浅出Mybatis系列 强大的动态SQL
上篇文章<深入浅出Mybatis系列(八)---mapper映射文件配置之select.resultMap>简单介绍了mybatis的查询,至此,CRUD都已讲完.本文将介绍mybatis ...
- mybatis入门基础(五)----动态SQL
一:动态SQL 1.1.定义 mybatis核心对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装. 1.2.案例需求 用户信息综合查询列表这个statement的定义使用动态s ...
- (转)Mybatis高级映射、动态SQL及获得自增主键
原文:http://www.cnblogs.com/edwinchen/p/4105278.html?utm_source=tuicool&utm_medium=referral 一.动态SQ ...
- Mybatis高级映射、动态SQL及获得自增主键
一.动态SQL 相信大家在用mybatis操作数据库时时都会碰到一个问题,假如现在我们有一个关于作者的list authorList,需要根据authorList里已有的作者信息在数据库中查询相应作者 ...
- MyBatis 源码分析——动态SQL语句
有几年开发经验的程序员应该都有暗骂过原生的SQL语句吧.因为他们不能一句就搞定一个业务,往往还要通过代码来拼接相关的SQL语句.相信大家会理解SQL里面的永真(1=1),永假(1=2)的意义吧.所以m ...
随机推荐
- JK触发器与模12计数器
JK触发器 JK触发器具有保持,置0,置1和翻转四个功能. 则可得出次态方程:\(Q_{n+1} = JQ_n'+K'Q_n\) Design `timescale 1ns / 1ps module ...
- Git安装与常用操作
Git作为一个版本控制工具,使用前需进行下载安装:可自行到官网下载. 一.安装(windows) 1.双击下载好的文件进行安装,弹窗中点击"next" 2.默认勾选,继续点击&qu ...
- 超精准!AI 结合邮件内容与附件的意图理解与分类!⛵
作者:韩信子@ShowMeAI 深度学习实战系列:https://www.showmeai.tech/tutorials/42 TensorFlow 实战系列:https://www.showmeai ...
- [CG] 用 Docker 配置 Ubuntu OpenGL 环境
成功在 MacOS 的 Docker 中运行 OpenGL 程序并显示这里记录一下: 我用的是 https://hub.docker.com/r/thewtex/opengl 这个镜像非常好,大部分工 ...
- python(牛客)试题解析3 - 困难
导航 一.找到已经最大承重的背包内如何放入最大价值的物品的最优解 二.查找一个字符串中包含另外一个字符串(可打乱顺序)的次数三.计算正整数数组从头走到最后一个成员所需的最小步骤四.计算字符串非严格递增 ...
- 使用Supervisor监控mysql
Supervisor安装教程参考:https://www.cnblogs.com/brad93/p/16639953.html mysql安装教程参考:https://www.cnblogs.com/ ...
- 【基础语法规范】BC1:Hello Nowcoder
语言1:Java public class Main{ public static void main(String[] args){ System.out.println("Hello N ...
- 【每日一题】【双端降序队列Deque】2021年12月28日-239. 滑动窗口最大值
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 来源:力扣(L ...
- UE4 WebUI插件使用指南
在开发数字孪生应用程序的时候,除了三维场景展示之外,也需要开发丰富和酷炫的2D页面. 使用UE4的UMG开发图表显得比较笨拙. 而通过Web插件允许开发者创建丰富的基于Web HTML5的用户界面,它 ...
- java并发数据结构之CopyOnWriteArrayList
CopyOnWriteArrayList是一个线程安全的List实现,其在对对象进行读操作时,由于对象没有发生改变,因此不需要加锁,反之在对象进行增删等修改操作时,它会先复制一个对象副本,然后对副本进 ...