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

Spring Boot多可选参数Data JPA查询及控制器实现咨询

实现步骤与代码示例

1. 实体类定义

先创建对应数据库表的实体类,以Employee为例覆盖所需字段:

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Data;

@Entity
@Data
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String address;
    private String city;
    private String state;
    private String country;
    private Integer age;
    private Double salary;
}

2. JPA Repository层

继承JpaRepository和JpaSpecificationExecutor,支持动态条件查询:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface EmployeeRepository extends JpaRepository<Employee, Long>, JpaSpecificationExecutor<Employee> {
}

3. 控制器层实现

编写REST控制器接收四个可选参数,根据参数动态构建查询条件,支持任意组合筛选场景:

方式一:使用Specification(灵活支持复杂条件)

适合需要自定义查询逻辑(比如薪资范围、年龄区间)的场景:

import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
public class EmployeeController {

    private final EmployeeRepository employeeRepository;

    // 构造注入
    public EmployeeController(EmployeeRepository employeeRepository) {
        this.employeeRepository = employeeRepository;
    }

    @GetMapping("/employees")
    public List<Employee> getFilteredEmployees(
            @RequestParam(required = false) String city,
            @RequestParam(required = false) String state,
            @RequestParam(required = false) Integer age,
            @RequestParam(required = false) Double salary) {

        Specification<Employee> spec = Specification.where(null);

        // 城市筛选:非空且非空字符串时生效
        if (city != null && !city.isBlank()) {
            spec = spec.and((root, query, cb) -> cb.equal(root.get("city"), city));
        }

        // 州筛选
        if (state != null && !state.isBlank()) {
            spec = spec.and((root, query, cb) -> cb.equal(root.get("state"), state));
        }

        // 年龄筛选
        if (age != null) {
            spec = spec.and((root, query, cb) -> cb.equal(root.get("age"), age));
        }

        // 薪资筛选
        if (salary != null) {
            spec = spec.and((root, query, cb) -> cb.equal(root.get("salary"), salary));
        }

        return employeeRepository.findAll(spec);
    }
}

方式二:使用QueryByExample(简洁的相等匹配)

适合仅需简单相等匹配的场景,代码更简洁:

import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
public class EmployeeController {

    private final EmployeeRepository employeeRepository;

    public EmployeeController(EmployeeRepository employeeRepository) {
        this.employeeRepository = employeeRepository;
    }

    @GetMapping("/employees")
    public List<Employee> getFilteredEmployees(
            @RequestParam(required = false) String city,
            @RequestParam(required = false) String state,
            @RequestParam(required = false) Integer age,
            @RequestParam(required = false) Double salary) {

        // 创建示例对象,设置需要筛选的字段
        Employee example = new Employee();
        example.setCity(city);
        example.setState(state);
        example.setAge(age);
        example.setSalary(salary);

        // 配置匹配规则:忽略null值,城市/州忽略大小写(可选)
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withIgnoreNullValues()
                .withIgnoreCase("city", "state");

        return employeeRepository.findAll(Example.of(example, matcher));
    }
}

补充说明

  • 两种方式都支持任意组合的筛选场景:仅薪资、城市+州、全参数等。
  • 如果需要薪资范围(比如大于某个值),推荐用Specification,修改对应条件为cb.greaterThan(root.get("salary"), salaryMin)即可。
  • 字符串参数用isBlank()判断,避免空字符串作为无效筛选条件。

内容的提问来源于stack exchange,提问作者My India Info

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 23:40:35