Mybatis学习笔记--(二)动态SQL

本文为how2java Mybatis教程的学习笔记,原教程链接如下:http://how2j.cn/k/mybatis/mybatis-tutorial/1087.html#nowhere

if 标签

背景

假设需要对Product执行两条sql语句,一个是查询所有,一个是根据名称模糊查询。那么按照现在的方式,必须提供两条sql语句:listProduct和listProductByName。然后在调用的时候,分别调用它们来执行。如下所示:
Product.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.how2java.pojo">
        <select id="listProduct" resultType="Product">
            select * from product_          
        </select>
        <select id="listProductByName" resultType="Product">
            select * from product_  where name like concat('%',#{name},'%')         
        </select>

    </mapper>

调用:

System.out.println("查询所有的");
List<Product> ps = session.selectList("listProduct");
for (Product p : ps) {
    System.out.println(p);
}

System.out.println("模糊查询");
List<Product> ps2 = session.selectList("listProductByName","a");
for (Product p : ps2) {
    System.out.println(p);
}  

如果Product的字段比较多的话,为了应付各个字段的查询,那么就需要写多条sql语句,这样就变得难以维护。
这个时候,就可以使用Mybatis 动态SQL里的if标签。

使用if标签

Product.xml:

...
<select id="listProduct" resultType="Product">
    select * from product_
    <if test="name!=null">
        where name like concat('%',#{name},'%')
    </if>           
</select>
...

调用:

System.out.println("查询所有的");
List<Product> ps = session.selectList("listProduct");
for (Product p : ps) {
    System.out.println(p);
}

System.out.println("模糊查询");
Map<String,Object> params = new HashMap<>(); 
params.put("name","a");
List<Product> ps2 = session.selectList("listProduct",params);
for (Product p : ps2) {
    System.out.println(p);
}  

如果没有传参数name,那么就查询所有,如果有name参数,那么就进行模糊查询。这样只需要定义一条sql语句即可应付多种情况了。
运行结果:

这里写图片描述

where、 set、 trim 标签

背景

利用if标签,如果要进行多条件判断,就会写成这样:

<select id="listProduct" resultType="Product">
    select * from product_
    <if test="name!=null">
        where name like concat('%',#{name},'%')
    </if>           
    <if test="price!=0">
        and price > #{price}
    </if>           
</select>

这么写的问题是:当没有name参数,却有price参数的时候,执行的sql语句就会是:

select * from product_ and price > 10

这句SQL是有语法错误的(多了一个and),不能执行。

使用where标签

select语句出现的上述问题可以通过where标签来解决:

<select id="listProduct" resultType="Product">
    select * from product_
    <where>
        <if test="name!=null">
            and name like concat('%',#{name},'%')
        </if>           
        <if test="price!=null and price!=0">
            and price > #{price}
        </if>   
    </where>        
</select>

where标签会进行自动判断

  • 如果任何条件都不成立,那么就在sql语句里就不会出现where关键字
  • 如果有任何条件成立,会自动去掉多出来的 and 或者 or

下面的测试代码无论加不加注释都可以正确执行:

System.out.println("多条件查询");
Map<String,Object> params = new HashMap<>(); 
//params.put("name","a");
//params.put("price","10");
List<Product> ps2 = session.selectList("listProduct",params);
for (Product p : ps2) {
    System.out.println(p);
}

使用set标签

与where标签类似的,在update语句里也会碰到多个字段相关的问题。 在这种情况下,就可以使用set标签

...
<update id="updateProduct" parameterType="Product" >
    update product_ 
    <set>
        <if test="name != null">name=#{name},</if>
        <if test="price != null">price=#{price}</if>

    </set>

     where id=#{id}    
</update>
...

使用trim标签

trim 用来定制想要的功能,可以替换上面的where标签和set标签。
替换where标签:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ... 
</trim>

替换set标签:

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

用trim标签的Product.xml:

<select id="listProduct" resultType="Product">
    select * from product_
    <trim prefix="WHERE" prefixOverrides="AND |OR ">
        <if test="name!=null">
            and name like concat('%',#{name},'%')
        </if>         
        <if test="price!=null and price!=0">
            and price > #{price}
        </if> 
    </trim>       
</select>

<update id="updateProduct" parameterType="Product" >
    update product_ 
    <trim prefix="SET" suffixOverrides=",">
        <if test="name != null">name=#{name},</if>
        <if test="price != null">price=#{price}</if>

    </trim>

    where id=#{id}    
</update>

choose、 when、 otherwise 标签

Mybatis里面没有else标签,但是可以使用choose when otherwise标签来达到if else的效果

...
<select id="listProduct" resultType="Product">
     SELECT * FROM product_ 
     <where>
         <choose>
             <when test="name != null">
                 and name like concat('%',#{name},'%')
             </when>           
             <when test="price !=null and price != 0">
                 and price > #{price}
             </when>                 
             <otherwise>
                 and id >1
             </otherwise>
         </choose>
    </where>
</select>
...

上述代码的效果是: 如果提供了任何条件,就进行条件查询,否则就使用id>1这个条件。

foreach 标签

foreach标签通常用于in 这样的语法里

<select id="listProduct" resultType="Product">
      SELECT * FROM product_ 
        WHERE ID in
            <foreach item="item" index="index" collection="list"
                open="(" separator="," close=")">
                #{item}
            </foreach>
</select> 

测试代码:

List<Integer> ids = new ArrayList();
ids.add(1);
ids.add(3);
ids.add(5);

List<Product> ps = session.selectList("listProduct",ids);
for (Product p : ps) {
    System.out.println(p);
}

把类似如下sql:select * from product_ where id in (‘1’,’3’,’5’)中in 后面的 (‘1’,’3’,’5’)拆成open=”(” separator=”,” close=”)”这种写法,open=’(‘代表in后面的开始的括号,close=’)’代表结束的括号,而seperator=’,’则代表括号里面数据的分隔符,那么具体的1,3,5则用占位符#{item}进行替换。

bind 标签

bind标签就像是再做一次字符串拼接,方便后续使用。
原来的模糊查询:

<select id="listProduct" resultType="Product">
    select * from   product_  where name like concat('%',#{0},'%')
</select>

使用bind标签的模糊查询:

<select id="listProduct" resultType="Product">
    <bind name="likename" value="'%' + name + '%'" />
    select * from   product_  where name like #{likename}
</select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值