动态sql简介&OGNL了解

动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处 理器相似。

MyBatis 采用功能强大的基于 OGNL 的表达式来简化操作。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

注意xml中的转义字符的使用

使用XML转义序列表示这些特殊的字符,这5个特殊字符所对应XML转义序列为:
& &
< &lt;
> &gt;
" &quot;
' &apos;

if标签使用

要求:查询员工,携带了哪个查询条件就带上这个字段的值

<resultMap id="EmployeeMap" type="Employee">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="gender" property="gender"/>
<result column="email" property="email"/>
<association property="department"
select="com.wang.Dao.DepartmentMapper.getDepartmentByDid"
column="d_id"/>
</resultMap>
<!--if
choose (when, otherwise)
trim (where, set)
foreach-->
<!-- //测试if语句-->
<!--if标签里的test属性放的就是OGNL表达式-->
<!--List<Employee> getEmployeeIf(HashMap<String, Object> map);-->
<select id="getEmployeeIf" parameterType="map" resultMap="EmployeeMap">
select *
from tbl_employee
where
<if test="id!=null">
id = #{id}
</if>
<if test="lastName!=null and lastName !=''">
and Last_name = #{lastName}
</if>
<if test="gender!=null and gender != ''">
and gender = #{gender}
</if>
<if test="email!=null and email != ''">
and email = #{email}
</if>
</select>

where标签使用

在使用if时会发现我们在使用if语句时,会因为and无法自动去除而导致了后面的sql语法错误,使用where标签就可以帮助我们自动去除and

  • 解决方法1:

    在原本的sql语句的where后面加上1=1

    但if语句中必须是这样的,and + 字段

    <if test="email!=null and email != ''">
    and email = #{email}
    </if>
  • 解决方法2:

    把我们需要判断的所有语句全部放到where标签下,用以取代原来的where语句

    and任然需要放在sql语句的前面

    <select id="getEmployeeIf" parameterType="map" resultMap="EmployeeMap">
    select *
    from tbl_employee
    <where>
    <if test="id!=null">
    and id = #{id}
    </if>
    <if test="lastName!=null and lastName !=''">
    and Last_name = #{lastName}
    </if>
    <if test="gender!=null and gender != ''">
    and gender = #{gender}
    </if>
    <if test="email!=null and email != ''">
    and email = #{email}
    </if>
    </where>
    </select>

trim代替where标签

在使用where时会发现,where只能去除整句sql语句的前缀,但后缀不能去除,且不够灵活

使用trim可以自定义在整句sql语句上加上前缀和后缀,当发现整句话前或者后多了某个词也能帮助我们去除

属性:

  • prefix:整句sql语句前加上一个前缀

  • suffix:整句sql语句后加上一个后缀

  • prefixOverride:整句sql语句前多了指定的值就会被删除

  • subfixOverride:整句sql语句后多了指定的值就会被删除

<select id="getEmployeeIf" parameterType="map" resultMap="EmployeeMap">
select *
from tbl_employee
<trim prefix="where" prefixOverrides="and" suffixOverrides="and">
<if test="id!=null">
and id = #{id}
</if>
<if test="lastName!=null and lastName !=''">
and Last_name = #{lastName}
</if>
<if test="gender!=null and gender != ''">
and gender = #{gender}
</if>
<if test="email!=null and email != ''">
and email = #{email}
</if>
</trim>
</select>

choose分支查询

要求:如果带了id就用id查询,不再使用其他的查询了,如果带了last_name就用last_name查询

所以:choose-when类似于switch-case

注意点:当输入了大量值的时候,按照when的先后顺序排其次

<!--    //测试choose语句-->
<!-- List<Employee> getEmployeeChoose(HashMap<String, Object> map);-->
<select id="getEmployeeChoose" resultMap="EmployeeMap">
select *
from tbl_employee
<trim prefix="where" prefixOverrides="and">
<choose>
<when test="id!=null">
and id = #{id}
</when>
<when test="lastName!=null and lastName!=''">
and last_name = #{lastName}
</when>
<when test="gender!=null and gender!=''">
and gender = #{gender}
</when>
<when test="email!=null and email!=''">
and email = #{email}
</when>
</choose>
</trim>
</select>

set标签

要求:更新数据库的时候,传入了什么数据就更新哪些数据类似于where属性,但是他主要用于uptate的sql语句

<update id="UpdateEmployee" parameterType="map">
update tbl_employee
<set>
<if test="lastName!=null">
last_name = #{lastName},
</if>
<if test="gender!=null">
gender = #{gender},
</if>
<if test="email!=null">
email = #{email},
</if>
</set>
where id = #{id}
</update>

trim代替set标签

<update id="UpdateEmployee" parameterType="map">
update tbl_employee
<trim prefix="set" suffixOverrides=",">
<if test="lastName!=null">
last_name = #{lastName},
</if>
<if test="gender!=null">
gender = #{gender},
</if>
<if test="email!=null">
email = #{email},
</if>
</trim>
where id = #{id}
</update>

foreach标签遍历传入参数给sql语句

<select id="getEmployeeForeach" parameterType="map" resultMap="EmployeeMap">
select *
from tbl_employee
<!--
collection:指定要遍历的集合
list类型的参数会特殊处理封装在map中,map的key就叫list
item:将当前遍历的元素赋值给指定的变量
separator:遍历出来的每个元素的分割符
open:该SQL语句拼接后在前面加上的字符
close:该sql语句拼接后在后面加上的字符
index:索引。遍历list的时候index就是索引,item就是当前值
遍历map时候index表示的就是map的key
--> <foreach collection="ids" item="item_id" separator="," open="where id in (" close=")">
#{item_id}
</foreach>
</select>

foreach实现批量保存

<insert id="insertEmployeeForeach" parameterType="list">
insert into tbl_employee
(id,last_name,gender,email,d_id)
<foreach collection="list" separator="," open="values" item="item">
(#{item.id},#{item.lastName},#{item.gender},#{item.email},#{item.department.id})
</foreach>
</insert>

mybatis的两个内置参数(提取可重用代码基础)

<select id="getEmployeeInnerParamter" parameterType="employee" resultMap="EmployeeMap">
<!--两个内置参数:
不只是方法传递过来的参数可以传递,取值。
mybatis还有两个内置参数:
_paramter:代表整个参数
单个参数时:_paramter就是这个歌参数
多个参数时:这些参数会被封装成一个map,_paramter就是封装好的map
_databaseId:如果配置了databaseIdProvider标签,_databaseId就代表数据库的别名-->
<!--这里使用databaseId参数来进行根据不同数据库,执行不同语句-->
<choose>
<when test="_databaseId=='mysql'">
<choose>
<when test="_parameter!=null">
select * from tbl_employee
</when>
</choose>
</when>
<when test="_databaseId=='oracle'">
<choose>
<when test="_parameter!=null">
select * from tbl_employee
</when>
</choose>
</when>
</choose>
</select>

bind绑定OGNL值,便于后来调用

<select id="getEmployeeBind" resultMap="EmployeeMap">
<!--bind:可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值-->
<!--帮助我们提前拼接好lastName以便于使用模糊查询-->
<bind name="_lastName" value="'%'+lastName+'%'"/>
select * from tbl_employee where last_name like #{_lastName};
</select>

sql标签和include标签结合使用实现sql语句复用

抽取可重复使用的sql片段,方便后期维护

1、sql抽取,经常将要查询的列名,或者插入用的列名抽取出来方便使用

2、include用来引用已经抽取的sql

3、include还可以自定义一些property,sql标签内部就能使用自定义的属性

​ include-property:取值的正确方式${prop},而不能是#{prop}

<sql id="insertColumn">
id,last_name,gender,email,${testcolumn}
</sql>
<insert id="insertEmployee">
insert into tbl_employee(
<include refid="insertColumn">
<property name="testcolumn" value="abc"/>
</include>
)
values(
<include refid="insertColumn"/>
)
</insert>

mybatis-6-动态sql的更多相关文章

  1. MyBatis的动态SQL详解

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑,本文详解mybatis的动态sql,需要的朋友可以参考下 MyBatis 的一个强大的特性之一通常是它 ...

  2. Mybatis解析动态sql原理分析

    前言 废话不多说,直接进入文章. 我们在使用mybatis的时候,会在xml中编写sql语句. 比如这段动态sql代码: <update id="update" parame ...

  3. mybatis 使用动态SQL

    RoleMapper.java public interface RoleMapper { public void add(Role role); public void update(Role ro ...

  4. MyBatis框架——动态SQL、缓存机制、逆向工程

    MyBatis框架--动态SQL.缓存机制.逆向工程 一.Dynamic SQL 为什么需要动态SQL?有时候需要根据实际传入的参数来动态的拼接SQL语句.最常用的就是:where和if标签 1.参考 ...

  5. 使用Mybatis实现动态SQL(一)

    使用Mybatis实现动态SQL 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 写在前面:        *本章节适合有Mybatis基础者观看* 前置讲解 我现在写一个查询全部的 ...

  6. MyBatis探究-----动态SQL详解

    1.if标签 接口中方法:public List<Employee> getEmpsByEmpProperties(Employee employee); XML中:where 1=1必不 ...

  7. mybatis中的.xml文件总结——mybatis的动态sql

    resultMap resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功. 如果sql查询字段名和pojo的属性名不一致,可以通过re ...

  8. mybatis.5.动态SQL

    1.动态SQL,解决关联sql字符串的问题,mybatis的动态sql基于OGNL表达式 if语句,在DeptMapper.xml增加如下语句; <select id="selectB ...

  9. MyBatis的动态SQL详解-各种标签使用

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. MyBatis中用于实现动态SQL的元素主要有: if choose(when,otherwise) ...

  10. 利用MyBatis的动态SQL特性抽象统一SQL查询接口

    1. SQL查询的统一抽象 MyBatis制动动态SQL的构造,利用动态SQL和自定义的参数Bean抽象,可以将绝大部分SQL查询抽象为一个统一接口,查询参数使用一个自定义bean继承Map,使用映射 ...

随机推荐

  1. 利用NVIDIA-NGC中的MATLAB容器加速语义分割

    利用NVIDIA-NGC中的MATLAB容器加速语义分割 Speeding Up Semantic Segmentation Using MATLAB Container from NVIDIA NG ...

  2. Autofac入门

    注意:本文为原创文章,任何形式的转载.引用(包括但不限于以上形式)等,须先征得作者同意,否则一切后果自负. 简介 Autofac 是一个令人着迷的.NET IoC 容器. 它管理类之间的依赖关系.当应 ...

  3. Spring Cloud09: Config 配置中心

    一.概述 什么是配置中心呢,在基于微服务的分布式系统中,每个业务模块都可以拆分成独立自主的服务,由多个请求来协助完成某个需求,那么在某一具体的业务场景中,某一个请求需要调用多个服务来完成,那么就存在一 ...

  4. 【NX二次开发】NX内部函数,pskernel.dll文件中的内部函数

    pskernel.dll文件中的内部函数,含有部分pk函数,用法可以查看pk函数帮助: ADPAPE ADVXED APPTRA ATGETO ATTGEO BLECHK BLECRB BLECVR ...

  5. 【NX二次开发】NX对象类型及基本操作

    说明:NX中的所有对象都是通过唯一的tag_t值进行标识的,这些对象大致可以分为部件对象.UF对象.表达式.链表对象和属性对象等. 部件对象的操作: 基本操作函数: 1. UF_PART_new()  ...

  6. 「模拟8.18」字符串(卡特兰数)·乌鸦喝水(树状数组,二分)·所驼门王的宝藏(tarjan,拓扑)

    最近好颓啊,所以啥都做不出来 简单说一下这次考试,分机房了,还分不同考卷,果然我还是留在二机房的蒟蒻, 大概也只有这样的简单题,才能勉强水个rank 3吧........ 其实不必管在哪个机房,努力便 ...

  7. linux基础(电脑基本原理)

    1.计算机体系结构:运算器  控制器   存储器  输入设备   输出设备 详解:存储即内存:编址的存储单元.即每一个存储单元在都有一个编址. 控制器告诉运算器加数在存储器的哪个存储单元. POST: ...

  8. 为你的Go应用创建轻量级Docker镜像?

    缩小Go二进制文件大小 环境 youmen@youmendeMacBook-Pro % gcc -dumpversion 12.0.5 youmen@youmendeMacBook-Pro % go ...

  9. 生成工作区设置文件settings.json

    先Ctrl+Shift+P,然后输入setting搜索 找到工作区设置(工作区,仅在当前打开的界面下生效,文档位置与根目录/.vscode/setting.json(可自己创建,也可不创建)) 选择之 ...

  10. Netty 框架学习 —— 添加 WebSocket 支持

    WebSocket 简介 WebSocket 协议是完全重新设计的协议,旨在为 Web 上的双向数据传输问题提供一个切实可行的解决方案,使得客户端和服务器之间可以在任意时刻传输消息 Netty 对于 ...