gpt4 book ai didi

java - 在 GET 方法中用于过滤对象的可选属性

转载 作者:行者123 更新时间:2023-12-02 01:05:14 25 4
gpt4 key购买 nike

目前我有一个实体Sneaker定义为

@Entity(name = "sneaker")
public class Sneaker extends Product {

@Column
private BigDecimal size;

@Enumerated(EnumType.STRING)
@Column
private BrandType brand;

...

// getters, setters, constructors omitted
}

和一个 @RestController get 方法,该方法接受可选参数以根据数据库对象的属性过滤数据库对象

 @GetMapping
public ResponseEntity<List<Sneaker>> getSneakers(
@RequestParam Optional<List<BrandType>> brands,
@RequestParam Optional<List<BigDecimal>> sizes
) {
List<Sneaker> sneakers;

if (brands.isPresent() && sizes.isEmpty()) {
sneakers = sneakerService.getAllByBrands(Util.filterNullItems(brands.get()));
} else if (brands.isEmpty() && sizes.isPresent()) {
sneakers = sneakerService.getAllBySize(sizes.get());
} else if (brands.isPresent() && sizes.isPresent()) {
sneakers = sneakerService.getAllByBrandAndSize(brands.get(), sizes.get());
} else {
sneakers = sneakerService.getAll();
}

if (sneakers.isEmpty())
throw new RuntimeException("No Sneakers were found");

return ResponseEntity
.ok(sneakers);
}

根据给定参数查询数据库的最佳实践是什么?我假设 Controller 中的多个 if else 语句不是最好的方法,因为向对象添加更多属性会呈指数级扩展我的代码并造成困惑。我应该查询所有(或仅通过某些属性)对象并使用流过滤它们 Java 风格吗?

最佳答案

我建议使用org.springframework.data.jpa.domain.Specification

public class SneakerSpecifications {
public static Specification<Sneaker> sizeIn(Optional<List<BigDecimal>> sizes) {
return (root, query, builder) ->
sizes.isPresent() ?
root.get("size").in(sizes.get()) :
builder.conjunction(); // to ignore this clause
}

public static Specification<Sneaker> brandIn(Optional<List<BrandType>> brands) {
return (root, query, builder) ->
brands.isPresent() ?
root.get("brand").in(brands.get()) :
builder.conjunction(); // to ignore this clause
}
}

然后你的SneakerRepository必须扩展org.springframework.data.jpa.repository.JpaSpecificationExecutor

@Repository
public interface SneakerRepository
extends JpaRepository<Sneaker, Long>, JpaSpecificationExecutor<Sneaker> {

}

您的服务方式:

@Service
public class SneakerService {

@Autowired
SneakerRepository repository;

public List<Sneaker> getSneakers(Optional<List<BrandType>> brands, Optional<List<BigDecimal>> sizes) {
Specification<Sneaker> spec =
Specifications.where(SneakerSpecifications.brandIn(brands))
.and(SneakerSpecifications.sizeIn(sizes));

return repository.findAll(spec);
}
}

如果您不使用Spring Data Jpa,则可以使用Criteria APIQuerydsl使用相同的方法

更多信息here

关于java - 在 GET 方法中用于过滤对象的可选属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60131701/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com