动态SQL
XML
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wzb.SqlImprove20240925.SQLImproveMapper">
<!-- 将条件查询改成动态SQL形式 -->
<!-- XML中,是对SQL语句进行拼接的,将若干SQL语句的条件,拼接成一条完整的SQL语句 -->
<!-- <if>标签用于判断条件是否成立,用test属性进行条件判断,若条件为true,那么就拼接SQL,若为false,则不操作 -->
<!-- <select id="sqlImprove" resultType="com.wzb.Pojo20240925.Emp">-->
<!-- select * from emp-->
<!-- where-->
<!-- <if test="name != null">-->
<!-- name like concat('%', #{name}, '%')-->
<!-- </if>-->
<!-- <if test="gender != -1">-->
<!-- and gender = #{gender}-->
<!-- </if>-->
<!-- <if test="begin != null and end != null">-->
<!-- and entrydate between #{begin} and #{end}-->
<!-- </if>-->
<!-- order by update_time desc-->
<!-- </select>-->
<!-- 上述代码看似完成了条件查询,但其实仍然有不足之处:
1.若所有参数都是null,那么仍然会在SQL语句中拼接where,这是不符合SQL语法的
2.若前面的是null,但是后面的参数不是null,那么会多拼接一个null,比如上面的代码:name是null;但是gender不是null
那么就会拼接成"...... where and gender = #{gender}",这是错误的SQL语句
-->
<!-- 解决方法:<where>标签:
<where>标签只会在子元素(参数)有内容的情况下,才会插入where子句,并且能够自动去除子句开头的and或者or -->
<!-- 优化代码 -->
<!-- 当参数没有传递(为null时),就不会将语句拼接成SQL语句,并且用了<where>标签,能够自动处理开头的and、or -->
<select id="sqlImprove" resultType="com.wzb.Pojo20240925.Emp">
select * from emp
<where>
<if test="name != null">
and name like concat('%', #{name}, '%')
</if>
<if test="gender != -1">
and gender = #{gender}
</if>
<if test="begin != null and end != null">
and entrydate between begin and end
</if>
</where>
order by update_time desc
</select>
<!-- 测试成功,成功实现动态SQL -->
<!-- 实现动态更新员工信息 -->
<!-- <update id="updateImprove">-->
<!-- update emp-->
<!-- set-->
<!-- <if test="username != null">-->
<!-- username=#{username},-->
<!-- </if>-->
<!-- <if test="name != null">-->
<!-- name=#{name},-->
<!-- </if>-->
<!-- <if test="gender != -1">-->
<!-- gender=#{gender},-->
<!-- </if>-->
<!-- <if test="image != null">-->
<!-- image=#{image},-->
<!-- </if>-->
<!-- <if test="job != null">-->
<!-- job=#{job},-->
<!-- </if>-->
<!-- <if test="entrydate != null">-->
<!-- entrydate=#{entrydate},-->
<!-- </if>-->
<!-- <if test="deptId != null">-->
<!-- dept_id=#{deptId},-->
<!-- </if>-->
<!-- <if test="updateTime != null">-->
<!-- update_time=#{updateTime}-->
<!-- </if>-->
<!-- where id = #{id}-->
<!-- </update>-->
<!-- 这个代码会出现问题,若只传递前面的参数,不传递最后一个参数,那么将会多出一个","(因为每一个拼接语句的末尾都有个逗号,
只有最后一1个拼接语句没有),所以说只要不传递最后一个参数,就会发生SQL语句语法错误 -->
<!-- 解决方法:使用标签<set>
在update语句中使用<set>标签,会删除掉额外的逗号,避免SQL语法错误 -->
<update id="updateImprove">
update emp
<set>
<if test="username != null">
username=#{username},
</if>
<if test="name != null">
name=#{name},
</if>
<if test="gender != -1">
gender=#{gender},
</if>
<if test="image != null">
image=#{image},
</if>
<if test="job != null">
job=#{job},
</if>
<if test="entrydate != null">
entrydate=#{entrydate},
</if>
<if test="deptId != null">
dept_id=#{deptId},
</if>
<if test="updateTime != null">
update_time=#{updateTime}
</if>
</set>
where id = #{id}
</update>
<!-- 这样可以解决update语句后多","的问题 -->
<!-- 小结:
<if>标签可以用于判断条件是否成立,若条件为true,那么拼接对应的SQL语句
<where>标签代替where,只会在子元素不为null的时候才插入where子句,并且能够自动去除子句开头的多余的and和or
<set>标签代替set在update语句中使用,可以动态的插入update子句,并且能删除额外的"," -->
<!-- 使用<foreach>标签达到删除多条语句的效果 -->
<!-- <foreach collection="集合名称" item="集合遍历出来的元素", separator="每一次遍历使用的分隔符"
open="遍历开始之前拼接的片段" close="遍历结束后拼接的片段"> -->
<delete id="deleteImprove">
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
<!-- 成功使用<foreach>完成批量删除 -->
<!-- 在XML映射文件中配置SQL,有时会出现很多重复的片段,那么就会导致很多冗余的代码 -->
</mapper>
SQLImproveMapper
java
package com.wzb;
import com.wzb.MybatisExercise20240925.EmpMapper;
import com.wzb.MybatisXmlExercise20240925.XmlMapper;
import com.wzb.Pojo20240925.Emp;
import com.wzb.SqlImprove20240925.SQLImproveMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@SpringBootTest
class SpringbootExercise20240925ApplicationTests {
@Autowired
private EmpMapper empMapper;
@Autowired
private XmlMapper xmlMapper;
@Autowired
private SQLImproveMapper sqlImproveMapper;
// 增
// @Test
// public void insertEmp() {
// Emp emp = new Emp();
// emp.setUsername("black");
// emp.setName("布莱克");
// emp.setGender((short)1);
// emp.setImage("2.jpg");
// emp.setJob((short)2);
// emp.setEntrydate(LocalDate.of(2000, 1, 1));
// emp.setCreateTime(LocalDateTime.now());
// emp.setUpdateTime(LocalDateTime.now());
//
// empMapper.insertEmp(emp);
// }
// // 删
// @Test
// public void deleteEmp() {
// empMapper.deleteEmp(20);
// }
//
// // 改
// @Test
// public void updateEmp() {
// Emp emp = new Emp();
// emp.setId(19);
// emp.setUsername("gaiya");
// emp.setName("盖亚");
// emp.setGender((short)1);
// emp.setImage("2.jpg");
// emp.setJob((short)2);
// emp.setEntrydate(LocalDate.of(2000, 1, 1));
// emp.setCreateTime(LocalDateTime.now());
// emp.setUpdateTime(LocalDateTime.now());
//
// empMapper.updateEmp(emp);
// }
//
// // 查
// @Test
// public void selectEmp() {
// Emp emp = empMapper.selectEmp(19);
// System.out.println(emp);
// }
@Test
public void XmlConditionSelect() {
List<Emp> empList = xmlMapper.conditionSelect("张", (short) 1, null, null
/*LocalDate.of(2000, 1, 1), LocalDate.of(2024,1,1)*/);
for (Emp emp : empList) {
System.out.println(emp);
}
}
@Test
public void SqlImprove() {
List<Emp> empList = sqlImproveMapper.sqlImprove(null, (short) -1, null, null);
for (Emp emp : empList) {
System.out.println(emp);
}
}
@Test
public void updateEmp() {
Emp emp = new Emp();
emp.setUsername("tom2");
sqlImproveMapper.updateImprove(emp);
}
@Test
public void deleteEmp() {
List<Integer> ids = new ArrayList<>();
Collections.addAll(ids, 18,19,26,27);
sqlImproveMapper.deleteImprove(ids);
}
}