gpt4 book ai didi

Java Spring REST API 处理许多可选参数

转载 作者:可可西里 更新时间:2023-11-01 06:43:37 24 4
gpt4 key购买 nike

出于教学目的,我目前正在处理一个 Spring Boot REST API 项目。我有一个相当大的表,其中有 22 列加载到 MySQL 数据库中,我试图让用户能够按多列过滤结果(在本示例中假设为 6)。

我目前正在扩展一个存储库,并已初始化方法,例如 findByParam1 和 findByParam2 以及 findByParam1OrderByParam2Desc 等,并已验证它们是否按预期工作。我想问你们的问题是最好的方法是让用户能够利用所有 6 个可选的 RequestParam,而无需编写大量的条件/存储库方法变体。例如,我想让用户能够点击 url home/get-data/ 获取所有结果,home/get-data?param1=xx 以基于 param1 进行过滤,并且可能, home/get-data?param1=xx&param2=yy...&param6=zz 过滤所有可选参数。

作为引用,下面是我的 Controller 的相关部分(大致)。

@RequestMapping(value = "/get-data", method = RequestMethod.GET)
public List<SomeEntity> getData(@RequestParam Map<String, String> params) {
String p1 = params.get("param1");
if(p1 != null) {
return this.someRepository.findByParam1(p1);
}
return this.someRepository.findAll();
}

到目前为止,我的问题是我处理这件事的方式意味着我基本上需要 n!我的存储库中支持此功能的方法数量 n 等于我要过滤的字段/列的数量。有没有更好的方法来处理这个问题,也许我正在“就地”过滤存储库,这样我就可以简单地“就地”过滤,因为我检查 map 以查看用户确实填充了哪些过滤器?

编辑:所以我目前正在实现一个可能与 J. West 下面的评论相关的“hacky”解决方案。我假设用户将在请求 URL 中指定所有 n 个参数,如果他们不指定(例如,他们指定 p1-p4 但不指定 p5 和 p6),我生成的 SQL 只匹配语句到 LIKE '%'非包含参数。它看起来像……

@Query("select u from User u where u.p1 = :p1 and u.p2 = :p2 ... and u.p6 = :p6") 
List<User> findWithComplicatedQueryAndSuch;

在 Controller 中,我会检测映射中的 p5 和 p6 是否为空,如果是,只需将它们更改为字符串“%”。我确信有一种更精确、更直观的方法可以做到这一点,尽管我还没有找到任何类似的方法。

最佳答案

您可以使用 JpaSpecificationExecutor 和自定义 Specification 轻松完成此操作:https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/

我会用包含所有可选获取参数的 DTO 替换 HashMap,然后基于该 DTO 构建规范,显然您也可以保留 HashMap 并基于它构建规范。

基本上:

public class VehicleFilter implements Specification<Vehicle>
{
private String art;
private String userId;
private String vehicle;
private String identifier;

@Override
public Predicate toPredicate(Root<Vehicle> root, CriteriaQuery<?> query, CriteriaBuilder cb)
{
ArrayList<Predicate> predicates = new ArrayList<>();

if (StringUtils.isNotBlank(art))
{
predicates.add(cb.equal(root.get("art"), art));
}
if (StringUtils.isNotBlank(userId))
{
predicates.add(cb.equal(root.get("userId"), userId));
}
if (StringUtils.isNotBlank(vehicle))
{
predicates.add(cb.equal(root.get("vehicle"), vehicle));
}
if (StringUtils.isNotBlank(identifier))
{
predicates.add(cb.equal(root.get("identifier"), fab));
}

return predicates.size() <= 0 ? null : cb.and(predicates.toArray(new Predicate[predicates.size()]));
}

// getter & setter
}

和 Controller :

@RequestMapping(value = "/{ticket}/count", method = RequestMethod.GET)
public long getItemsCount(
@PathVariable String ticket,
VehicleFilter filter,
HttpServletRequest request
) throws Exception
{
return vehicleService.getCount(filter);
}

服务:

@Override
public long getCount(VehicleFilter filter)
{
return vehicleRepository.count(filter);
}

存储库:

@Repository
public interface VehicleRepository extends JpaRepository<Vehicle, Integer>, JpaSpecificationExecutor<Vehicle>
{
}

只是一个根据公司代码改编的简单示例,您明白了!

关于Java Spring REST API 处理许多可选参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41068956/

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