栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

实现JPA和Spring Boot的搜索功能

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

实现JPA和Spring Boot的搜索功能

我可以推荐几种解决此任务的方法:

1)简单的,但不灵活:在控制器中使用刚请求参数根据自己的滤波器特性(

name
from
to
),并且在回购制备相应的查询,例如:

控制器:

@GetMapping("/q")public List<ResponseDto> getAllByQuery(    @RequestParam(value = "name", required = false) String name,    @RequestParam(value = "from", required = false) @DateTimeFormat(iso = ISO.DATE) LocalDate from,    @RequestParam(value = "to", required = false) @DateTimeFormat(iso = ISO.DATE) LocalDate to,    Pageable pageable) {    return service.getByQuery(name, from, to, pageable);}

服务:

public Page<ResponseDto> getByQuery(String name, LocalDate from, LocalDate to, Pageable pageable) {    return repo.getByQuery(name, from, to, pageable).map(mapper::toResponseDto);}

仓库:

@Query("select m from MyEntity m where " +       "(?1 is null or upper(m.name) like concat('%', upper(?1), '%')) " +       "and (?2 is null or m.createdAt >= ?2) " +       "and (?3 is null or m.createdAt <= ?3)")Page<MyEntity> getByQuery(String name, final LocalDate from, final LocalDate to, final Pageable pageable);

然后执行一个请求:

GET http://localhost:8080/q?name=john&from=2019-04-19&to=2019-04-19

2)使用 QueryDsl
。您应该将其添加到您的项目中(您可以在此处找到详细信息),从

QuerydslPredicateExecutor
和扩展您的仓库
QuerydslBinderCustomizer
,向其中添加一些“调整”:

public interface MyEntityRepo extends JpaRepository<MyEntity, Integer>, QuerydslPredicateExecutor<MyEntity>, QuerydslBinderCustomizer<QMyEntity> {    @Override    default void customize(@NonNull QuerydslBindings bindings, @NonNull QMyEntity entity) {        // Make case-insensitive 'like' filter for all string properties        bindings.bind(String.class).first((SinglevalueBinding<StringPath, String>) Stringexpression::containsIgnoreCase);        // Add 'between' and 'greater or equal' filter date property        bindings.bind(entity.createdAt).all((path, value) -> { Iterator<? extends LocalDate> it = value.iterator(); LocalDate from = it.next(); if (value.size() >= 2) {     LocalDate to = it.next();     return Optional.of(path.between(from, to)); // between } else {     return Optional.of(path.goe(from)); // greater than or equal }        });    }

添加服务方式:

public Page<ResponseDto> getAllByQueryDsl(Predicate predicate, Pageable pageable) {    return repo.findAll(predicate, pageable).map(mapper::toResponseDto);}

添加控制器方法:

@GetMapping("/query-dsl")public Page<ResponseDto> getAllByQueryDsl(        @QuerydslPredicate(root = MyEntity.class, bindings = MyEntityRepo.class) Predicate predicate,        Pageable pageable) {    return service.getAllByQueryDsl(predicate, pageable);}

并将

@DateTimeFormat
注释添加到实体的“日期”属性中:

@Entitypublic class MyEntity {    // ...    @DateTimeFormat(iso = ISO.DATE) private LocalDate createdAt;}

然后,您可以执行这样的请求:

GET http://localhost:8080/query-dsl?name=john&createdAt=2019-04-15&createdAt=2019-04-19

其中第一个日期是“ from”参数,第二个日期是“ to”参数。如果您仅使用一个日期-它将是’from’参数(大于或等于)。

3)使用 Specification-arg-resolver
库。将其添加到您的项目中(请参阅说明:1和2),然后从

JpaSpecificationExecutor
以下位置扩展您的存储库:

public interface MyEntityRepo extends JpaRepository<MyEntity, Integer>, JpaSpecificationExecutor<MyEntity> {}

将这样的方法添加到您的控制器中:

@GetMapping("/specification")public Page<ResponseDto> getAllBySpecification(        @And({     @Spec(path = "name", spec = LikeIgnoreCase.class),     @Spec(path = "createdAt", params = "from", spec = GreaterThanOrEqual.class),     @Spec(path = "createdAt", params = "to", spec = LessThanOrEqual.class)        }) Specification<MyEntity> specification,        Pageable pageable) {    return service.getAllBySpecification(specification, pageable);}

更新您的服务:

public Page<ResponseDto> getAllBySpecification(final Specification<MyEntity> specification, final Pageable pageable) {    return repo.findAll(specification, pageable).map(mapper::toResponseDto);}

然后请求您的数据:

GET http://localhost:8080/specification?name=john&from=2019-04-10&to=2019-04-19

4)手动建立规范:

创建一个过滤器类:

@Datapublic class MyFilter implements Specification<MyEntity> {    private String name;    @DateTimeFormat(iso = ISO.DATE) private LocalDate from;    @DateTimeFormat(iso = ISO.DATE) private LocalDate to;    @Override    public Predicate toPredicate(Root<MyEntity> root, CriteriaQuery<?> query, CriteriaBuilder builder) {        List<Predicate> predicates = new ArrayList<>();        if (name != null) predicates.add(builder.like(builder.upper(root.get("name")), "%" + name.toUpperCase() + "%"));        if (from != null) predicates.add(builder.greaterThanOrEqualTo(root.get("createdAt"), from));        if (to != null) predicates.add(builder.lessThanOrEqualTo(root.get("createdAt"), to));        return builder.and(predicates.toArray(new Predicate[0]));    }}

创建一个控制器方法:

@GetMapping("/filter")public Page<ResponseDto> getAllByMyFilter(MyFilter filter, Pageable pageable) {    return service.getAllBySpecification(filter, pageable);}

然后运行请求:

GET http://localhost:8080/filter?name=john&from=2019-04-10&to=2019-04-19


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/394146.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号