Mybatis中的动态sql(if&where/sql片段/foreach)

1、sql标签

重复的sql语句永远不可以避免,标签就是用来解决这个问题的。sql标签可以提高代码的可重用性。具体方法就是将常用的字段,sql代码封装进SQL标签中,在后面的配置中,当需要使用的时候,通过标签来指定所要使用的封装好的sql标签代码。
具体代码如下:

<!--将常用的字段写进sql字段里面-->
 <sql id="userinfo">id,username,birthday,sex,address</sql>

 <select id="findByid" parameterType="int" resultType="com.zwj.model.User">
      <!--在后面需要使用的时候直接通过include标签来使用-->
        select <include refid="userinfo"></include> from user
        where id=#{id};
    </select>

<select id="findUser" parameterType="com.zwj.VO.FindByIdByVo" resultMap="findUserMap">
       <!--在后面需要使用的时候直接通过include标签来使用-->
        select <include refid="userinfo"></include> from user where id=#{user.id}
    </select>

2、if/where标签

我觉得这对标签是很好的体现了动态sql的。
if标签:作为判断传入参数来使用的,如果符合条件(比如不为空,有参数),就把if标签体内的sql拼接上。不符合的话,就会自动把该条件去掉。
注意!用if进行判断是否为空时,不仅要判断null,也要判断空字符串
where标签:if标签是在where标签里面进行判断的,where和sql中的where一样,用于写选择条件。使用如下图所示:

包装类:

package com.zwj.VO;

import com.zwj.model.User;

import java.util.List;

public class findByVo{
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

接口方法:

public List<User> findBydramatic(findByVo findbyvo);

映射文件:

<select id="findBydramatic" parameterType="com.zwj.VO.findByVo" resultType="user">
        select * from user
        <where>
            <if test="user!=null">
                <if test="user.sex!=null and user.sex!=''">
                    sex=#{user.sex}
                </if>
                <if test="user.username!=null and user.username!=''">
                    and username like '%${user.username}%'
                </if>
            </if>
        </where>
    </select>

如果加上sql标签,使用如下(我的理解理解就是等价替换,把你想换掉的代码段拿到sql标签,在这段代码想用的时候,用上include标签)

<sql id="sqlcut" >
        <if test="user!=null">
            <if test="user.sex!=null and user.sex!=''">
                sex=#{user.sex}
            </if>
            <if test="user.username!=null and user.username!=''">
                and username like '%${user.username}%'
            </if>
        </if>
    </sql>

    <select id="findBydramatic" parameterType="com.zwj.VO.findByVo" resultType="user">
        select * from user
        <where>
            <include refid="sqlcut"></include>
        </where>
    </select>

测试代码段:
@Test
public void test2(){

    UserMapper userMapper=session.getMapper(UserMapper.class);
    findByVo query2=new findByVo();
    User user=new User();
    user.setSex("1");
    //user.setUsername("陈");加上这句,查出的就是所有姓陈的并且性别为1
    的用户
    query2.setUser(user);
    List<User> user2=userMapper.findBydramatic(query2);
    System.out.println("查出的用户有:"+user2);
    //session.commit();
}

测试结果就是查出所有性别为1的用户。

3、foreach标签

foreach标签主要的属性有
(1)collection:传进来的集合参数的名称
(2)item:实体类中对应的属性值(依次从集合中取值赋给item)
(3)open:表示遍历的开始的地方
(4)close:标识遍历结束的地方
(5)separator:每次遍历之间的分隔符

包装类:

package com.zwj.VO;

import com.zwj.model.User;

import java.util.List;

public class findByVo{
    private User user;
    private List<Integer> Ids;

    public List<Integer> getIds() {
        return Ids;
    }

    public void setIds(List<Integer> ids) {
        Ids = ids;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
}

接口方法:

public List<User> findByIds(findByVo findbyvo);

映射文件:

<select id="findByIds" parameterType="com.zwj.VO.findByVo" resultType="user">
        select * from user
        <where>
            <if test="Ids!=null and Ids.size>0">
                <foreach collection="Ids" item="id" open="id in ( " close=")" separator=",">
                    ${id}
                </foreach>
            </if>

        </where>
    </select>

测试

@Test
    public void test3(){

        UserMapper userMapper=session.getMapper(UserMapper.class);
        findByVo query3=new findByVo();
        List<Integer> ids=new ArrayList<Integer>();
        ids.add(24);
        ids.add(25);
        ids.add(26);
        query3.setIds(ids);
        List<User> user2=userMapper.findByIds(query3);
        System.out.println("查出的用户有:"+user2);
        //session.commit();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值