pur*_*doo 6 java mysql rest spring-data-jpa spring-boot
我目前正忙着使用Spring Boot REST API项目进行教学.我有一个相当大的表,其中22列被加载到MySQL数据库中,我试图让用户能够按多列过滤结果(假设这个例子的目的是6).
我目前正在扩展一个Repository并初始化了一些方法,例如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();
}
Run Code Online (Sandbox Code Playgroud)
到目前为止我的问题是我正在进行的这种方式意味着我基本上需要n!我的存储库中用于支持此功能的方法数量,n等于我要过滤的字段/列数量.有没有更好的方法来处理这个问题,也许我正在过滤存储库'就地'所以我可以简单地过滤'就地',因为我检查地图以查看用户确实填充了哪些过滤器?
编辑:所以我现在正在实施一个'hacky'解决方案,可能与J. West的评论有关.我假设用户将在请求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;
Run Code Online (Sandbox Code Playgroud)
在Controller中,我会检测地图中p5和p6是否为空,如果是,则只需将它们更改为字符串'%'即可.我确信有更精确和直观的方法来做到这一点,虽然我还没有找到任何类型的东西.
您可以使用JpaSpecificationExecutor和自定义轻松完成此操作Specification:https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/
我会用包含所有可选get参数的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
}
Run Code Online (Sandbox Code Playgroud)
和控制器:
@RequestMapping(value = "/{ticket}/count", method = RequestMethod.GET)
public long getItemsCount(
@PathVariable String ticket,
VehicleFilter filter,
HttpServletRequest request
) throws Exception
{
return vehicleService.getCount(filter);
}
Run Code Online (Sandbox Code Playgroud)
服务:
@Override
public long getCount(VehicleFilter filter)
{
return vehicleRepository.count(filter);
}
Run Code Online (Sandbox Code Playgroud)
库:
@Repository
public interface VehicleRepository extends JpaRepository<Vehicle, Integer>, JpaSpecificationExecutor<Vehicle>
{
}
Run Code Online (Sandbox Code Playgroud)
只是一个根据公司代码改编的简单示例,您就会明白!
| 归档时间: |
|
| 查看次数: |
2087 次 |
| 最近记录: |