You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+MyBatis如何构建多条件运算符的查询语句

实现多条件运算符的学生查询方案

针对你的需求,这里提供两种基于原生MyBatis的实现方案,无需引入额外框架:

方案一:拆分条件字段,直观定义查询参数

这种方式通过自定义查询DTO,把不同的条件拆分成独立字段,逻辑清晰,易于维护。

1. 创建查询参数类

新建StudentQuery类,封装年龄的各类查询条件:

public class StudentQuery {
    // 原等于查询条件
    private Integer age;
    // 年龄大于
    private Integer ageGt;
    // 年龄小于
    private Integer ageLt;
    // 年龄区间起始值(between)
    private Integer ageStart;
    // 年龄区间结束值(between)
    private Integer ageEnd;

    // getter、setter方法省略
}

2. 调整各层方法参数

依次修改DAO、Service、Controller的方法,将原Student参数替换为StudentQuery:

// StudentDao
List<Student> listStudent(StudentQuery query, Pageable pageable);

// StudentService
List<Student> listStudent(StudentQuery query, Pageable pageable) {
    return this.studentDao.listStudent(query, pageable);
}

// StudentController
List<Student> listStudent(StudentQuery query, Pageable pageable) {
    return this.studentService.listStudent(query, pageable);
}

3. 编写动态SQL

修改MyBatis的XML映射文件,通过<if>标签判断不同条件是否生效,自动拼接SQL:

<select id="listStudent" resultType="student">
    select * from student
    <where>
        <!-- 等于条件 -->
        <if test="age != null">
            age = #{age}
        </if>
        <!-- 大于条件 -->
        <if test="ageGt != null">
            <if test="age != null">AND</if>
            age > #{ageGt}
        </if>
        <!-- 小于条件 -->
        <if test="ageLt != null">
            <if test="age != null or ageGt != null">AND</if>
            age < #{ageLt}
        </if>
        <!-- 区间条件 -->
        <if test="ageStart != null and ageEnd != null">
            <if test="age != null or ageGt != null or ageLt != null">AND</if>
            age between #{ageStart} and #{ageEnd}
        </if>
    </where>
    <!-- 处理分页与排序 -->
    <if test="pageable.sort != null">
        order by
        <foreach item="order" collection="pageable.sort" separator=",">
            ${order.property} ${order.direction}
        </foreach>
    </if>
    limit #{pageable.offset}, #{pageable.pageSize}
</select>

补充说明

  • 可以在Service层添加参数校验逻辑,避免冲突条件(如同时传入age和ageStart),防止生成不符合预期的SQL。
  • 客户端调用时,只需传入对应条件字段即可,比如查询age>10就传ageGt=10,查询区间就传ageStart=10和ageEnd=12。

方案二:用枚举定义运算符,灵活适配多场景

这种方式通过枚举统一管理运算符,单个字段可适配多种查询逻辑,适合需要灵活切换运算符的场景。

1. 定义运算符枚举

public enum Operator {
    EQ,    // 等于
    GT,    // 大于
    LT,    // 小于
    BETWEEN // 区间
}

2. 创建带运算符的查询类

public class StudentQuery {
    private Integer age;
    // 区间查询的第二个值
    private Integer ageSecondValue;
    // 年龄对应的查询运算符
    private Operator ageOperator;

    // getter、setter方法省略
}

3. 编写动态SQL

通过<choose>标签根据运算符拼接对应SQL片段:

<select id="listStudent" resultType="student">
    select * from student
    <where>
        <if test="age != null">
            age
            <choose>
                <when test="ageOperator == 'EQ'">= #{age}</when>
                <when test="ageOperator == 'GT'">&gt; #{age}</when>
                <when test="ageOperator == 'LT'">&lt; #{age}</when>
                <when test="ageOperator == 'BETWEEN'">between #{age} and #{ageSecondValue}</when>
                <!-- 默认使用等于查询 -->
                <otherwise>= #{age}</otherwise>
            </choose>
        </if>
    </where>
    <!-- 分页与排序逻辑同方案一 -->
    <if test="pageable.sort != null">
        order by
        <foreach item="order" collection="pageable.sort" separator=",">
            ${order.property} ${order.direction}
        </foreach>
    </if>
    limit #{pageable.offset}, #{pageable.pageSize}
</select>

补充说明

  • 业务层需校验运算符与参数的匹配性,比如使用BETWEEN时必须传入ageSecondValue,否则抛出参数异常。
  • 客户端调用时,只需指定age、ageOperator(及对应辅助参数)即可实现不同条件查询。

内容的提问来源于stack exchange,提问作者frank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 00:50:23