每日一记-Mybatis动态语句

前言

      对Mybatis没有过使用经验,早起的时候就是直接写SQL语句,后来学会都在使用Hibernate,现在的公司使用的Mybatis,所以需要学习一下。

      为了学习这个,直接搜了一个系列的Mybatis教程进行学习。看到动态SQL语句部分,博主开篇就先说了Mybatis的动态SQL语句是基于OGNL表达式的。OGNL-Object Graph Navigation Lanaguage(对象图导航语言),第一次接触这个还是在Struts2内,用在Struts配置文件中或者在JSP内使用struts标签时,调用变量、方法或者对象时控制十分灵活。

动态SQL语句

      很多时候进行sql增删查改操作,可能会有很多不同的条件,比如说假定有一个用户数据库,字段有ID、姓名、联系电话、邮箱,查询用户的时候可能会根据一个字段姓名或者联系电话、邮箱作为条件来查,也可能会根据俩个字段姓名及联系电话或者姓名及邮箱等作为条件来查。

      在类内直接写select的时候可能要写很多条SQL语句,然后通过种种判断来确定要调用哪一条语句,十分繁琐;后来学会了Hibernate,觉得方便了很多,不需要再去写很多条sql语句了,虽然会多写一点代码;现在看到Mybatis的动态sql语句,轻便、简单。


      以一个user表为例,有ID name phone email四个字段,ID为自增。以下只写出了动态sql语句,并未写出完整的增删查改配置。

if

select * from user where 1=1
    <if test="name!=null">
        and name = #{name}
    </if>
    <if test="phone!=null">
        and phone = #{phone}
    </if>
    <if test="email!=null">
        and email = #{email}
    </if>

      只要任一字段满足不为空,就会增加一个条件,直到所有的语句都进行了判断,如name不为空,则相当于
select * from user where 1=1 and name = #{name}
当phone字段也不为空时,相当于
select * from user where 1=1 and name = #{name} and phone = #{phone},这样可以灵活控制查询的条件。

choose(when otherwize)

select * from user where 1=1 
<choose>
    <when test="name!=null">
        and name = #{name}
    </when>
    <when test="phone!=null">
        and phone = #{phone}
    </when>
    <otherwise>
        and email = #{email}
    </otherwise>
</choose>

      when otherwise组成的条件语句相当于JAVA中switch的效果,满足哪一条判断就将相应的条件附加上,然后跳出逻辑,不再继续向下判断条件,不同于使用if时;当所有when条件都不满足时,就输出otherwise对应的语句,相当于switch中的default。

trim

select * from user where 1=1
<trim prefix="where" prefixOverrides="and|or">
    <if test="name!=null">
        name = #{name}
    </if>
    <if test="phone!=null">
        and phone = #{phone}
    </if>
    <if test="email!=null">
        or email = #{email}
    </if>
</trim>

      对trim的理解不透彻,实验结果也有所疑惑,看了网上的几篇博客,依旧不明白几个if条件的关系,留待稍后继续研究。

where

select * from user 
<where>
    <if test="name!=null">
        name = #{name}
    </if>
    <if test="phone!=null">
        and phone = #{phone}
    </if>
    <if test="email!=null">
        and email = #{email}
    </if>
</where>

      where的作用就是输出一个where,其优点是不需要关心~~~中的语句逻辑,使用where时会自动处理where后包含的and|or开头。比如当name为空,而phone不为空时,拼接成语句
select * from user where and phone = #{phone},然后检测到where后有and开头的条件,自动将and忽略,最后输出
select * from user where phone = #{phone}。where中的几个if语句与单独使用if相同,可以同时存在。

set

update user
<set>
    <if test="name!=null">
        name = #{name},
    </if>
    <if test="phone!=null">
        phone = #{phone},
    </if>
    <if test="email!=null">
        email = #{email}
    </if>
</set>
where ID=#{id}

      set主要用于更新,会输出一个set在语句前,类似与where,不同的是set处理语句的末尾,如果语句末尾以逗号结束,set会自动处理掉,方便各种条件的更新操作。等价于
update user name = #{name},phone = #{phone} where ID = #{id}

foreach

select * from user where ID in
<foreach collection="collectionType" index="index" item="item" open="openFlage" separator="dilimiter" close="closeFlage" >
    #{item}
</foreach>

      上述语句中的collectionType、index、openFlag、closeFlag、dilimiter在具体的使用中需要根据条件进行设置。

collectionType:该属性是必须的,可以为List、Array或者Map等,分别针对不同的情况。如果传入的是单一参数且参数类型是list,那么就是List;如果是单一参数且参数类型是array,则是array;如果是多个参数时,则必须使用map;

index:指定在迭代过程中,每次迭代到什么位置

openFlag:foreach条件语句以什么开始,如常见的”()”、”<>”
closeFlag:语句以什么结束

item:collection中每一个元素在迭代时的别名

dilimeter:collection中元素之间以什么作为分隔符,如”,”、”.”、”;”

完整语句整合

UserMapper.xml

<?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="User">
<!--    查询相关   -->
    <!-- 使用if -->
    <select id="selectWithIf" parameterType="java.util.Map" resultType="User">
        select * from user where 1=1
            <if test="name!=null">
                and name = #{name}
            </if>
            <if test="phone!=null">
                and phone = #{phone}
            </if>
            <if test="email!=null">
                and email = #{email}
            </if>
    </select>
    <!-- 使用choose -->
    <select id="selectWithChoose" parameterType="java.util.Map" resultType="User" >
        select * from user where 1=1 
            <choose>
            <when test="name!=null">
                and name = #{name}
            </when>
            <when test="phone!=null">
                and phone = #{phone}
            </when>
            <otherwise>
                and email = #{email}
            </otherwise>
            </choose>
    </select>
    <!-- 使用where -->
    <select id="selectWithWhere" >
        select * from user 
        <where>
        <if test="name!=null">
            name = #{name}
        </if>
        <if test="phone!=null">
            and phon e= #{phone}
        </if>
        <if test="email!=null">
            and email = #{email}
        </if>
        </where>
    </select>
<!--    新增相关 -->
    <insert id="addUser" parameterType="java.util.Map">
        insert into User(ID,name,phone,email) values
        (#{id},#{name},#{phone},#{email})
    </insert>
<!--    更新相关 -->
    <update id="updateWithSet" parameterType="java.util.Map">
        update user
        <set>
        <if test="name!=null">
            name = #{name},
        </if>
        <if test="phone!=null">
            phone = #{phone},
        </if>
        <if test="email!=null">
            email = #{email}
        </if>
        </set>
        where ID = #{id}
    </update>
<!--    批量删除 -->
    <delete id="delWithForeach" parameterType="java.util.List" >
     delete from user where ID in
    <foreach collection="list" index="index" item="item" open="(" separator="," close=")" >
        #{item}
    </foreach>
    </delete>
</Mapper>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值