上一章我们已经讲完了关于Mybatis的分页用法,其实MyBatis 还具有的一个强大的特性之一通常是它的动态 SQL 能力。 如果你有使用 JDBC 或其他 相似框架的经验,你就明白要动态的串联 SQL 字符串在一起是十分纠结的,确保不能忘了空格或在列表的最后省略逗号。Mybatis中的动态 SQL 可以彻底处理这种痛苦。对于动态SQL,最通俗简单的方法就是我们自己在硬编码的时候赋予各种动态行为的判断,而在Mybatis中,用一种强大的动态 SQL 语 言来改进这种情形,这种语言可以被用在任意映射的 SQL 语句中。动态 SQL 元素和使用 JSTL 或其他相似的基于 XML 的文本处理器相似。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。

  本章中我们利用前几章构建的实例,假设几种应用情况,通过实践了解这几种动态SQL标签的用法,毕竟学习最快的途径就是动手实践~

  我们常用的几个节点元素有if,choose(when, otherwise),trim(where, if),foreach。真正使用下来我感觉有点像XSLT的用法。详细用法说明(点我)

  (1)if 的用法

   还记得上一章中我们有再ViisitMapper的分页配置中看到if节点吗,如果pageIndex>-1 and pageSize>-1的时候就加入相应的分页SQL,否则就不添加(默认取全部),如下:

<select id="getListByPagenate" parameterType="PagenateArgs"
    resultType="Visitor">
    select * from (
    <include refid="getListSql" /> <include refid="orderBySql"/>
    ) t <!-- #{}表示参数化输出,${}表示直接输出不进行任何转义操作,自己进行转移 -->
    <if test="pageStart>-1 and pageSize>-1">
        limit #{pageStart}, #{pageSize}
    </if>
</select>
<sql id="getListSql">
    select * from Visitor where
    status>0
</sql>
<sql id="orderBySql">
    order by ${orderFieldStr} ${orderDirectionStr}
</sql>

  因为我们的参数pageIndex与pageSize都是int值所以可以这样直接判断,如果是对象实例我们可以利用null判断来进行一些动态逻辑的控制,具体实际开发中就要看业务需求了。这里我认为要注意的是别十分顺手的吧and写成&&,这个在配置中不会被识别~。

  (2)choose (when, otherwise)的用法

  choose when 主要在多个条件的情况下只满足其中一个条件的应用场景中使用,例如这里就构建一个query条件,分别传递id,name与createTime。假设我们查询Visitor表时,如果VisitorId有值则,使用Id查询,如果VisitorName有值则采用VisitName查询,如下,还是在david.mybatis.demo.IVisitorOperation接口类中添加List<Visitor> getListChooseWhenDemo(BasicQueryArgs args)方法。在VisitorMapper中添加相应的的select节点配置:

package david.mybatis.demo;

import java.util.List;

import david.mybatis.model.BasicQueryArgs;
import david.mybatis.model.PagenateArgs;
import david.mybatis.model.Visitor;
import david.mybatis.model.VisitorWithRn;

public interface IVisitorOperation {
    /*
     * 添加访问者
     */
    public int add(Visitor visitor);
    
    /*
     * 删除访问者
     */
    public int delete(int id);
    
    /*
     * 更新访问者
     */
    public int update(Visitor visitor);
    
    /*
     * 查询访问者
     */
    public Visitor query(int id);
    
    /*
     * 查询List
     */
    public List<Visitor> getList();
    
    /*
     * 分页查询List
     */
    public List<Visitor> getListByPagenate(PagenateArgs args);
    
    /*
     * 分页查询List(包含Rownum)
     */
    public List<VisitorWithRn> getListByPagenateWithRn(PagenateArgs args);
    
    /*
     * 基础查询
     */
    public Visitor basicQuery(int id);
    
    /*
     * 动态条件查询(choose,when)实例
     */
    public List<Visitor> getListChooseWhenDemo(BasicQueryArgs args);
    
    /*
     * 动态条件查询(where,if)实例
     */
    public List<Visitor> getListWhereDemo(BasicQueryArgs args);
    
    /*
     * 动态查询(foreach)实例
     */
    public List<Visitor> getListForeachDemo(List<Integer> ids);
    
}
修改后的IvisitorOperation

相关文章: