【Mybatis 学习】Mybatis 的动态 SQL 语句

Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL 是动态变化的,此时在前面的学习中我们的 SQL 就不能满足要求了。

一、动态 SQL 之if标签

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

<select id="findByCondition" resultType="User" parameterType="User">
        select * from user where  1=1
        <if test="username !=null and username !=''">
            and username like #{username}
        </if>
        <if test="address !=null">
            and address like #{address};
        </if>
</select>

注意: 标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法。
另外要注意 where 1=1 的作用!

 @Test
    public void testFindByCondition() {
        //5.使用代理对象执行方法
        User u = new User();
        u.setUsername("%王%");
        u.setAddress("%北京%");
        List<User> users = userDao.findByCondition(u);
        for (User user :users) {
            System.out.println(user);
        }
    }

二、动态 SQL 之where标签

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

<select id="findByCondition" resultType="User" parameterType="User">
        select * from user
        <where>
            <if test="username !=null and username !=''">
                and username like #{username}
            </if>
            <if test="address !=null">
                and address like #{address};
            </if>
        </where>
    </select>

三、动态标签之foreach标签

传入多个 id 查询用户信息,用下边两个 sql 实现:

SELECT * FROM USERS WHERE username LIKE '%张%' AND (id =10 OR id =89 OR id=16)
SELECT * FROM USERS WHERE username LIKE '%张%' AND id IN (10,89,16)

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

 <select id="findUserInIds" resultType="User" parameterType="QueryVo">
        <include refid="defaultUser"></include>
        <where>
            <if test="ids !=null and ids.size()>0">
                <foreach collection="ids" open="id in (" close=")" item="id" separator=",">
                    #{id}
                </foreach>
            </if>
        </where>
    </select>
<foreach>标签用于遍历集合,它的属性:
	collection:代表要遍历的集合元素,注意编写时不要写#{}
	open:代表语句的开始部分
	close:代表结束部分
	item:代表遍历集合的每个元素,生成的变量名,需要和#{item}名称对应
	sperator:代表分隔符
 @Test
    public void testFindByQueryVo() {
        //5.使用代理对象执行方法
        QueryVo queryVo = new QueryVo();
        ArrayList<Integer> list = new ArrayList<>();
        list.add(41);
        list.add(42);
        list.add(43);
        queryVo.setIds(list);
        List<User> users = userDao.findUserInIds(queryVo);
        for (User u : users) {
            System.out.println(u);
        }
    }

1. 实现批量删除

/**
 * 通过数组实现批量删除
 */
int deleteMoreByArray(@Param("sids") Integer[] sids);
<delete id="deleteMoreByArray">
    delete from stu where sid in
    <foreach collection="sids" item="sid" separator="," open="(" close=")">
        #{sid}
    </foreach>
</delete>

另外一种写法:

<!--int deleteMoreByArray(@Param("sids") Integer[] sids);-->
<delete id="deleteMoreByArray">
    delete from stu where
    <foreach collection="sids" item="sid" separator="or">
        sid = #{sid}
    </foreach>
</delete>
@Test
public void testDeleteMoreByArray(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
    int result = mapper.deleteMoreByArray(new Integer[]{11, 12, 13});
    System.out.println(result);
}

在这里插入图片描述
第二种方式的SQL语句执行结果:
在这里插入图片描述

2. 实现批量增加

/**
* 通过list集合实现批量添加
*/
int insertMoreByList(@Param("stus") List<Student> stus);
<!--int insertMoreByList(@Param("stus") List<Student> stus);-->
<insert id="insertMoreByList">
  insert into stu values
  <foreach collection="stus" item="stu" separator=",">
      (#{stu.sid},#{stu.sname},#{stu.score},null)
  </foreach>
</insert>
@Test
public void testInsertMoreByList(){
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
    Student stu1 = new Student().setSid(11).setSname("11").setScore(11);
    Student stu2 = new Student().setSid(12).setSname("12").setScore(12);
    Student stu3 = new Student().setSid(13).setSname("13").setScore(13);
    List<Student> stus = Arrays.asList(stu1, stu2, stu3);
    System.out.println(mapper.insertMoreByList(stus));
}

在这里插入图片描述

四、Mybatis 中简化编写的 SQL 片段

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。

<!-- 抽取重复的语句代码片段 -->
<sql id="defaultSql">
select * from user
</sql>

在这里插入图片描述
比如查询语句:select sid,sname,score from stu

可以简化为:将 sid,sname,score 抽取出来

<sql id="stuColumns">sid,sname,score</sql>
select <include refid="stuColumns"></include> from stu

五、trim 标签

若标签中有内容时:
prefix|suffix:将 trim 标签中内容前面或后面添加指定内容
suffixOverrides|prefixOverrides:将trim标签中内容前面或后面去掉指定内容
若标签中没有内容时,trim 标签也没有任何效果

如果不加 trim,则一旦出现某个字段为空, and 和 or 就会拼接错误
在这里插入图片描述

/**
 * 多条件查询
 */
List<Student > getStuByCondition(Student student);
<!--List<Student> getStuByCondition(Student student);-->
    <select id="getStuByCondition" resultType="Student">
        select * from stu
        <trim prefix="where" suffixOverrides="and|or">
            <if test="sid != null and sid != ''">
                sid = #{sid} and
            </if>
            <if test="sname != null and sname != ''">
                sname = #{sname} or
            </if>
            <if test="score != null and sex != ''">
                score = #{score} and
            </if>
        </trim>
    </select>
	@Test
    public void testGetStuByCondition(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        List<Student> list = mapper.getStuByCondition(new Student(4, "Max", null));
        System.out.println(list);
    }

在这里插入图片描述

六、choose、when、otherwise 标签

choose、when、otherwise,相当于if...else if...else

when至少要有一个,otherwise最多只能有一个

	/**
     * 测试choose、when、otherwise
     */
    List<Student> getStuByChoose(Student student);
<!--List<Student> getStuByChoose(Student student);-->
    <select id="getStuByChoose" resultType="Student">
        select * from stu
        <where>
            <choose>
                <when test="sid != null and sid != ''">
                    sid = #{sid}
                </when>
                <when test="sname != null and sname != ''">
                    sname = #{sname}
                </when>
                <when test="score != null and score != ''">
                    score = #{score}
                </when>
                <otherwise>
                    sid = 5
                </otherwise>
            </choose>
        </where>
    </select>
@Test
    public void testGetStuByChoose(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
        List<Student> list = mapper.getStuByChoose(new Student(null, "", null));
        System.out.println(list);
    }

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

南淮北安

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

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

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

打赏作者

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

抵扣说明:

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

余额充值