Mybatis之动态sql


Mybatis之动态sql

One of the most powerful features of MyBatis has always been its Dynamic SQL capabilities.

  • MyBatis employs powerful OGNL based expressions to eliminate most of the other elements:

    • if

    • choose (when, otherwise)

    • trim (where, set)

    • foreach

Mybatis 中的sql允许我们通过某个条件动态拼接sql语句

if

比如

<select id="getUsersByConditionIf" resultType="user">
    select * from user
    where
    <if test="id!=null">
        id = #{id}
    </if>
    <if test="name!=null">
        and name = #{name}
    </if>
    <if test="password!=null">
        and password = #{password}
    </if>
    <if test="address!=null" >
        and address = #{address}
    </if>
</select>

注意:这样拼接sql会有问题 就是不写id sql语句一定不正确!

解决:

​ 方法1 :在where 后添加 1=1 每个if标签的内容全写为and xxx=#{xxx}形式

​ 方法2 : 使用Mybatis的where标签 优雅推荐

<where>
    <if test="id!=null">
        id = #{id}
    </if>
    <if test="name!=null">
        and name = #{name}
    </if>
    <if test="password!=null">
        and password = #{password}
    </if>
    <if test="address!=null" >
        and address = #{address}
    </if>
</where>

​ 方法3: 通过标签 设置前缀后缀来解决

choose

只会选择其中的一条语句 有点想java中的switch case break

<select id="getUsersByConditionChoose" resultType="user">
    select * from user
    where
    <choose>
        <when test="id!=null">
            id = #{id}
        </when>
        <when test="name!=null">
            name = #{name}
        </when>
        <when test="password!=null">
            password = #{password}
        </when>
        <otherwise>
            1 = 1
        </otherwise>
    </choose>
</select>

set

<update id="updateUserByConditionSet" >
    update user
    <set>
        <if test="name!=null">
            name = #{name},
        </if>
        <if test="password!=null">
            password = #{password}
        </if>
    </set>
    where id = #{id}
</update>

同理 写入set标签可以自动修改后缀

也可以使用trim标签

<trim prefix="set" suffixOverrides=",">
    <if test="name!=null">
      name = #{name},
    </if>
    <if test="password!=null">
      password = #{password}
    </if>
</trim>

foreach

如果是集合类型的参数 也会被mybatis 封装成map

Key: Collection ——> collection

​ list ——> list

​ array ——> array

foreach标签:
​ collection:指定要遍历的集合的名称
​ item:指定集合中每个元素个体的名称
​ separator: 元素间的分隔符
​ open:拼接好的字符串前缀
​ close: 拼接好的字符串后缀

<select id="getUserByLists"  resultType="user">
    select * from user where name in
    <foreach collection="list" item="ofName" separator="," 											open="(" close=")">
        #{ofName}
    </foreach>
</select> 

批量更新

void insertBatchUser(@Param("users") List<User> users);
<insert id="insertBatchUser">
    insert into user (name,password,address_id) values
    <foreach collection="users" item="user" separator=",">
        (#{user.name},#{user.password},#{user.address.id})
    </foreach>
</insert>

也可以通过拼接成多条insert语句实现

<!--方法2 要求mysql连接 支持多重查询  需要在url中将alllowMultQueries设置为true-->
<insert id="insertBatchUser">
    <foreach collection="users" item="user" separator=";">
        insert into user (name,password,address_id) values(#{user.name},#{user.password},#{user.address.id})
    </foreach>
    
</insert>

bind

可以将ognl表达式 绑定为一个变量 使用这个变量相当于使用表达式

<select id="getUsersByWord" resultType="user">
    <bind name="_word" value ="word+'%'" />
    select * from user where name like #{_word};
</select>

sql

可以将sql语句封装为一个变量sql语句,使用时通过引用就可以用

注意:若在sql标签内定义了property 取值的时候 要用**${}**


文章作者: Bxan
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Bxan !
  目录