我正在使用Spring Boot v1.5.3 在我的代码中,我有很多条件的搜索操作。
public Page<ParentObject> search(Pageable pageable) {
Specification<ParentObject> specification = (root, cq, cb) -> {
Predicate p = cb.and(
cb.equals(root.get("child").get("id"), "someValue"),
// a lot of predicates appended by conditions
);
return p;
};
Sort newSort = pageable.getSort().and(new Sort(Sort.Direction.ASC, "child.id"));
pageable = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), newSort)
Page<ParentObject> result = parentObjectRepository.findAll(specification, pageable);
return result;
}
问题是我的parent
表包含带有索引的child_id
字段。我希望SQL像这样:
SELECT .... FROM parent p INNER JOIN child c ON c.id = p.child_id WHERE ...
ORDER BY p.child_id ASC;
但是结果是:
SELECT .... FROM parent p INNER JOIN child c ON c.id = p.child_id WHERE ...
ORDER BY c.id ASC;
请注意ORDER BY
子句。如果我有c.id
,则不涉及索引,搜索速度慢。如果我有ORDER BY p.child_id
,它的运行速度会更快。
我尝试使用
Sort newSort = pageable.getSort().and(new Sort(Sort.Direction.ASC, "child"));
,但无法正常工作。 实体:
public class ParentObject {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "child_id", referencedColumnName = "id")
private ChildObject child;
}
我无法用本机SQL替换它,因为此搜索规范包含30多个if / else语句,并且将需要大量时间来重写代码。
如何解决此问题?预先感谢您的回答。
答案 0 :(得分:0)
最后,我找到了解决方案。众所周知,ORM通过实体与数据库一起工作。 我所有的实体都有String(UUID)值作为ID。因此,我将以下代码添加到了ParentObject中:
public class ParentObject {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "child_id", referencedColumnName = "id")
private ChildObject child;
@Column(name = "child_id", insertable = false, updatable = false)
private String childId;
}
如您所见,在这里我添加了一个简单的字段,其中包含子对象的ID。将此字段标记为insertable = false, updatable = false
很重要,我们不能在代码中更改此字段,这是只读字段。但这使我们能够按parent.child_id
而不是child.id
对结果进行排序。如果需要替换子对象,只需调用setChild(newValue)
。
最后,我的搜索方法现在看起来像:
public Page<ParentObject> search(Pageable pageable) {
Specification<ParentObject> specification = (root, cq, cb) -> {
Predicate p = cb.and(
cb.equals(root.get("child").get("id"), "someValue"),
// a lot of predicates appended by conditions
);
return p;
};
// IMPORTANT change in next line
Sort newSort = pageable.getSort().and(new Sort(Sort.Direction.ASC, "childId"));
pageable = new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), newSort)
Page<ParentObject> result = parentObjectRepository.findAll(specification, pageable);
return result;
}
结果,我有以下SQL查询:
SELECT .... FROM parent p INNER JOIN child c ON c.id = p.child_id WHERE ...
ORDER BY p.child_id ASC;
希望这对某人有用