MyBatis(七) 动态SQL

1.if

方法:public List getEmpsByConditionIF(Employee employee);

sql:


    <select id="getEmpsByConditionIF" resultType="cn.edu.pzhu.cg.entities.Employee">
        select * from employee where
            <if test="id!=null">
                id=#{id}
            </if>
            <if test="lastName!=null and lastName!=''">
                and last_name like #{lastName}
            </if>
            <if test="age!=null">
                and age=#{age}
            </if>
    </select>

根据传来的参数去获取属性值,如果不为 null 就拼接在 SQL 中。

但是上面代码会出现问题:如果如果传入的对象 id 属性值为 null,那么 sql 语句将会多出一个 ‘and’ 所以需要用下面方式


    <select id="getEmpsByConditionIF" resultType="cn.edu.pzhu.cg.entities.Employee">
        select * from employee 
        <where>
            <if test="id!=null">
                id=#{id}
            </if>
            <if test="lastName!=null and lastName!=''">
                and last_name like #{lastName}
            </if>
            <if test="age!=null">
                and age=#{age}
            </if>
        </where>
    </select>


where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除

2.choose, when, otherwise

方法:public List getEmpsByChoose(Employee employee);

  有时我们不想应用到所有的条件语句,而只想从中择其一项。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。


    <select id="getEmpsByChoose" resultType="cn.edu.pzhu.cg.entities.Employee">
        select * from employee
        <where>
            <choose>
                <when test="id!=null">
                    id = #{id}
                </when>
                <when test="lastName!=null">
                    last_name like #{lastName}
                </when>
                <when test="age!=null">
                    age = #{age}
                </when>
                <otherwise>//以上属性都为null时的情况
                    email = #{email}
                </otherwise>    
            </choose>
        </where>
    </select>

以上代码表示,如果 id!= null 使用 id 去查,如果 id == null,则判断 lastName 是否为 null,不为 null 使用 lastName 去查,如果都为 null 就使用 email 属性去查询数据。

3.set

方法:public void updateEmployee(Employee employee);


    <update id="updateEmployee">
        update employee
        <set>
            <if test="lastName!=null">
                last_name = #{lastName},
            </if>
            <if test="age!=null">
                age = #{age},
            </if>
            <if test="email!=null">
                email = #{email},
            </if>
        </set>
        where id = #{id}
    </update>

动态构造更新语句:

  • 如果 if 条件成立就修改当前字段。
  • 这里,set 元素会动态前置 SET 关键字,同时也会删掉无关的逗号,因为用了条件语句之后很可能就会在生成的 SQL 语句的后面留下这些逗号。(译者注:因为用的是“if”元素,若最后一个“if”没有匹配上而前面的匹配上,SQL 语句的最后就会有一个逗号遗留)

这样当我们需要修改某条记录时,只需将要修改的信息放到对应的属性中,MyBatis 就会判断 POJO 中属性值来拼凑 update 语句,大大提升了开发效率。

4.foreach

  • collection:指定要遍历的集合,list类型的参数会特殊封装在map中,map的key就叫list。
  • item:将当前遍历出来的元素赋值给指定的变量。
  • separator:每个元素之间的分隔符。
  • open:遍历出所有的结果拼接一个开始的字符串。
  • close:遍历出的结果拼接成一个结束的字符串。
  • index:索引:
    • 遍历 list 时 index 就是索引,item 就是当前值;
    • 遍历 map 的时候,index 就是 map 的key,item 就是 map 的值。
  • 通过 #{item} 就能取出变量值。

方法:public List getEmpsByIds( @Param(“ids”) List ids );


    <select id="getEmpsByIds" resultType="cn.edu.pzhu.cg.entities.Employee">
        select * from employee where id
        <foreach collection="ids" item="item_id" separator=","
                 open="in (" close=")">
            #{item_id}
        </foreach>
    </select>

上面 sql 为:select * from employee where id in( id1, id2, id3 …);

可以利用 foreach 实现批量保存,mysql 支持 values(),(),()语法:


    <insert id="addEmps">
        insert into employee(last_name,age,email,dept_id)
        values
        <foreach collection="emps" item="emp" separator=",">
            (#{emp.lastName},#{emp.age},#{emp.email},#{emp.department.id})
        </foreach>
    </insert>

5.bind

bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:


    <select id="getEmpsTestInnerParameter" resultType="cn.edu.pzhu.cg.entities.Employee">
        <!-- 可以将 OGNL 表达式的值绑定到一个变量中,方便后面引用这个变量 -->
        <bind name="_lastName" value="'%'+lastName+'%'"/>
        select * from employee
            where last_name like #{_lastName};
    </select>

通过 bind 拼接模糊查询表达式 %lastName%,后面 sql 语句直接引用。

注意:不能直接在 sql 中拼接 %lastName% ,即如下方式是错误的:


    select * from employee
            where last_name like '%#{_lastName}%';

6._databaseId

  一个配置了“_databaseId”变量的 databaseIdProvider 可用于动态代码中,这样就可以根据不同的数据库厂商构建特定的语句。比如下面的例子:


    <select id="getEmpsTestInnerParameter" resultType="cn.edu.pzhu.cg.entities.Employee">
        <if test="_databaseId == 'mysql'">
            select * from employee
            <if test="_parameter!=null">
                where last_name like #{_lastName};
            </if>
        </if>
        <if test="_databaseId == 'oracle'">
            select seq_users.nextval from dual
        </if>
    </select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值