如何在Spring Boot的API GET接口中传递多个ID
This is a super common use case, and there are a couple of clean, secure ways to implement it with Spring Boot and JDBC. Let’s walk through two approaches—including the path-based format you mentioned in your question.
Approach 1: Comma-Separated IDs in the Path Variable
This matches the URL structure you described (http://localhost:8080/api/v/listemployee/1,2,3,4). Here’s how to build it step by step:
Step 1: Build the Controller
First, create a GET endpoint that accepts a comma-separated string of IDs via @PathVariable, then convert it into a list of integers for processing:
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @RestController @RequestMapping("/api/v") public class EmployeeController { private final EmployeeService employeeService; // Constructor injection (preferred over @Autowired for clarity) public EmployeeController(EmployeeService employeeService) { this.employeeService = employeeService; } @GetMapping("/listemployee/{ids}") public List<Employee> getEmployeesByIds(@PathVariable String ids) { // Split the comma-separated string into a list of integers List<Integer> idList = Arrays.stream(ids.split(",")) .map(Integer::parseInt) .collect(Collectors.toList()); return employeeService.getEmployeesByIds(idList); } }
Step 2: Implement the JDBC Service
Use JdbcTemplate to safely run an IN query. Important: Never concatenate IDs directly into your SQL string—that’s a massive SQL injection risk. Instead, generate dynamic placeholders for each ID:
import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import java.util.List; import java.util.stream.Collectors; @Service public class EmployeeService { private final JdbcTemplate jdbcTemplate; public EmployeeService(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public List<Employee> getEmployeesByIds(List<Integer> ids) { // Generate placeholders like "?, ?, ?" for each ID in the list String placeholders = ids.stream() .map(id -> "?") .collect(Collectors.joining(", ")); String sql = "SELECT id, name, department, salary FROM employees WHERE id IN (" + placeholders + ")"; // Map SQL results directly to your Employee POJO return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Employee.class), ids.toArray()); // Pass IDs as arguments to replace placeholders safely } }
Step 3: Employee Model Class
You’ll need a simple POJO to represent your employee data:
public class Employee { private Integer id; private String name; private String department; private Double salary; // Getters and setters public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } }
Approach 2: Multiple IDs as Request Parameters
If you prefer a more RESTful alternative (common for filter-style queries), you can pass IDs as repeated request parameters:http://localhost:8080/api/v/listemployee?ids=1&ids=2&ids=3&ids=4
The controller changes just a bit—use @RequestParam to capture the list directly:
@GetMapping("/listemployee") public List<Employee> getEmployeesByIds(@RequestParam List<Integer> ids) { return employeeService.getEmployeesByIds(ids); }
The EmployeeService code stays exactly the same as above—no extra changes needed!
Quick Best Practices
- SQL Injection Protection: Using
JdbcTemplatewith parameterized queries ensures IDs are properly escaped, so you don’t have to worry about injection attacks. - Input Validation: Add checks (like ensuring IDs are positive integers or the list isn’t empty) using Spring’s validation annotations (e.g.,
@Min,@NotEmpty) if you want to enforce clean input. - NamedParameterJdbcTemplate Alternative: For more readable code, you can use
NamedParameterJdbcTemplatewith a named list parameter:String sql = "SELECT * FROM employees WHERE id IN (:ids)"; Map<String, Object> params = Map.of("ids", ids); return namedParameterJdbcTemplate.query(sql, params, new BeanPropertyRowMapper<>(Employee.class));
内容的提问来源于stack exchange,提问作者Faisal Jaffri

