如何通过请求参数添加动态搜索



我应该如何在rest api请求中正确实现动态搜索?我的rest api分为Controller->服务->存储库。我创建了从数据库获取所有驱动程序的GET请求:

@GetMapping
public ResponseEntity<Set<DriverDTO>> getAll(@PageableDefault(value = 15) Pageable pageable) {
Page<DriverEntity> driverEntities = driverService.getAll(pageable);
Set<DriverDTO> driverDTOSet = modelMapperService.mapPageToSetOfEnteredClass(driverEntities, DriverDTO.class);
return new ResponseEntity<>(driverDTOSet, HttpStatus.OK);
}

现在我想添加一些搜索参数,例如name、ageUpToX。。。所以我添加了@RequestParams:

@GetMapping
public ResponseEntity<Set<DriverDTO>> getAll(@PageableDefault(value = 15) Pageable pageable,
@RequestParam String name,
@RequestParam int ageUpTo,
@RequestParam int ageOver) {
Page<DriverEntity> driverEntities = driverService.getAll(pageable);
Set<DriverDTO> driverDTOSet = modelMapperService.mapPageToSetOfEnteredClass(driverEntities, DriverDTO.class);
return new ResponseEntity<>(driverDTOSet, HttpStatus.OK);
}

来自服务的方法getAll((看起来像:

public Page<DriverEntity> getAll(Pageable pageable) {
return driverEntityRepository.findAll(pageable);
}

那么接下来是什么呢?我是否应该将每个requestParam添加到getAll方法中,如:getAll(String name,int ageUpTo,int ageOver(,如果字段为空,则检查几个if循环/!=无效的或者通过某种开关?

如果您想验证查询参数,您不必使用If语句,这可以使用注释以更优雅的方式完成。

首先,您需要在pom.xml文件中包含以下依赖项

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

spring-boot-starter-validation依赖项将包括验证请求参数所需的所有jar。

因此,如果要验证查询参数ageUpTo的最小值为5,最大值为7,则可以将@Validated注释与@Min@Max注释一起使用。@Validated注释用于指定要验证的休息控制器。spring-boot应用程序在调用之前验证所有方法。以下是示例:

@Validated
public RestController {
@GetMapping
public ResponseEntity<Set<DriverDTO>> getAll(@PageableDefault(value = 15) Pageable pageable,
@RequestParam String name,
@RequestParam @Min(5) @Max(7) int ageUpTo,
@RequestParam int ageOver) {
Page<DriverEntity> driverEntities = driverService.getAll(pageable);
Set<DriverDTO> driverDTOSet = modelMapperService.mapPageToSetOfEnteredClass(driverEntities, DriverDTO.class);
return new ResponseEntity<>(driverDTOSet, HttpStatus.OK);
}
}

如果要验证请求参数name是否为空,可以使用@NotBlank注释。

此外,您还可以自定义验证失败时将显示给用户的消息。

你可以在这里或这里阅读更多关于

如果要根据给定的查询参数搜索数据库,则必须在存储库界面中声明一个新方法,该方法将根据给定的参数执行搜索。这意味着您还必须在将调用该方法的服务中声明一个新方法,类似于您之前所做的操作。

我认为你需要将这些参数添加到你的服务方法中,否则你可以向服务发送一个Map,而不是一个接一个地发送,其中键将是你需要筛选的列,然后你可以迭代映射,如果键/值不为空,你可以将其添加到查询规范中,例如:

Specification<MyDomain> querySpec = Specifications.where((root, query, cb) -> {
Predicate p = null;
//iterate over the map
mapParam.forEach(k,v -> {
if(k != null && v!= null) {
p = cb.and(p, cb.equal(root.get(k), k));
}
})
return p;
});
// then use the specification
Page<MyDomain> pageResult = myRepo.findAll(querySpec, pageRequest);

注意,您需要执行一些验证,因为CCD_ 10可能为空,另一件重要的事情是,您的存储库必须从JpaSpecificationExecutor扩展

我认为您可以在spring存储库中使用规范,你需要扩展JpaSpecificationExecutor,比如这个

@Repository
public interface PostRepository extends PagingAndSortingRepository<Post, Integer>, JpaSpecificationExecutor<Post>{}

你必须制作一个规范文件,在那里你会有你的搜索规范,比如下面的

public class PostSpecification implements Specification<Post> {
//.....other codes
//.....other codes
public static Specification<Post> bySearch(String search) {
return (root, query, criteriaBuilder) -> {
if (search == null) {
return criteriaBuilder.conjunction();
}
query.distinct(true);
Predicate titlePredicate = criteriaBuilder.like(root.<String>get("title"), "%" + search + "%");
Predicate contentPredicate = criteriaBuilder.like(root.<String>get("content"), "%" + search + "%");
Predicate authorPredicate = criteriaBuilder.like(root.<String>get("author"), "%" + search + "%");
Join<Post, Tag> postTagsTable = root.join("tags", JoinType.INNER);
Predicate tagPredicate = criteriaBuilder.like(postTagsTable.get("name"), "%" + search + "%");
return criteriaBuilder.or(titlePredicate, contentPredicate,
authorPredicate, tagPredicate);
};
}
}

现在你必须从你的控制器调用findAll,如下

PostSpecification postSpecification = new PostSpecification();
Specification<Post> filteredSpecification = 
postSpecification.findByFilters(search, authorNames, tagNames);

posts = postRepository.findAll(filteredSpecification, pageable).getContent();

相关内容

  • 没有找到相关文章

最新更新