mybatis动态sql 使用解释


<select id = "foo" parameterType="Blog" resultType="Blog">
select * from t_blog where 1 = 1
<if test ="title != null">
and title = #{title}
</if>
<if test = "content != null">
and content = #{content}
</if>
<if test ="owner != null">
and owner = #{owner}
</if>
</select>
<select id = "foo" parameterType="Blog" resultType="Blog">
select * from t_blog where 1 = 1
<choose>
<when test = "title != null">
and title = #{title}
</when>
<when test = "content != null">
and content = #{content}
</when>
<otherwise>
and owner = "owner1"
</otherwise>
</choose>
</select>
<select id = "bar" resultType="Blog">
select * from t_blog where id in
<foreach collection = "array" index="index"
item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
<!-- - if - choose / when / otherwise - trim - where - set - foreach -->


mybatis动态sql中的trim标签的使用

trim标记是一个格式化的标记,可以完成set或者是where标记的功能,如下代码:

  1、

  select * from user 

  <trim prefix="WHERE" prefixoverride="AND |OR">

    <if test="name != null and name.length()>0"> AND name=#{name}</if>

    <if test="gender != null and gender.length()>0"> AND gender=#{gender}</if>

  </trim>

  假如说name和gender的值都不为null的话打印的SQL为:select * from user where    name = 'xx' and gender = 'xx'

  在红色标记的地方是不存在第一个and的,上面两个属性的意思如下:

  prefix:前缀      

  prefixoverride:去掉第一个and或者是or

 

  2、

  update user

  <trim prefix="set" suffixoverride="," suffix=" where id = #{id} ">

    <if test="name != null and name.length()>0"> name=#{name} , </if>

    <if test="gender != null and gender.length()>0"> gender=#{gender} ,  </if>

  </trim>

  假如说name和gender的值都不为null的话打印的SQL为:update user set name='xx' , gender='xx'     where id='x'

  在红色标记的地方不存在逗号,而且自动加了一个set前缀和where后缀,上面三个属性的意义如下,其中prefix意义如上:

  suffixoverride:去掉最后一个逗号(也可以是其他的标记,就像是上面前缀中的and一样)

  suffix:后缀



mybatis 实现批量更新

更新单条记录

1
UPDATE course SET name = 'course1' WHERE id = 'id1';

   更新多条记录的同一个字段为同一个值

1
UPDATE course SET name = 'course1' WHERE id in ('id1', 'id2', 'id3);    

更新多条记录为多个字段为不同的值

比较普通的写法,是通过循环,依次执行update语句。

Mybatis写法如下:

1
2
3
4
5
6
7
8
9
<update id="updateBatch"  parameterType="java.util.List">  
    <foreach collection="list" item="item" index="index" open="" close="" separator=";">
        update course
        <set>
            name=${item.name}
        </set>
        where id = ${item.id}
    </foreach>      
</update>

一条记录update一次,性能比较差,容易造成阻塞。

MySQL没有提供直接的方法来实现批量更新,但可以使用case when语法来实现这个功能。

1
2
3
4
5
6
7
8
9
10
11
12
UPDATE course
    SET name = CASE id 
        WHEN 1 THEN 'name1'
        WHEN 2 THEN 'name2'
        WHEN 3 THEN 'name3'
    END, 
    title = CASE id 
        WHEN 1 THEN 'New Title 1'
        WHEN 2 THEN 'New Title 2'
        WHEN 3 THEN 'New Title 3'
    END
WHERE id IN (1,2,3)

这条sql的意思是,如果id为1,则name的值为name1,title的值为New Title1;依此类推。

在Mybatis中的配置则如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<update id="updateBatch" parameterType="list">
            update course
            <trim prefix="set" suffixOverrides=",">
             <trim prefix="peopleId =case" suffix="end,">
                 <foreach collection="list" item="i" index="index">
                         <if test="i.peopleId!=null">
                          when id=#{i.id} then #{i.peopleId}
                         </if>
                 </foreach>
              </trim>
              <trim prefix=" roadgridid =case" suffix="end,">
                 <foreach collection="list" item="i" index="index">
                         <if test="i.roadgridid!=null">
                          when id=#{i.id} then #{i.roadgridid}
                         </if>
                 </foreach>
              </trim>
              
              <trim prefix="type =case" suffix="end," >
                 <foreach collection="list" item="i" index="index">
                         <if test="i.type!=null">
                          when id=#{i.id} then #{i.type}
                         </if>
                 </foreach>
              </trim>
       <trim prefix="unitsid =case" suffix="end," >
                  <foreach collection="list" item="i" index="index">
                          <if test="i.unitsid!=null">
                           when id=#{i.id} then #{i.unitsid}
                          </if>
                  </foreach>
           </trim>
             </trim>
            where
            <foreach collection="list" separator="or" item="i" index="index" >
              id=#{i.id}
          </foreach>
</update>

注:

MyBatis的foreach语句详解

foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有 item,index,collection,open,separator,close。item表示集合中每一个元素进行迭代时的别名,index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔 符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况 下,该属性的值是不一样的,主要有一下3种情况:
  1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
  2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
  3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在breast里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
下面分别来看看上述三种情况的示例代码:
1.单参数List的类型:  
    <select id="dynamicForeachTest" resultType="Blog">  
        select * from t_blog where id in  
        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">  
            #{item}  
        </foreach>  
    </select>  
上述collection的值为list,对应的Mapper是这样的  
public List<Blog> dynamicForeachTest(List<Integer> ids);  
测试代码:  
    @Test  
    public void dynamicForeachTest() {  
        SqlSession session = Util.getSqlSessionFactory().openSession();  
        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  
        List<Integer> ids = new ArrayList<Integer>();  
        ids.add(1);  
        ids.add(3);  
        ids.add(6);  
        List<Blog> blogs = blogMapper.dynamicForeachTest(ids);  
        for (Blog blog : blogs)  
            System.out.println(blog);  
        session.close();  
    }  
2.单参数array数组的类型:  
    <select id="dynamicForeach2Test" resultType="Blog">  
        select * from t_blog where id in  
        <foreach collection="array" index="index" item="item" open="(" separator="," close=")">  
            #{item}  
        </foreach>  
    </select>  
上述collection为array,对应的Mapper代码:  
public List<Blog> dynamicForeach2Test(int[] ids);  
对应的测试代码:  
    @Test  
    public void dynamicForeach2Test() {  
        SqlSession session = Util.getSqlSessionFactory().openSession();  
        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  
        int[] ids = new int[] {1,3,6,9};  
        List<Blog> blogs = blogMapper.dynamicForeach2Test(ids);  
        for (Blog blog : blogs)  
            System.out.println(blog);  
        session.close();  
    }  
3.自己把参数封装成Map的类型  
    <select id="dynamicForeach3Test" resultType="Blog">  
        select * from t_blog where title like "%"#{title}"%" and id in  
        <foreach collection="ids" index="index" item="item" open="(" separator="," close=")">  
            #{item}  
        </foreach>  
    </select>  
上述collection的值为ids,是传入的参数Map的key,对应的Mapper代码:  
public List<Blog> dynamicForeach3Test(Map<String, Object> params);  
对应测试代码:  
    @Test  
    public void dynamicForeach3Test() {  
        SqlSession session = Util.getSqlSessionFactory().openSession();  
        BlogMapper blogMapper = session.getMapper(BlogMapper.class);  
        final List<Integer> ids = new ArrayList<Integer>();  
        ids.add(1);  
        ids.add(2);  
        ids.add(3);  
        ids.add(6);  
        ids.add(7);  
        ids.add(9);  
        Map<String, Object> params = new HashMap<String, Object>();  
        params.put("ids", ids);  
        params.put("title", "中国");  
        List<Blog> blogs = blogMapper.dynamicForeach3Test(params);  
        for (Blog blog : blogs)  
            System.out.println(blog);  
        session.close();  
    } 

猜你喜欢

转载自blog.csdn.net/qq_37954693/article/details/80771478