JPA 中构建复杂查询/Geometry关系查询

default

方法一:利用 Predicate 构建查询条件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Specification<DataDO> specification = (root, query, builder) -> {
    List<Predicate> list = new ArrayList<>();

    Predicate isDeletedPredicate = builder.equal(root.get("isDeleted"), 0);
    list.add(isDeletedPredicate);

    Predicate publishPredicate = builder.equal(root.get("publishStatus"), DataPublishStatusEnum.PUBLISH_SUCCESS.getCode());
    list.add(publishPredicate);
    // 添加名称搜索条件
    addNamePredicate(dataSearchVO, root, builder, list);
    // 添加标签搜索条件
    addLabelPredicate(dataSearchVO, root, builder, list);
    // 添加数据类型搜索条件
    addDataTypePredicate(dataSearchVO, root, builder, list);
    // 添加空间搜索条件
    addGeometryPredicate(dataSearchVO.getGeometry(), builder, root, list);
    // 添加行政区范围搜索条件
    addGeometryPredicate(dataSearchVO.getPacGeometry(), builder, root, list);
    // 添加发布时间搜索条件
    addTimesPredicate(dataSearchVO.getPublishTime(), builder, root, "publishTime", list);
    // 添加创建时间搜索条件
    addTimesPredicate(dataSearchVO.getCreateTime(), builder, root, "createTime", list);
    Predicate predicate = builder.and(list.toArray(new Predicate[0]));
    return query.where(predicate).getRestriction();
};
return dataMapper.findAll(specification, pageable);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
private static void addNamePredicate(DataSearchVO dataSearchVO, Root<DataDO> root, CriteriaBuilder builder, List<Predicate> list) {
    String categoryName = dataSearchVO.getCategoryName();
    if (categoryName != null) {
        Predicate namePredicate = builder.like(root.get("categoryName"), "%" + categoryName + "%");
        list.add(namePredicate);
    }
}

private static void addLabelPredicate(DataSearchVO dataSearchVO, Root<DataDO> root, CriteriaBuilder builder, List<Predicate> list) {
    String[] categoryLabels = dataSearchVO.getCategoryLabel();
    if (!ObjectUtils.isEmpty(categoryLabels)) {
        CriteriaBuilder.In<Object> in = builder.in(root.get("categoryLabel"));
        for (String label : categoryLabels) {
            in.value(label);
        }
        list.add(in);
    }
}

private static void addDataTypePredicate(DataSearchVO dataSearchVO, Root<DataDO> root, CriteriaBuilder builder, List<Predicate> list) {
    Integer[] dataTypes = dataSearchVO.getDataType();
    if (!ObjectUtils.isEmpty(dataTypes)) {
        CriteriaBuilder.In<Object> in = builder.in(root.get("dataType"));
        for (Integer dataType : dataTypes) {
            in.value(dataType);
        }
        list.add(in);
    }
}

private static void addGeometryPredicate(Geometry dataSearchVO, CriteriaBuilder builder, Root<DataDO> root, List<Predicate> list) {
    Geometry pacGeometry = dataSearchVO;
    if (pacGeometry != null) {
        Expression<Boolean> withInExpression = builder.function("st_intersects", Boolean.class, root.get("extent"), builder.literal(pacGeometry));
        Predicate geometryPredicate = builder.isTrue(withInExpression);
        list.add(geometryPredicate);
    }
}

private static void addTimesPredicate(Date[] times, CriteriaBuilder builder, Root<DataDO> root, String timeFieldName, List<Predicate> list) {
    if (ArrayUtils.isNotEmpty(times)) {
        if (times.length >= 1 && !ObjectUtils.isEmpty(times[0])) {
            Predicate createTimePredicate = builder.greaterThanOrEqualTo(root.get(timeFieldName), times[0]);
            list.add(createTimePredicate);
        }

        if (times.length >= 2 && !ObjectUtils.isEmpty(times[1])) {
            Predicate createTimePredicate = builder.lessThanOrEqualTo(root.get(timeFieldName), times[1]);
            list.add(createTimePredicate);
        }
    }
}

方法二:利用sql语句

当需要过滤空参数,仅对非空参数进行查询时,需要在 SQL 语句中进行参数非空判断,导致代码更复杂。

1
2
3
4
@Query(value = "select * from data "
        " where st_intersects(geom, ?) " +
        " order by create_time desc ", nativeQuery = true)
List<DataDO> queryLabel(geom Geometry);
Gear(夕照)的博客。记录开发、生活,以及一些不足为道的思考……