Mybatis xml mapper 特殊写法总结

  项目告一段落,业务代码也写得差不多了,框架仍然用的是 ssm ,为了省去单表数据库操作的代码编写,继续用 mybatis generator 生成单表对应的实体类、dao层映射关联及配置文件,私下还尝试了几个实现批量插入,翻页查询及实体类序列化的插件,还是很奏效的。下面着重介绍一下近期开发中常见的 mybatis xml 中的特殊写法。

1. 关于 >,< 比较运算符的使用

  一种写法是直接将 > 换成 &gt; 把 < 换成 &lt; 

        <if test="start != null">
          AND call_time &gt;= #{start}
        </if>
        <if test="end != null">
          AND call_time &lt;= #{end}
      </if>

  另一种写法是用 <![CDATA[ *** ]]> 将 sql 包起来:

        <![CDATA[
        and create_time >= #{start}
        ]]>

 2. 实现模糊查询 like 

  一种是比较规矩一点的写法,用 <bind name=" *** " value = " *** " />  实现 like 子句的绑定:

    <if test="secretId != null and secretId != ''">
      <bind name="pattern" value="'%' + secretId + '%'" />
      and secret_id like #{pattern}
    </if>

  注意将 <bind .../> 写在条件判断里面,否则当 secretId 为 null 的时候是会出异常的。

  另一种比较简单粗暴,直接写为 '%${like_clause}%' 放到语句中:

    <if test="batchNo != null and batchNo != ''">
        WHERE batch_no LIKE '%${batchNo}%'
    </if>

 3. IF(***,***,***) 这样的 mysql 函数在 mybatis 中无效:

   <select id="getCallerItems" parameterType="java.lang.String">
    SELECT a.account AS name,
    IF(tmp1.calledNum IS NULL,0,tmp1.calledNum),
    IF(tmp2.ownedCallNum IS NULL,0,tmp2.ownedCallNum)
    FROM account a LEFT JOIN (
        SELECT COUNT(*) AS calledNum,`owner`
        FROM secret_pool
        WHERE `status` = 0
        <if test="batchNo !=null">
            and batch_no = #{batchNo}
        </if>
        AND call_round > 0
        GROUP BY `owner`
    )tmp1 ON a.account = tmp1.`owner` LEFT JOIN (
        SELECT COUNT(*) AS ownedCallNum,`owner`
        FROM secret_pool
        WHERE `status` = 0
        <if test="batchNo !=null">
            and batch_no = #{batchNo}
        </if>
        GROUP BY `owner`
    )tmp2 ON a.account = tmp2.`owner`
  </select>

    这里我是想用将外连接中因匹配不到对应结果而产生的 null 替换成 0 ,结果非但没有替换成功还查不出正确的结果,心塞。

4. <where>,<choose>,<foreach> 标签的应用:

  <where></where> 广泛用于非必传参数的条件查询;

  mybatis 中没有表示 else if 的标签,可用<choose> 配合 <otherwise> 来代替;

  <foreach> 在传入参数包含集合的时候可用到;

    <select id="selectByPagination" resultMap="BaseResultMap" parameterType="bz.sunlight.dto.UserSearchDTO">
        SELECT u.* FROM `user` u
        LEFT JOIN user_role ur ON u.Id = ur.User_Id
        LEFT JOIN role r ON ur.Role_Id = r.Id
        <where>
            <if test="name != null and name != ''">
                u.`Name` LIKE '%${name}%'
            </if>
            <if test="status != null">
                AND u.Status = #{status}
            </if>
            <if test="roleId != null">
                AND r.Id IN
                <foreach item="item" collection="roleIds" separator="," open="(" close=")" index="">
                    #{item, jdbcType=VARCHAR}
                </foreach>
            </if>
        </where>
        <if test="sortField != null and sortField != ''">
            ORDER BY
            <choose>
                <when test="isDesc != null and isDesc"> ${sortField} DESC </when>
                <otherwise> ${sortField} </otherwise>
            </choose>
        </if>
        <if test="pageSize != null">
            <if test="offset != null">
                limit ${offset}, ${pageSize}
            </if>
            <if test="offset == null">
                limit ${pageSize}
            </if>
        </if>
    </select>

 

  其实说到底,不管哪种写法都是为了实现一条 sql 语句,后台开发核心还是 sql ,即使框架用得再熟,如果对理解不透数据模型不能高效地查出准确的结果,什么高大上的实现方式都是花架子,至于到底选择哪种写法,个人觉得越简单越好。我虽然在上面列举了不同的实现方式都因为在对的时间遇到了不一定对的它,记下来缅怀那段邂逅。

posted @ 2017-07-18 11:49  笑叹词穷  阅读(3064)  评论(0编辑  收藏  举报