mybatis动态Sql标签应用

Mybatis动态sql是做什么的

传统使用JDBC方法,大家在写复杂Sql时,需手动拼接,繁锁而且容易出错,而MyBatis的动态sql正是为了解决这种场景问题,具体通过if, choose, when, otherwise, trim, where, set 等标签,灵活组装动态sql,从而提高开发效率

动态sql标签有哪些种呢?

mybatis提供以下9种动态sql标签

if choose whenotherwisetrim
wheresetforeach  bind


动态SQL标签应用

<if/>用于判断 条件 如java中的if作用类似 我们看下例子:


<select id="findByCondition" parameterType="user" resultType="user">select * from User where<if test="id !=null">   id = #{id}</if>  and username = "zhangsan"</select>

上面例子:不难发现 如果id不等于null,才会拼接:id = #{id} ,再细品一下 如果id =null Sql不就变成了这样吗:

select * from user where and username = 'zhangsan'

where 后面多了个 and怎么处理呢


好,为了解决Sql拼接问题<where>标签就开始登场了



<select id="findByCondition" parameterType="user" resultType="user">select * from User<where>  <if test="id !=null">       id = #{id}  </if>      and username = "zhangsan"</where></select>

仔细一看,就是多了个where标签而已!是的,而实质上,mybatis是对它做了处理,当它遇到AND或者OR这些,从而做出正确识别处理。


trim 会不会比where更灵活些呢:

    是一个格式化标签,主要有4个参数:

    prefix(前缀);

    prefixOverrides(去掉第一个标记);

    suffix(后缀);

    suffixOverrides(去掉最后一个标记);



<select id="findByCondition" parameterType="user" resultType="user">select * from User<trim prefix="WHERE" prefixOverrides="AND |OR ">  <if test="id !=null">       id = #{id}  </if>      and username = "zhangsan"</trim></select>

从上面可以看出:当WHERE后紧随AND或则OR的时候,就去除AND或者OR。除了WHERE以外, 其实还有一个比较经典的实现,那就是SET。


咱们在说说Set标签,直接上案例:



<update id="updateUser" parameterType="user">update User set<if test="id != null">    id = #{id},</if><if test="userName != null">    userName = #{userName}</if><where>    <if test="id != null">        id = #{id}    </if></where></update>


问题又来了:如果我只有id不为null,  那么这SQL不就成了

update User set id =#{id}, where ...

 那么id后面那逗号会导致出错的呀!

是的,这时mybatis提供的set标签就登场啦:改造一下如下:



<update id="updateUser" parameterType="user">update User<set>  <if test="id != null">      id = #{id},  </if>  <if test="userName != null">      userName = #{userName}  </if></set><where>  <if test="id != null">      id = #{id}  </if></where></update>


额看似完美,是否还可以有其它方式实现呢,前面有讲到,trim也是可以做到的哦~ 上案例:



<update id="updateUser" parameterType="user">update User<trim prefix="SET" suffixOverrides=",">  <if test="id != null">      id = #{id},  </if>  <if test="userName != null">      userName = #{userName}  </if>        </trim><where>  <if test="id != null">      id = #{id}  </if></where></update>

WHERE用的是 prefixOverrides(前缀), SET用的是suffixOverrides (后缀),看懂了吧!


5. foreach: 循环 ,java中有for, 我有foreach!

mybatis中有foreach, 可通过它实现循环,循环的对象当然主要是java容器和数组。

foreach:循环 id in separator分割 直接上案例:



<selectid="findByIds" parameterType="list" resultType="user"><include refid="selectUser"></include><where>    <foreach collection="array" open="id in (" close=")" item="id" separator=",">        #{id}    </foreach></where></select>


choose:  Java中有switch,  mybatis有choose

话不多少直接上案例:




 <select id="findByConditionList" parameterType="user" resultType="user">select * from User<where><choose>    <when test="id!=null">        AND id=#{id}    </when>    <when test="userName!=null">        AND userName=#{userName}    </when>    <when test="id!=null and userName!=null">       and id=#{id} and userName={#userName}    </when>    <otherwise>        AND id=1 and userName='zhangsan'    </otherwise></choose></where></select>

从上例子可以看出:当id和username都不为null的时候, 那么选择二选一(前者优先), 如果都为null, 那么就选择 otherwise中的, 如果id和username只有一个不为null, 那么就选择不为null的那个。

 

补充:mybatis官网《MyBatis 官方文档 —— 动态 SQL》 。

https://mybatis.org/mybatis-3/zh/dynamic-sql.html