24.MyBatis学习--动态sql_if_判断&OGNL&where查询条件&trim_自定义字符串截取解决sql拼装出现的问题

本文介绍了MyBatis中如何使用动态SQL进行条件查询,针对空条件导致的SQL错误提出了三种解决方案:1) 在where后添加1=1;2) 使用`<where>`标签去除多余条件;3) 使用`<trim>`标签精细控制字符串拼接,避免SQL错误。详细解析了`if`、`OGNL`和`where`、`trim`的用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面的文章中一直介绍的都是静态sql,在实际开发过程中,我们会遇到条件查询的需求,根据所给的多个条件查询,mybatis提供了动态sql实现方法。

需求

  1. 条件查询员工信息
  2. 条件:员工id或员工lastName或员工email或员工性别。

相关文件

  1. Employee.java
public class Employee {

	private Integer id;
	private String lastName;
	private String email;
	private String gender;
	private Department dept;

	public Employee() {
		super();
	}

	public Employee(Integer id, String lastName, String email, String gender) {
		super();
		this.id = id;
		this.lastName = lastName;
		this.email = email;
		this.gender = gender;
	}




	public Department getDept() {
		return dept;
	}

	public void setDept(Department dept) {
		this.dept = dept;
	}

	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	@Override
	public String toString() {
		return "Employee [id=" + id + ", lastName=" + lastName + ", email="
				+ email + ", gender=" + gender + "]";
	}

}

  1. 创建接口EmployeeDynamicSQLMapper.java,在接口中定义条件查询方法。
public interface EmployeeDynamicSQLMapper {

    public List<Employee> getEmployeeByCondition(Employee employee);
}

  1. 创建EmployeeDynamicSQLMapper接口对应的sql映射文件EmployeeDynamicSQLMapper.xml。并通过if和where完成条件查询。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fzl.mybatis.dao.EmployeeDynamicSQLMapper">

    <select id="getEmployeeByCondition" resultType="com.fzl.mybatis.bean.Employee">
        select * from tbl_employee
        where
        <if test="id!=null">
            id=#{id}
        </if>
        <if test="lastName!=null and lastName!='' ">
            and last_name like concat("%",#{lastName},"%")
        </if>
        <if test="email!=null">
            and email=#{email}
        </if>
        <if test="gender==0 or gender==1">
            and gender=#{gender}
        </if>
    </select>
</mapper>
  1. 测试
在这里插入代码片public class MyBatisDynamicSQLTest {

    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "MyBatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        return  sqlSessionFactory;
    }

    @Test
    public void test1() throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession openSession = sqlSessionFactory.openSession();
        try{
            EmployeeDynamicSQLMapper mapper = openSession.getMapper(EmployeeDynamicSQLMapper.class);
            Employee employee = new Employee(3, "u", "236534567@qq.com", "1");
            List<Employee> employeeList = mapper.getEmployeeByCondition(employee);
            for(Employee e:employeeList){
                System.out.println(e);
            }
        }finally{
            openSession.close();
        }
    }
}
  1. 测试结果
    在这里插入图片描述
    测试数据的id不为空时,我们可以发现测试成功。但是,将测试的查询的员工信息的id设置为null,重新运行,会发现报错了。

在这里插入图片描述

这是因为id为空,他就直接执行lastName和下面的条件查询了,但是其他的条件都是以and开头的,因此会报错。这个问题有三种解决办法。

解决办法1

在where后面加上1=1,给where后面加上1==1,以后的条件都and xxx。
在这里插入图片描述

解决办法2

mybatis使用<where></where>标签来将所有的查询条件包括在内。没有把提升就会将where标签中拼装的sql,多出来的and或者or去掉。
在这里插入图片描述
但是,<where></where>只会去掉第一个多出来的and或者or。有些开发者,喜欢在条件的后面加上and,
在这里插入图片描述

这时候这个办法就不管用了,这时我们可以采用第三种解决办法。

解决办法3

使用<trim></trim>标签来解决。<trim></trim>标签有一下几个属性,可以通过这些属性来解决add或or在后面的的问题。
prefix="":前缀:trim标签体中是整个字符串拼串 后的结果。
prefix给拼串后的整个字符串加一个前缀
prefixOverrides="":
前缀覆盖: 去掉整个字符串前面多余的字符
suffix="":后缀
suffix给拼串后的整个字符串加一个后缀
suffixOverrides=""
后缀覆盖:去掉整个字符串后面多余的字符。

 <select id="getEmployeeByConditionByTrim" resultType="com.fzl.mybatis.bean.Employee">
        select * from tbl_employee
        <!--
            prefix="":前缀:trim标签体中是整个字符串拼串 后的结果。
	 			prefix给拼串后的整个字符串加一个前缀
	 	prefixOverrides="":
	 			前缀覆盖: 去掉整个字符串前面多余的字符
	 	suffix="":后缀
	 			suffix给拼串后的整个字符串加一个后缀
	 	suffixOverrides=""
	 			后缀覆盖:去掉整个字符串后面多余的字符
         -->
        <trim prefix="where" suffixOverrides="and">
            <if test="id!=null">
               id=#{id}  and
            </if>
            <if test="lastName!=null and lastName!='' ">
               last_name like concat("%",#{lastName},"%")  and
            </if>
            <if test="email!=null">
                email=#{email} and
            </if>
            <if test="gender==0 or gender==1">
                gender=#{gender}
            </if>
        </trim>
    </select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值