Mybatis | 05 Mybatis动态SQL语句

Mybatis动态SQL语句

1. 动态SQL语句

1.1 什么是动态SQL

动态SQL语句是Mybatis的重要特性

在遇到较为复杂的SQL语句时,需要进行SQL拼接,动态SQL可以简化拼接SQL的操作并避免错误

1.2 动态SQL常用标签

  • if
  • where
  • foreach
  • trim
  • when
  • set
  • choose

目前使用到前3个后续继续补充

2. < if >

目的:**根据所给条件动态拼接**SQL进行查询

这里的条件可能有可能没有可能是某一个属性,也可能是多个属性组合

2.1 相关准备

  • 新增DAO接口方法
public interface IUserDao{
    List<User> findByCondition(User user);
}

2.2 标签配置

使用 if标签 进行条件判断

标签属性:

  • test属性指定判断条件
<!--已经注册过别名-->
<select id="findByCondition" parameterType="user" resultType="user">
	select * from user where 1=1
    <if test="username != null">
        <!--所给条件中有用户名就把用户名添加到查询条件中-->
    	and username = #{username}
    </if>
    <if test="bonus != null">
        <!--所给条件中有奖金就把奖金添加到查询条件中-->
    	and bonus = #{bonus}
    </if> 
</select>

2.3 测试

  1. 使用用户名一个属性查询
@Test 
//只有用户名一个查询条件时
public void findByConditionTest(){
    User user = new User();
    user.setUsername("test");
    
    List<User> users = userDao.findByCondition(user);
    for(User u : users){
        System.out.println(u);
    }
}

查询结果

动态SQL_if_1

  1. 使用用户名和奖金属性查询
@Test 
//有用户名和奖金两个查询条件时
public void findByConditionTest(){
    User user = new User();
    user.setUsername("test");
    user.setBonus(1000);
    
    List<User> users = userDao.findByCondition(user);
    for(User u : users){
        System.out.println(u);
    }
}

查询结果

动态SQL_if_2

小心别掉坑:SQL语句中的部分无关大小写,实体类中的属性有大小写之分

错误示范:

用户实体类

public class User{
    private String userName;
}

映射文件

<select id="findByCondition" parameterType="user" resultType="user">
	select * from user where 1=1
    <if test="username != null">
    	and username = #{username}
    </if>
</select>
  • 判断条件中、SQL语句占位符中的值与实体类属性有关,但这里使用小写

很好,你错了:

SQL和实体类属性的写法区别

Tips:能保证实体类属性和数据库列名相同最好,如果不行要时刻注意属性名!!

3. < where >

3.1 标签配置

使用 where标签 代替SQL语句中动态拼接条件的部分

<select id="findByCondition" parameterType="user" resultType="user">
	select * from user
    <where>
        <if test="username != null">
    		and username = #{username}
    	</if>
    	<if test="bonus != null">
    		and bonus = #{bonus}
   		</if> 
    </where>
</select>

Tips 3.1:where 1=1 和 < where >

似乎只是换了一种条件判断的写法,实际上Mybatis对结果进行简单的处理

例如:

  • 只会在至少有一个条件满足时才插入“WHERE”子句
  • 若语句的开头为“AND”或“OR”时,Mybatis知道怎么去处理

这些都是之前“where 1=1”没有实现的

4. < foreach >

目的:根据QueryVo中的ID进行子查询

对应的SQL语句为“ select * from user where id in( )

4.1 相关准备

  • QueryVo查询条件类
package org.example.domain;

public class QueryVo{
    private User user;
    private List<Integer> ids;
    //省略了get和set方法
}
  • 新增DAO接口方法
public interface IUserDao{
    List<User> findByIds(QueryVo vo);
}

4.2 标签配置

使用 foreach标签 遍历集合

标签属性:

  • collection属性指定所要遍历的集合

  • open属性指定语句开始的部分

  • close属性指定语句结束的部分

  • item属性代表遍历集合时每个元素的变量名

  • sperator属性指定每个元素之间的分隔符

<select id="findByIds" parameterType="queryvo" resultType="user">
	select * from user
    <where>
    	<if test="ids != null and ids.size() > 0">
        	<foreach collection="ids" open="and id in (" close=")" item="id" seperater=",">
            	#{id}
            </foreach>
        </if>
    </where>
</select>

Tips:value属性占位符中的属性名由item的变量的决定

动态SQL_foreach_item

4.3 测试

测试方法

@Test
public void findByIdsTest(){
	QueryVo vo = new QueryVo();
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(5);
    vo.setIds(list);
    
    List<User> users = userDao.findByIds(vo);
    for(User user : users){
        System.out.println(user);
    }
}

查询结果

动态SQL_foreach

5. < sql >补充

问题:使用动态SQL语句时每条语句前都要使用“select * from user”

5.1 抽取重复SQL语句

使用 sql标签 抽取重复SQL语句

标签属性:

  • id属性唯一标识这一段可复用的SQL语句
<sql id="selectDefault">
	select * from user
</sql>

5.2 插入重复的SQL语句

在使用时使用 include标签 引入

标签属性:

  • refid属性指定所使用的复用SQL语句的唯一标识
<select id="findAll" resultType="user">
	<include refid="selectDefault"/>
</select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值