MyBatis系统学习篇 - 动态SQL

MyBatis提供了动态SQL帮助我们解决在业务过程中,我们根据不同的条件动态生成SQL语句,用来满足各种复杂的查询需求,包括MyBatis中常用的动态SQL标签和用法,这种方式在一定程度上帮助我们重复写许多SQL堆积在一起,下面我们就看一下Mybatis中常用的有哪些动态SQL标签以及他的用法:

if

<if>:用来表示条件判断,根据我们的条件动态生成SQL片段。在实际开发中,算是我们用的最多的一种动态SQL条件判断字段是加入SQL中还是不加入SQL语句中。

<select id="getUser" resultType="com.example.User">
  SELECT * FROM users
  WHERE 1=1
  <if test="name != null and name != ''">
    AND name = #{name}
  </if>
  <if test="age != null">
    AND age = #{age}
  </if>
</select>

上述代码中,我们使用了<if> 语句来判断,上述语句的 name != null and name != '' 表示,当传过来的name 字段的值不为空,并且name 传过来的是不是空字符串,那么我们就通过 将<if >语句内部的SQL语句添加进去。实际上If 标签,就是通过test属性的表达式进行判断,当表达式的结果为true,那么标签中的内容就会执行,否则就直接被忽略掉。

where

<where>: where一般和if结合使用:

  • 当where 标签中的if条件都不满足的时候,则where标签没有任何功能,那就不会添加任何的where关键字。
  • 当where标签中的if条件有满足或者全部满足的时候,那么where标签会自动添加where关键字,并将条件最前方多余的and去掉
    ps: where标签不能去掉条件最后多余的and标签
<select id="getUser" resultType="com.example.User">
  SELECT * FROM users
  <where>
	  <if test="name != null and name != ''">
	    AND name = #{name}
	  </if>
	  <if test="age != null">
	    AND age = #{age}
	  </if>
  </where>
</select>

trim标签

<trim>:用于去除或添加SQL片段的前缀或后缀。
常用属性:

  • prefix: 在trim标签中的内容的前面添加某些内容。
  • prefixOverrides: 在trim标签中的内容的前面去掉某些内容。
  • suffix:在trim标签中内容的后面添加某些内容。
  • suffixOverrides : 在trim标签中的内容的后面去掉某些内容。
<select id="getEmpListByMoreTJ" resultType="Emp">
	select * from users
	<trim prefix="where" suffixOverrides="and">
		<if test="name != '' and name != null">
			name = #{ename} and
		</if>
		<if test="age != '' and age != null">
			age = #{age} and
		</if>
		<if test="sex != '' and sex != null">
			sex = #{sex}
		</if>
	</trim>
</select>

<trim prefix="where" suffixOverrides="and">:在<trim>标签中添加了前缀where,并通过suffixOverrides="and"去除了最后一个条件中的and。
根据不同的条件值,动态生成了查询语句的条件部分。如果ename、age和sex参数都有值,则生成完整的查询条件;如果某个参数没有值,则不生成对应的条件。

上述示例中使用了#{}占位符来引用参数值,这是为了防止SQL注入攻击。确保传递给SQL语句的参数值被正确地转义和处理。

choose、when、otherwise

<choose><when><otherwise>:用于多条件判断,类似于Java中的switch语句。也可以说是if ...else if ... else

<select id="getUser" resultType="com.example.User">
  SELECT * FROM users
  WHERE 1=1
  <choose>
    <when test="name != null">
      AND name = #{name}
    </when>
    <when test="age != null">
      AND age = #{age}
    </when>
    <otherwise>
      AND status = 'ACTIVE'
    </otherwise>
  </choose>
</select>

在上述示例中,根据name和age参数的值,动态生成了不同的查询条件:

如果name参数不为null,则生成AND name = #{name}的条件。
如果age参数不为null,则生成AND age = #{age}的条件。
如果以上两个条件都不成立(即name和age都为null),则生成AND status = 'ACTIVE’的条件。

<choose>标签用于多条件判断,类似于Java中的switch语句。在<choose>标签中,可以包含多个<when>标签和一个<otherwise>标签。

<when>标签用于指定条件成立时生成的SQL片段。在每个<when>标签中,通过test属性来判断条件是否成立。

<otherwise>标签用于指定所有条件都不成立时生成的SQL片段。

通过使用、和标签,可以根据不同的条件值动态生成不同的SQL片段,实现灵活的条件判断和SQL拼接。这样可以满足复杂查询需求,同时保持SQL语句的可读性和可维护性。

foreach

<foreach>:用于遍历集合或数组,生成重复的SQL片段。

<!--int insertMoreEmp(List<Emp> emps);-->
<insert id="insertMoreEmp">
	insert into t_emp values
	<foreach collection="emps" item="emp" separator=",">
		(null,#{emp.ename},#{emp.age},#{emp.sex},#{emp.email},null)
	</foreach>
</insert>
<!--int deleteMoreByArray(int[] eids);-->
<delete id="deleteMoreByArray">
	delete from t_emp where
	<foreach collection="eids" item="eid" separator="or">
		eid = #{eid}
	</foreach>
</delete>
<!--int deleteMoreByArray(int[] eids);-->
<delete id="deleteMoreByArray">
	delete from t_emp where eid in
	<foreach collection="eids" item="eid" separator="," open="(" close=")">
		#{eid}
	</foreach>
</delete>

<insert>标签示例:

<insert id="insertMoreEmp">
    insert into t_emp values
    <foreach collection="emps" item="emp" separator=",">
        (null,#{emp.ename},#{emp.age},#{emp.sex},#{emp.email},null)
    </foreach>
</insert>

使用了<foreach>标签来遍历emps集合,将集合中的每个Emp对象的属性值插入到t_emp表中。

public int insertMoreEmp(List<Emp> emps) {
    try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
        return empMapper.insertMoreEmp(emps);
    }
}

public static void main(String[] args) {
    List<Emp> emps = new ArrayList<>();
    // 添加要插入的Emp对象到emps集合中
    Emp emp1 = new Emp();
    emp1.setEname("John");
    emp1.setAge(25);
    emp1.setSex("Male");
    emp1.setEmail("john@example.com");
    emps.add(emp1);

    Emp emp2 = new Emp();
    emp2.setEname("Jane");
    emp2.setAge(30);
    emp2.setSex("Female");
    emp2.setEmail("jane@example.com");
    emps.add(emp2);

    // 调用insertMoreEmp方法进行批量插入
    int rowsAffected = insertMoreEmp(emps);
    System.out.println(rowsAffected + " rows inserted.");
}

<delete>标签示例(使用or连接条件)

<delete id="deleteMoreByArray">
    delete from t_emp where
    <foreach collection="eids" item="eid" separator="or">
        eid = #{eid}
    </foreach>
</delete>

在上述示例中,使用了<foreach>标签来遍历eids数组,将数组中的每个元素作为删除条件的一部分,使用or连接多个条件。

public int deleteMoreByArray(int[] eids) {
    try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
        return empMapper.deleteMoreByArray(eids);
    }
}

public static void main(String[] args) {
    int[] eids = {1, 2, 3}; // 要删除的eid数组

    // 调用deleteMoreByArray方法进行批量删除
    int rowsAffected = deleteMoreByArray(eids);
    System.out.println(rowsAffected + " rows deleted.");
}

<delete>标签示例(使用in连接条件):

<delete id="deleteMoreByArray">
    delete from t_emp where eid in
    <foreach collection="eids" item="eid" separator="," open="(" close=")">
        #{eid}
    </foreach>
</delete>

公共SQL片段

在Mapper.xml文件中,我们对可以通过记录一段公共的SQL片段,在使用的地方通过include标签进行引入。

示例:

<sql id="empColumns">
	eid,ename,age,sex,did
</sql>

使用:

select <include refid="empColumns"></include> from t_emp
  • 23
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Miaow.Y.Hu

赏一口饭吃吧,大大们

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

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

打赏作者

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

抵扣说明:

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

余额充值