我有两张表格如下:
Table_0
ID Description
5 description5
6 description6
7 description7
8 description8
TABLE_1
ID Table_0_ID Status
1 5 LOADED
2 6 LOADED
3 7 LOADED
4 7 LOADED
TABLE_2
ID Table_1_ID
1 1
2 2
3 3
4 4
当我调用findAll查询时,我的预期结果是它消除了重复,因此结果将返回(对于两个表)三行(table_1 id从1到3)。
我编写了命名查询和条件构建器查询,但最后一个查询速度提高了4倍。我想知道为什么。我犯了错误吗?
以下是代码:
query = "SELECT OBJECT(sb) FROM Table_2 sb WHERE sb.Table_1.id IN (SELECT MAX(maxsr.id) FROM Table_1 maxsr WHERE maxsr.status = LOADED GROUP BY maxsr.Table_0.id)")
标准构建者:
final EntityManager em = getEntityManager();
final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<Table_2> criteriaQuery = cb.createQuery(Table_2.class);
final Root<Table_2> root = criteriaQuery.from(Table_2.class);
Predicate p = getPredicateOnList(data, cb, root, gateSession);
if (p != null) {
criteriaQuery.where(p);
}
final Query q = getEntityManager().createQuery(criteriaQuery);
return q.getResultList();
}
方法getPredicateOnList
private Predicate getPredicateOnList(final PaginationData data, final CriteriaBuilder cb, final Root<Table_2> root) {
final Join<Table_2, Table_1> readingJoin = root.join("Table_1");
boolean filterUnloaded = false;
boolean selectMax = true;
for (KeyValuePair pair : data.getRequestParams()) {
if (pair.getKey().equalsIgnoreCase("filterUnloaded")) {
filterUnloaded = ParsingUtils.parseBoolean(pair.getValue(), false);
}
if (pair.getKey().equalsIgnoreCase("selectMax")) {
selectMax = ParsingUtils.parseBoolean(pair.getValue(), true);
}
}
Predicate predicate = null;
if (selectMax) {
List<Long> maxReadingIds = getMaxReadingIds(gateSession.getId(), filterUnloaded);
if (maxReadingIds == null || maxReadingIds.isEmpty()) {
//do nothing
} else {
predicate = readingJoin.get("id").in(maxReadingIds);
}
}
return predicate;
}
方法getMaxReadingIds
private List<Long> getMaxReadingIds(Long sessionId, boolean filterUnloaded) {
final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<Long> maxReadingIdQuery = cb.createQuery(Long.class);
final Root<Table_1> Table_1Root = maxReadingIdQuery.from(Table_1.class);
final Path<Long> idGet = Table_1Root.get("id");
maxReadingIdQuery.select(cb.greatest(idGet));
final Join<Table_1, Table_0> join = Table_1Root.join("Table_0");
maxReadingIdQuery.groupBy(join.get("id"));
Predicate predicate = null;
if (filterUnloaded) {
predicate = cb.equal(Table_1Root.get("status"), LOADED);
}
//omiss sessionId parameter
if (predicate != null) {
maxReadingIdQuery.where(predicate);
}
final Query q = getEntityManager().createQuery(maxReadingIdQuery);
return q.getResultList();
}
(我做了一些简化,如果代码没有明确定义请告诉我,我提供更多信息) 两个结果都是正确的,但标准构建器更快。