【发布时间】:2017-04-25 10:28:03
【问题描述】:
出于教学目的,我目前正在处理一个 Spring Boot REST API 项目。我有一个相当大的表,其中 22 列加载到 MySQL 数据库中,并试图让用户能够按多列过滤结果(在本示例中假设为 6)。
我目前正在扩展存储库并已初始化方法,例如 findByParam1 和 findByParam2 和 findByParam1OrderByParam2Desc 等,并已验证它们按预期工作。我对你们的问题是让用户能够利用所有 6 个可选的 RequestParams 而无需编写大量的条件/存储库方法变体的最佳方法。例如,我想让用户能够点击 url home/get-data/ 以获取所有结果, home/get-data?param1=xx 以基于 param1 进行过滤,并且可能, home/get-data?param1=xx¶m2=yy...¶m6=zz 过滤所有可选参数。
作为参考,这是我的控制器的相关块(大致)的样子。
@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 等于我要过滤的字段/列的数量。有没有更好的方法来处理这个问题,也许我正在“就地”过滤存储库,这样我就可以在检查地图以查看用户确实填充了哪些过滤器时简单地过滤“就地”?
编辑:所以我目前正在实施一个可能与 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;
在控制器中,我会检测映射中的 p5 和 p6 是否为空,如果是,只需将它们更改为字符串“%”。我确信有一种更精确和直观的方法可以做到这一点,尽管我还没有找到任何类似的东西。
【问题讨论】:
-
嗯,这很难。我确信 Spring 支持这样的东西,我只是不知道它到底是什么;我正在查看文档,因为我现在很好奇。作为一个潜在的“hacky”解决方案,您可以只返回整个对象,然后循环遍历并
null您不想包含的字段。由于您正在映射一个对象,即使您以正确的方式执行此操作,您未从查询中返回的字段将为空。 -
我不是 100% 确定你的意思是 null 我不想包含的字段,也就是说,这将如何帮助我不必写出 n 阶乘的存储库函数,如 findByP1和 findByP1andP2 和 findByP1andP3 等等?这可能类似于我现在正在实施的 hacky 方法(更新答案),我只是假设用户总是过滤 6 个参数,如果不是,则生成与 LIKE '%' 等效的 SQL 以基本上不过滤根本......这就是你不想包含的字段的意思吗?
-
我想我误解了你在问什么。看看这个关于创建自定义
JpaSpecificationExecutor的链接,看起来它可能在正确的轨道上。 cubrid.org/wiki_ngrinder/entry/… -
@fapple 这就是人们使用 QueryDsl querydsl.com 的原因。在 Spring 应用程序中使用它很常见 - 并且易于集成 - spring.io/blog/2011/04/26/…
标签: java mysql rest spring-boot spring-data-jpa