Ale*_*lex 4 rest hibernate jpa filter
我对这些技术相当陌生,我需要一个推销来理解做事的好方法。我有一个 Employee 实体,我想通过对端点进行 GET 查询来列出它们。在对字段应用过滤器后,我必须返回一个员工页面。目前,GET 查询上的 Pageable 有效,但我的过滤器无效。
这是我的 REST 端点:
@RequestMapping(value = "/employees",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
@Transactional(readOnly = true)
public ResponseEntity<List<EmployeeDTO>> getAllEmployees(Pageable pageable, String filters) throws URISyntaxException, JSONException {
JSONObject sfilters = null;
try {
sfilters = new JSONObject(filters.trim());
} catch (JSONException e) {
e.printStackTrace();
}
// I wish this on could works, but still have to update it if we add fields to our Employee entity
Page<Employee> page = employeeRepository.findAllByCompanyIdAndFirstnameLikeAndLastnameLike(
userService.getUserWithAuthorities().getCompany().getId(),
sfilters.get("firstname").toString(),
sfilters.get("lastname").toString(),
pageable);
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/employees");
ResponseEntity<List<EmployeeDTO>> result = new ResponseEntity<>(page.getContent().stream()
.map(employeeMapper::employeeToEmployeeDTO)
.collect(Collectors.toCollection(LinkedList::new)), headers, HttpStatus.OK);
return result;
}
Run Code Online (Sandbox Code Playgroud)
注意:我必须过滤更多的字段,但我想让示例尽可能清晰。
我的存储库方法:
Page<Employee> findAllByCompanyIdAndFirstnameLikeAndLastnameLike(Long idCompany, String firstname, String lastname, Pageable pageable);
Run Code Online (Sandbox Code Playgroud)
客户端,它运行良好,我为可分页和要转换为 JSONObject 的过滤器发送了良好的参数。但是现在我需要有关如何在查询中正确生成动态过滤器的建议。我的 JPA 存储库方法不起作用。
我尝试使用谓词,但它没有帮助,因为当我给它一个 Predicate arg 时方法失败。这种方法似乎很适合逐项检查,如果一个或多个与您的 pred 匹配,但不确定它们是否用于使用动态查询检索一组项目。
编辑:我创建了一个实现规范的 EmployeeSpecification 类,但我想返回一个谓词列表/数组,而不仅仅是一个。因此,要覆盖的默认方法返回单个 Predicate。我怎样才能从这个实体中获得多个谓词?
感谢您提供任何提示、帮助和过去的经验分享。
我发现了如何使用谓词来做到这一点。首先,我必须在我的存储库中使用 JPA 方法 findAll :
Page<Employee> findAll(Specification<Employee> spec, Pageable pageable);
Run Code Online (Sandbox Code Playgroud)
然后,我创建了一个实现规范 Spring Boot 对象的自定义类:
public class EmployeeSpecification implements Specification<Employee> {
private final JSONObject criteria;
private List<Predicate> filters;
public EmployeeSpecification(JSONObject criteria) {
this.criteria = criteria;
}
@Override
public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Iterator<?> keys = criteria.keys();
List<Predicate> filters = new ArrayList<>();
if (criteria.length() != 0) {
while (keys.hasNext()) {
String key = (String) keys.next();
String filterValue = null;
try {
filterValue = criteria.get(key).toString();
} catch (JSONException e) {
e.printStackTrace();
}
if (filterValue != null) {
filters.add(criteriaBuilder.like(criteriaBuilder.upper(root.<String>get(key)), "%" + filterValue.toUpperCase() + "%"));
}
}
}
//this is the point : didn't know we could concatenate multiple predicates into one.
return criteriaBuilder.and(filters.toArray(new Predicate[filters.size()]));
}
}
Run Code Online (Sandbox Code Playgroud)
在此之后,在我的 WS 端点方法中,我只需要实例化 EmployeeSpecification并调用 JPA findAll 方法,传递我的过滤器 JSON 对象和我的 Pageable 对象:
@RequestMapping(value = "/employees",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
@Timed
@Transactional(readOnly = true)
public ResponseEntity<List<EmployeeDTO>> getAllEmployees(Pageable pageable, String filters) throws URISyntaxException, JSONException {
JSONObject sfilters = null;
try {
sfilters = new JSONObject(filters.trim());
} catch (JSONException e) {
e.printStackTrace();
}
EmployeeSpecification spec = new EmployeeSpecification(sfilters);
Page<Employee> page = employeeRepository.findAll(
spec,
pageable);
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/employees");
ResponseEntity<List<EmployeeDTO>> result = new ResponseEntity<>(page.getContent().stream()
.map(employeeMapper::employeeToEmployeeDTO)
.collect(Collectors.toCollection(LinkedList::new)), headers, HttpStatus.OK);
return result;
}
Run Code Online (Sandbox Code Playgroud)
现在我可以发送可分页项目和多个字段过滤器,我能够根据排序、每页数量、当前页面和字段过滤器正确检索结果。非常感谢您的帮助;) (lol)
| 归档时间: |
|
| 查看次数: |
12810 次 |
| 最近记录: |