Spring Boot中如何基于不同查询参数编写查询数据的控制器与服务?
Spring Boot REST API 实现带动态查询参数的/buy端点
1. 实体类(对应数据库表)
先定义与数据库表映射的实体类,假设业务表名为buy_records:
import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.Table; @Entity @Table(name = "buy_records") public class BuyRecord { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String projectionId; private String place; // 可根据业务需求添加其他字段,如buyTime、amount等 // 无参、全参构造方法 public BuyRecord() {} public BuyRecord(String projectionId, String place) { this.projectionId = projectionId; this.place = place; } // Getter、Setter方法 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getProjectionId() { return projectionId; } public void setProjectionId(String projectionId) { this.projectionId = projectionId; } public String getPlace() { return place; } public void setPlace(String place) { this.place = place; } }
2. 数据访问层(Repository)
要支持动态查询参数,继承JpaSpecificationExecutor来构建灵活的查询条件:
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; public interface BuyRecordRepository extends JpaRepository<BuyRecord, Long>, JpaSpecificationExecutor<BuyRecord> { }
3. 服务层(Service)
处理业务逻辑,动态构建查询条件并调用Repository查询数据:
import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import java.util.List; @Service public class BuyRecordService { private final BuyRecordRepository buyRecordRepository; // 构造注入(符合Spring最佳实践) public BuyRecordService(BuyRecordRepository buyRecordRepository) { this.buyRecordRepository = buyRecordRepository; } public List<BuyRecord> getBuyRecords(String projectionId, String place) { Specification<BuyRecord> spec = Specification.where(null); // 仅当参数非空时添加查询条件 if (projectionId != null && !projectionId.isEmpty()) { spec = spec.and((root, query, cb) -> cb.equal(root.get("projectionId"), projectionId)); } if (place != null && !place.isEmpty()) { spec = spec.and((root, query, cb) -> cb.equal(root.get("place"), place)); } return buyRecordRepository.findAll(spec); } }
4. 控制器层(Controller)
定义REST端点,接收查询参数并调用服务层返回结果:
import org.springframework.http.ResponseEntity; 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 BuyRecordController { private final BuyRecordService buyRecordService; // 构造注入 public BuyRecordController(BuyRecordService buyRecordService) { this.buyRecordService = buyRecordService; } @GetMapping("/buy") public ResponseEntity<List<BuyRecord>> getBuyRecords( @RequestParam(required = false) String projectionId, @RequestParam(required = false) String place // 如需支持更多查询参数,直接添加@RequestParam即可 ) { List<BuyRecord> records = buyRecordService.getBuyRecords(projectionId, place); return ResponseEntity.ok(records); } }
核心说明
- 查询参数通过
@RequestParam(required = false)标记为可选,支持任意参数组合(仅传projectionId、仅传place或两者都传) - 使用
Specification动态构建查询条件,后续新增查询参数时只需在Service中添加对应判断逻辑即可,扩展性强 - 采用构造注入替代字段注入,避免依赖注入相关的潜在问题
内容的提问来源于stack exchange,提问作者B Santhosh
相关产品推荐
相关产品推荐

