gpt4 book ai didi

java - 从数据库中过滤数据的正确方法

转载 作者:行者123 更新时间:2023-12-01 19:31:22 24 4
gpt4 key购买 nike

我是 Spring 框架的新手,所以问题可能会很愚蠢。

我有一个数据库,其中有近 5000 个条目。我需要创建一个 GET 请求,它需要 5 个参数来过滤数据。根据存在的参数,请求将过滤数据。我能够做到这一点,但我认为我做得不够有效。这是我的问题:

  • 首先,哪种方法更好?使用repository.findAll()从数据库检索所有数据,然后使用流+过滤器过滤掉数据在JPA存储库接口(interface)中编写查询,然后简单地调用这些方法?哪一种效率更高?
  • 第二,检索大量数据的最佳方式是什么?就像我的例子一样,有 5000 个条目。那么我该如何找回它们呢?我读过一些有关 Pageable 的内容,但不是 100% 确定。这是可行的方法还是还有其他更好的选择?

任何帮助表示赞赏。谢谢:)

最佳答案

对于第一个问题,最好只从数据库中检索所需的记录,而不是检索所有条目,然后在 Java 上过滤它们。在 JPA 存储库中编写查询是选项之一,但也是您的选择可以使用 CriteriaQuery 来执行此操作。 CriteriaQuery 使您能够以编程方式对填充项目进行更多操作。它还可以帮助您解决第二个问题。

是的分页是其中一种方法,专门针对Web应用程序。分页的主要思想是将大数据记录划分为较小的 block (页面),用户在第一个卡盘(页面)上搜索他的记录,然后他/她将请求第二页,如果他/她确实找到了。

下面的示例总结了您的两个查询。在此示例中,我尝试检索/搜索大量订单。

Bean OrderSearchCriteria.java ,用于标识过滤器参数。

public class OrderSearchCriteria {

private String user ;

private Date periodFrom ;

private Date periodTo ;

private String status ;

private Integer pageLimit ;

private Integer page ;

private Integer offset ;

private String sortOrder ;

.....
}

存储库

public interface OrderRepository extends JpaRepository<Order, Integer> , JpaSpecificationExecutor<Order>{}

下面使用 CriteriaQuery 根据提交的条件过滤订单。

@Service
public class OrderServiceImpl implements OrderService{
......
@Override
public Page<Order> orderSearch(OrderSearchCriteria orderSearchCriteria) {
if (orderSearchCriteria.getPage() == null)
orderSearchCriteria.setPage(orderSearchCriteria.getOffset() / orderSearchCriteria.getPageLimit());

return orderRepository.findAll(OrderSearchSpecificaton.orderSearch(orderSearchCriteria) ,
PageRequest.of(orderSearchCriteria.getPage(), orderSearchCriteria.getPageLimit()));
}

private static class OrderSearchSpecificaton {

public static Specification<Order> orderSearch(OrderSearchCriteria orderSearchCriteria) {
return new Specification<Order>() {

private static final long serialVersionUID = 1L;

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

if (!StringUtils.isEmpty(orderSearchCriteria.getUser()) && !orderSearchCriteria.getUser().toUpperCase().equals("ALL")) {
Join<Order, User> userJoin = root.join("user") ;
predicates.add(criteriaBuilder.equal(userJoin.get("name") ,orderSearchCriteria.getUser()));
}

if (!StringUtils.isEmpty(orderSearchCriteria.getStatus()) && !orderSearchCriteria.getStatus().toUpperCase().equals("ALL")) {
predicates.add(criteriaBuilder.equal(root.get("status") ,orderSearchCriteria.getStatus()));
}

if (orderSearchCriteria.getPeriodFrom() != null) {
predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("entryDate"), orderSearchCriteria.getPeriodFrom())) ;
}


if (orderSearchCriteria.getPeriodTo()!= null) {
predicates.add(criteriaBuilder.lessThan(root.get("entryDate"), orderSearchCriteria.getPeriodTo())) ;
}

if (!StringUtils.isEmpty(orderSearchCriteria.getSortOrder())) {
if (orderSearchCriteria.getSortOrder().toUpperCase().equals("DESC")) {
query.orderBy(criteriaBuilder.desc(root.get("entryDate"))) ;
}

else {
query.orderBy(criteriaBuilder.asc(root.get("entryDate"))) ;
}
}

return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
}

};
}

}

从 Controller 调用orderSearch

@ResponseBody
@RequestMapping(path = "/order/search" , method = RequestMethod.POST)
public HashMap<String, Object> orderSearch(@RequestBody OrderSearchCriteria orderSearchCriteria) {
Page<Order> page = getOrderService().orderSearch(orderSearchCriteria) ;
HashMap<String, Object> result = new HashMap<>() ;
result.put("total", page.getTotalElements());
result.put("rows", page.getContent());
return result ;
}

我希望这可以帮助你。

关于java - 从数据库中过滤数据的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59703480/

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