mybatis高级

1.动态 SQL

2.choose 与 trim

3.where 与 set

4.bind 与 foreach

5.collection 深入学习

6.script

MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。

动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。

  1. if 语句 (简单的条件判断)
  2. choose (when,otherwize),相当于 java 语言中的 switch,与 jstl 中的 choose 很类似。
  3. trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)
  4. where (主要是用来简化 sql 语句中 where 条件判断的,能智能的处理 and or,不必担心多余导致语法错误)
  5. set (主要用于更新时)
  6. foreach (在实现 in 语句查询时特别有用)

在实际开发中我们经常封装用于包含所有查询条件的询条件类,有时条件类也可以使用 map 代替,只是使用 map 代码可读性较差。

public class ConditionPet {
    private String name;
    private int minWeight;
    private int maxWeight;
}

if 的用法
用于根据参数的条件,动态拼接 SQL。if 里面的 test 就是对应的条件,当条件满足,if 中的 SQL 就会正常拼接。
案例:

<select id="findByCondition" resultType="cn.hx.entity.Pet">
    select * from pet
    <if test="name != null and name != ''">
        where name like #{name}
    </if>
</select>

案例:

<select id="findByCondition" resultType="cn.hx.entity.Pet">
        select * from pet where true
        <if test="name != null">
          and  name = #{name}
        </if>
        <if test="minWeight != null">
           and weight >= #{minWeight}
        </if>
</select>

2.choose 与 trim

choose (when,otherwize) 相当于 java 语言中的 if-else/switch,与 jstl 中 的 choose 很类似。但是它与 if 的区别是,如下案例中三条分支语句程序只能走其中一条。

案例:

<select id="findByCondition" resultType="cn.hx.entity.Pet">
    select * from pet where
    <choose>
        <when test="name != null">
            name = #{name}
        </when>
        <when test="minWeight != null">
            weight >= #{minWeight}
        </when>
        <otherwise>
            id = 1
        </otherwise>
    </choose>
</select>

mybatis 的 trim 标签一般用于去除 sql 语句中多余的 and 关键字,逗号,或者给 sql 语句前拼接 “where“、“set“以及“values(“ 等前缀,或者添加“)“等后缀,可用于选择性插入、更新、删除或者条件查询等操作,如果要同时去除多个使用管道符连接 prefixOverrides="AND|OR"。

案例1:去除多余的 and 或者 where

select * from pet
<trim prefix="WHERE" prefixOverrides="AND">
    <if test="name != null">
        name = #{name}
    </if> 
    <if test="minWeight != null">
        AND weight >= #{minWeight}
    </if>
    <if test="maxWeight != null">
        AND weight <![CDATA[ <=]]> #{maxWeight}
    </if>
</trim>

prefix:前缀

prefixOverrides:去除 SQL 语句前面的关键字或者字符。

suffixOverrides:去除 SQL 语句结束位置的关键字或者字符。

案例2:使用 trim 标签去除结尾多余的逗号

insert into pet
<trim prefix="(" suffix=")" suffixOverrides=",">
    <if test="name != null">name,</if>
    <if test="weight != null">weight,</if>
</trim>
values
<trim prefix="(" suffix=")" suffixOverrides=",">
    <if test="name!=null">#{name},</if>
    <if test="weight!=null">#{weight},</if>
</trim>
3.where 与 set

where 会自动判断后面的条件,如果没有条件则不在 SQL 中拼接 where 关键字。同时还能自动去掉 where 最前面多出的 and 或者 or 关键字。

案例:

select * from pet
<where>
    <if test="name != null">and name like #{name}</if>
    <if test="weight != null">and weight = #{weight}</if>
</where>

与 trim 类似 set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。

案例:

update pet
<set>
    <if test="name != null">name = #{name},</if>
    <if test="weight != null">weight = #{weight},</if>
</set>
where id =#{id}

4.bind 与 foreach

bind 元素允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文。比如:

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + parameter.titie + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>

foreach 主要用于数组、集合的遍历,foreach 提供大量属性用于满足开发需求如:collection 用于指定遍历的集合名称、 item 正在遍历的那个对象、 open 遍历前拼接的字符串、 close 结束时拼接的字符串、 separator 间隔字符和 index 指定遍历的索引。

案例:

where id in
<foreach collection="ids" item="id" open="(" close=")" separator=",">
    #{id}
</foreach>

等价于

where id in (
<foreach collection="ids" item="id" separator=",">
    #{id}
</foreach>
)

5.collection 深入学习

foreach 中的 collection 在实际开发中有如下使用方法: 

  1. 如果传入的是单参数且参数类型是一个 array 数组的时候,collection 的属性值为 array
  2. 如果传入的是单参数且参数类型是一个 List 的时候,collection 属性值为 list 
  3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个 Map,当然单参数也可,如果传入的参数是多个的时候,我们也可以放在实体类中(这种实际用到也是非常多的)

1.普通数组

<select id="select" parameterType="int">
    select * from person 
    where id in
    <foreach collection="array" item="id" open="(" close=")" separator=",">
        #{id}
    </foreach>
</select>

使用时

int[] ids = {4,6};		
mapper.select(int [] ids);

2.List 集合

<select id="select" parameterType="int">
    select * from person
    where id in
    <foreach collection="list" item="id" open="(" close=")" separator=",">
        #{id}
    </foreach>
</select>

使用时

List<Integer> list = new ArrayList<Integer>();
list.add(4);
list.add(6);
mapper.select(list);

3.map 传值

<select id="select" parameterType="map">
    delete from person
    where id in
    <foreach collection="ids" item="id" open="(" close=")" separator=",">
        #{id}
    </foreach>		
</select>

使用时

Map<String,Object> map = new HashMap<String,Object>();
int[] ids = {4,6};
map.put("ids", ids);		
mapper.select(map);

6.script 

要在带注解的映射器接口类中使用动态 SQL,可以使用 script 元素。比如:

@Update({"<script>",
      "update Author",
      "  <set>",
      "    <if test='username != null'>username=#{username},</if>",
      "    <if test='password != null'>password=#{password},</if>",
      "    <if test='email != null'>email=#{email},</if>",
      "    <if test='bio != null'>bio=#{bio}</if>",
      "  </set>",
      "where id=#{id}",
      "</script>"})
void updateAuthorValues(Author author);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值