Mybatis 的动态SQL

Mybatis 的映射文件中,平常写的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL是动态变化的,此时我们的简单 SQL 就不能满足要求了,以下就简单讲解常用的几个动态SQL的标签。

【动态 SQL 之if标签】

1.目标

我们根据实体类的不同取值,使用不同的 SQL 语句来进行查询。
比如在 id 如果不为空时可以根据 id查询,如果 username 不为空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到

2.讲解

  • QueryVo.java

它的作用专门是用来包装查询参数的。

@AllArgsConstructor
@NoArgsConstructor
@Data
public class QueryVo implements Serializable {

    //封装查询对象(参数)
    private User user;
}
  • UserDao.java
public interface UserDao {
    /**
     * 根据用户名和用户Id查询用户列表
     */
    List<User> findUserListByQueryVo(QueryVo queryVo);
}
  • UserDao.xml
<!--根据包装类对象 条件进行查询用户列表-->
    <select id="findUserListByQueryVo" resultType="User">
        select * from t_user where 1=1
        <!--根据判断传入的参数是否为null 来进行查询条件的拼接-->
        <if test="user!=null and  user.uid>0">
            and uid=#{user.uid}
        </if>
        <if test="user!=null and user.username!=null and user.username.length>0">
            and username like concat('%',#{user.username},'%')
        </if>
    </select>
  • 测试
@Test
    public void findAllTest01(){
        //1.获取sqlSession对象
        SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();
        //2.获取dao接口实例
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //3.调用方法
        QueryVo queryVo = new QueryVo();
        //设置查询参数
        User user = new User();
        //user.setUid(3);
        user.setUsername("w");
        queryVo.setUser(user);


        List<User> list = userDao.findUserListByQueryVo(queryVo);
        System.out.println("list = " + list);
        //4.提交事务  关闭对象
        SqlSessionFactoryUtils.commitAndClose(sqlSession);
    }

3.小结

a. if适合动态多条件查询
b. 注意
在这里插入图片描述

【动态 SQL 之where标签】

1.目标

为了简化上面 where 1=1 的条件拼装,我们可以采用标签来简化开发。

2.讲解

修改 UserDao.xml 映射文件如下:

<!--根据包装类对象 条件进行查询用户列表-->
    <select id="findUserListByQueryVo2" resultType="User">
        select * from t_user
        <!--where 表示它里面就进行条件的拼接  自动识别条件拼接  如果有多余的关键字 and、or会自动去除
            注意:where只会自动去除多余的关键字  不会自动添加  所以在编写sql语句时关键字and、or不能省略
        -->
        <where>
            <!--根据判断传入的参数是否为null 来进行查询条件的拼接-->
            <if test="user!=null and  user.uid>0">
                and uid=#{user.uid}
            </if>
            <if test="user!=null and user.username!=null and user.username.length>0">
                and username like concat('%',#{user.username},'%')
            </if>
        </where>
    </select>

注意: <where />可以自动处理第一个 and

3.小结

a. where标签用在自己写sql语句时 where关键字不好处理的情况下代替where 1= 1
b. 注意:where只会自动去除多余的关键字但是不会自动添加,所以在编写sql语句时关键字and、or不能省略

【动态标签之foreach标签】

1.目标

foreach标签用于遍历集合,实际开发中会经常用到,属性值多了的话还是难记住

2.讲解

2.1需求
  • 传入多个 id 查询用户信息,用下边sql 实现:
select uid ,username ,birthday ,sex, address from t_user WHERE username LIKE '张%' AND (uid =1 OR uid =2 OR uid=6)

这样我们在进行范围查询时,就要将一个集合中的值,作为参数动态添加进来。这样我们将如何进行参数的传递?

  • 在QueryVo.java 添加一个集合
public class QueryVo implements Serializable {

    //封装查询对象(参数)
    private User user;

    private List<Integer> ids;
}
  • UserDao.java
	/**
     * 根据用户名和用户Id列表查询用户
     */
    List<User> findUserListByQueryVo3(QueryVo queryVo);
  • UserDao.xml
<!--根据用户名和用户Id列表查询用户-->
    <select id="findUserListByQueryVo3" parameterType="QueryVo" resultType="User">
        SELECT uid ,username ,birthday ,sex, address FROM t_user
	        <where>
                <if test="user!=null and user.username!=null and user.username.length>0">
                    and username like concat('%',#{user.username},'%')
                </if>
                <if test="ids!=null and ids.size>0">
                    and uid IN
                    <!--
                        foreach标签:循环遍历集合参数  进行sql语句拼接
                            collection:你要遍历的集合数据
                            open:表示拼接的内容以什么开头
                            close:表示拼接的内容以什么结尾
                            separator:表示遍历元素以什么进行分隔
                            item:就是集合遍历的每一个元素
                    -->
                    <foreach collection="ids" open="(" close=")" separator="," item="id">
                        #{id}
                    </foreach>
                </if>
            </where>

    </select>
  • 测试
// 需求:查询姓张的并且uid为1 2 6 的用户
    @Test
    public void findAllTesForeach(){
        //1.获取sqlSession对象
        SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSession();
        //2.获取dao接口实例
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        //3.调用方法
        QueryVo queryVo = new QueryVo();
        //设置查询参数
        User user = new User();
        user.setUsername("张");

        List<Integer> ids = new ArrayList<Integer>();
        ids.add(1);
        ids.add(2);
        ids.add(6);

        queryVo.setUser(user);
        queryVo.setIds(ids);

        List<User> list = userDao.findUserListByQueryVo3(queryVo);
        System.out.println("list = " + list);
        //4.提交事务  关闭对象
        SqlSessionFactoryUtils.commitAndClose(sqlSession);
    }

3.小结

foreach标签用于遍历集合,它的属性:

  • collection:代表要遍历的集合元素,注意编写时不要写#{}
  • open:代表语句的开始部分(一直到动态的值之前)
  • close:代表语句结束部分
  • item:代表遍历集合的每个元素,生成的变量名(随便取)
  • sperator:代表分隔符 (动态值之间的分割)
    在这里插入图片描述

【SQL 片段 】

1.目标

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。我们先到 UserDao.xml 文件中使用标签,定义出公共部分。

2.讲解

  • 使用sql标签抽取
   <!--提取共性的sql语句,把这些共性的sql语句称之为 sql片段-->
   <sql id="selectUser">
        SELECT username,address FROM t_user
    </sql>
  • 使用include标签引入使用
<!--根据用户名和用户Id列表查询用户-->
    <select id="findUserListByQueryVo3" parameterType="QueryVo" resultType="User">
            <include refid="selectUser"></include>
	        <where>
                <if test="user!=null and user.username!=null and user.username.length>0">
                    and username like concat('%',#{user.username},'%')
                </if>
                <if test="ids!=null and ids.size>0">
                    and uid IN
                    <!--
                        foreach标签:循环遍历集合参数  进行sql语句拼接
                            collection:你要遍历的集合数据
                            open:表示拼接的内容以什么开头
                            close:表示拼接的内容以什么结尾
                            separator:表示遍历元素以什么进行分隔
                            item:就是集合遍历的每一个元素
                    -->
                    <foreach collection="ids" open="(" close=")" separator="," item="id">
                        #{id}
                    </foreach>
                </if>
            </where>
    </select>
  • 整个图示
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夏目不听话

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值