9、Mybatis之动态SQL
9.1、环境搭建
9.1.1、创建新module
创建名为mybatis_dynamicSQL的新module,过程参考5.1节

9.1.2、创建Emp实体类

package org.rain.mybatis.pojo;
/**
* @author liaojy
* @date 2023/6/20 - 0:09
*/
public class Emp {
private Integer empId;
private String empName;
private Integer age;
private String gender;
public Emp() {
}
public Emp(Integer empId, String empName, Integer age, String gender) {
this.empId = empId;
this.empName = empName;
this.age = age;
this.gender = gender;
}
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Emp{" +
"empId=" + empId +
", empName='" + empName + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
9.1.3、创建Mapper接口和映射文件

++++++++++++++++++++++++++++分割线++++++++++++++++++++++++++++

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.rain.mybatis.mapper.DynamicSQLMapper">
</mapper>
9.1.4、创建测试类

9.2、if标签
9.2.1、接口方法

List<Emp> getEmpsByCondition(Emp emp);
9.2.2、映射文件

<!--List<Emp> getEmpsByCondition(Emp emp);-->
<select id="getEmpsByCondition" resultType="Emp">
select * from t_emp where
<!--
if标签:通过test属性中的表达式判断标签中的内容是否会拼接到sql中
-->
<if test="empName != '' and empName != null">
emp_name = #{empName}
</if>
<if test="age != '' and age != null">
and age = #{age}
</if>
<if test="gender != '' and gender != null">
and gender = #{gender}
</if>
</select>
9.2.3、测试方法

模拟符合所有if标签的test属性中的表达式判断为true的情况
@Test
public void testCetEmpsByCondition(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
DynamicSQLMapper dynamicSQLMapper = sqlSession.getMapper(DynamicSQLMapper.class);
Emp emp = new Emp();
emp.setEmpName("张三");
emp.setAge(20);
emp.setGender("男");
List<Emp> emps = dynamicSQLMapper.getEmpsByCondition(emp);
System.out.println(emps);
sqlSession.close();
}
9.2.4、执行效果

所有if标签的内容都已顺利拼接到sql中
9.3、where标签
9.3.1、if标签缺陷

注意:当部分或全部if标签的test属性中的表达式判断为false时,sql可能会因为where条件的拼接报错
9.3.2、缺陷修正
9.3.2.1、方式一:增加恒成立条件

<!--List<Emp> getEmpsByCondition(Emp emp);-->
<select id="getEmpsByCondition" resultType="Emp">
select * from t_emp where 1=1
<if test="empName != '' and empName != null">
and emp_name = #{empName}
</if>
<if test="age != '' and age != null">
and age = #{age}
</if>
<if test="gender != '' and gender != null">
and gender = #{gender}
</if>
</select>

9.3.2.1、方式二:使用where标签

<!--List<Emp> getEmpsByCondition(Emp emp);-->
<select id="getEmpsByCondition" resultType="Emp">
select * from t_emp
<!--
where标签的效果:
1、若标签中有条件成立,则自动生成where关键字,且能自动删除(前方)多余的and关键字
2、若标签中没有任何条件成立,则没有任何功能
-->
<where>
<if test="empName != '' and empName != null">
and emp_name = #{empName}
</if>
<if test="age != '' and age != null">
and age = #{age}
</if>
<if test="gender != '' and gender != null">
and gender = #{gender}
</if>
</where>
</select>

++++++++++++++++++++++++++++分割线++++++++++++++++++++++++++++

9.4、trim标签

<!--List<Emp> getEmpsByCondition(Emp emp);-->
<select id="getEmpsByCondition" resultType="Emp">
select * from t_emp
<!--
trim标签:用于添加或去掉标签中的内容
prefix属性:在标签中内容的前面添加指定的内容
suffix属性:在标签中内容的后面添加指定的内容
prefixOverrides属性:在标签中内容的前面去掉指定的内容
suffixOverrides属性:在标签中内容的后面去掉指定的内容
-->
<trim prefix="where" suffixOverrides="and">
<if test="empName != '' and empName != null">
emp_name = #{empName} and
</if>
<if test="age != '' and age != null">
age = #{age} and
</if>
<if test="gender != '' and gender != null">
gender = #{gender} and
</if>
</trim>
</select>
9.5、choose标签组

<!--List<Emp> getEmpsByCondition(Emp emp);-->
<select id="getEmpsByCondition" resultType="Emp">
select * from t_emp
<where>
<!--
choose、when和otherwise标签组合(少用):
when(相当于if...else)至少有一个,otherwise(相当于else)至多有一个
-->
<choose>
<when test="empName != '' and empName != null">
emp_name = #{empName}
</when>
<when test="age != '' and age != null">
age = #{age}
</when>
<when test="gender != '' and gender != null">
gender = #{gender}
</when>
</choose>
</where>
</select>
9.6、foreach标签
9.6.1、批量添加
9.6.1.1、接口方法

void insertMoreEmp(@Param("emps") List<Emp> emps);
9.6.1.2、映射文件

<!--void insertMoreEmp(@Param("emps") List<Emp> emps);-->
<!--
foreach标签:
collection属性:设置要循环的数组或集合
item属性:设置表示数组或集合中迭代元素的变量名
separator属性:设置每次foreach循环之间的分隔符
-->
<insert id="insertMoreEmp">
insert into t_emp values
<foreach collection="emps" item="emp" separator=",">
(null ,#{emp.empName},#{emp.age},#{emp.gender},null)
</foreach>
</insert>
9.6.1.3、测试方法

@Test
public void testInsertMoreEmp(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
DynamicSQLMapper dynamicSQLMapper = sqlSession.getMapper(DynamicSQLMapper.class);
Emp emp1 = new Emp(null,"小明1",20,"男");
Emp emp2 = new Emp(null,"小明2",20,"男");
Emp emp3 = new Emp(null,"小明3",20,"男");
List<Emp> emps = Arrays.asList(emp1, emp2, emp3);
dynamicSQLMapper.insertMoreEmp(emps);
sqlSession.close();
}
9.6.1.4、执行效果

++++++++++++++++++++++++++++分割线++++++++++++++++++++++++++++

++++++++++++++++++++++++++++分割线++++++++++++++++++++++++++++

9.6.2、批量删除
9.6.2.1、接口方法

void deleteMoreEmp(@Param("empIds") Integer[] empIds);
9.6.2.2、映射文件

<!--void deleteMoreEmp(@Param("empIds") Integer[] empIds);-->
<!--
foreach标签:
collection属性:设置要循环的数组或集合
item属性:设置表示数组或集合中迭代元素的变量名
separator属性:设置每次foreach循环之间的分隔符
open属性:设置foreach循环体的前缀
close属性:设置foreach循环体的后缀
-->
<delete id="deleteMoreEmp">
delete from t_emp where emp_id in
<foreach collection="empIds" item="empId" separator="," open="(" close=")">
#{empId}
</foreach>
</delete>
9.6.2.3、测试方法

@Test
public void testDeleteMoreEmp(){
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
DynamicSQLMapper dynamicSQLMapper = sqlSession.getMapper(DynamicSQLMapper.class);
Integer[] empIds = {6, 7};
dynamicSQLMapper.deleteMoreEmp(empIds);
sqlSession.close();
}
9.6.2.4、执行效果

++++++++++++++++++++++++++++分割线++++++++++++++++++++++++++++

++++++++++++++++++++++++++++分割线++++++++++++++++++++++++++++

9.6.2.5、映射文件(变体)

<delete id="deleteMoreEmp">
delete from t_emp where
<foreach collection="empIds" item="empId" separator="or">
emp_id = #{empId}
</foreach>
</delete>

9.7、sql标签

<!--
sql标签:设置一个sql片段
-->
<sql id="empColumns">
emp_id,emp_name,age,gender
</sql>
<!--List<Emp> getEmpsByCondition(Emp emp);-->
<!--
include标签:
refid属性:通过sql标签的id引用相关sql片段
-->
<select id="getEmpsByCondition" resultType="Emp">
select <include refid="empColumns"></include> from t_emp
</select>
9、Mybatis之动态SQL的更多相关文章
- MyBatis的动态SQL详解
MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,本文详解mybatis的动态sql,需要的朋友可以参考下 MyBatis 的一个强大的特性之一通常是它 ...
- Mybatis解析动态sql原理分析
前言 废话不多说,直接进入文章. 我们在使用mybatis的时候,会在xml中编写sql语句. 比如这段动态sql代码: <update id="update" parame ...
- mybatis 使用动态SQL
RoleMapper.java public interface RoleMapper { public void add(Role role); public void update(Role ro ...
- MyBatis框架——动态SQL、缓存机制、逆向工程
MyBatis框架--动态SQL.缓存机制.逆向工程 一.Dynamic SQL 为什么需要动态SQL?有时候需要根据实际传入的参数来动态的拼接SQL语句.最常用的就是:where和if标签 1.参考 ...
- 使用Mybatis实现动态SQL(一)
使用Mybatis实现动态SQL 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 写在前面: *本章节适合有Mybatis基础者观看* 前置讲解 我现在写一个查询全部的 ...
- MyBatis探究-----动态SQL详解
1.if标签 接口中方法:public List<Employee> getEmpsByEmpProperties(Employee employee); XML中:where 1=1必不 ...
- mybatis中的.xml文件总结——mybatis的动态sql
resultMap resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功. 如果sql查询字段名和pojo的属性名不一致,可以通过re ...
- mybatis.5.动态SQL
1.动态SQL,解决关联sql字符串的问题,mybatis的动态sql基于OGNL表达式 if语句,在DeptMapper.xml增加如下语句; <select id="selectB ...
- MyBatis的动态SQL详解-各种标签使用
MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. MyBatis中用于实现动态SQL的元素主要有: if choose(when,otherwise) ...
- 利用MyBatis的动态SQL特性抽象统一SQL查询接口
1. SQL查询的统一抽象 MyBatis制动动态SQL的构造,利用动态SQL和自定义的参数Bean抽象,可以将绝大部分SQL查询抽象为一个统一接口,查询参数使用一个自定义bean继承Map,使用映射 ...
随机推荐
- 2022-03-30:有m个同样的苹果,认为苹果之间无差别, 有n个同样的盘子,认为盘子之间也无差别, 还有,比如5个苹果如果放进3个盘子, 那么1、3、1和1、1、3和3、1、1的放置方法,也认为是
2022-03-30:有m个同样的苹果,认为苹果之间无差别, 有n个同样的盘子,认为盘子之间也无差别, 还有,比如5个苹果如果放进3个盘子, 那么1.3.1和1.1.3和3.1.1的放置方法,也认为是 ...
- 美女同事的烦恼:如何配置 Apache SkyWalking 告警?
小婉 技术部基本上是一个和尚庙,女生非常少,即使有女生也略微有点抽象,小婉就不一样,她气质绝佳. 上午,同事小婉刚才从老板办公室里出来,看上去一脸不悦的样子.为了表示对同事的关(ba)心(gua),我 ...
- SpringIOC和SpringAOP
作为一个Spring使用者条件: 拥有深入的Spring框架知识和开发经验,能够熟练地运用Spring框架来构建复杂的应用程序. 了解Spring框架的核心概念和设计思想,如控制反转(IoC).依赖注 ...
- CVE-2021-41773 apache路径遍历
来自tryhackeme的漏洞复现 CVE-2021-41773/42013 利用:路径遍历利用将允许服务器公开任意文件 需要启用mod_cgi模块才能获得远程代码执行 2021 年 10 月 5 日 ...
- 写一个Python简单的Socket网络通讯
完成需求 用Python完成一个简单的Socket通讯实例 1. 服务端 用于提供服务 源码: import socket s = socket.socket() # 创建服务器端套接字 # sk.s ...
- RedHat7.4配置yum源(原创!详细易懂)
redhat7 .4配置centOS yum源(自带yum文件) 1.定位到yum的配置文件 root@192.168.6.129:/etc# cd yum.repos.d 2.检查yum是否安装,以 ...
- Java类加载原理中为何要设计双亲委派机制
首先,给大家演示两个示例代码,我们自定义一个与Java核心类库中java.lang.String类名相同的代码: package java.lang; /** * 自定义java.lang.Strin ...
- ClickHouse技术研究及语法简介
本文对Clickhouse架构原理.语法.性能特点做一定研究,同时将其与mysql.elasticsearch.tidb做横向对比,并重点分析与mysql的语法差异,为有mysql迁移clickhou ...
- tSNE算法在自然语言处理中的应用:文本降维和可视化
目录 技术原理及概念 t-SNE(Toeplitz-Stochastic Neural Network)是一种常用的文本降维和可视化算法,它的核心思想是将高维文本数据映射到低维空间,同时保持数据的一致 ...
- 在命令行按下tab键之后, 发生了生么?
1. 引言 2. complete命令 3. 自定义补全列表 4. 动态补全列表 5. compgen命令 6. 别名的自动补全 7. 补全规则永久生效 8. 自动加载 9. 参考 1. 引言 当我们 ...