如何通过单次ObjectBox数据库查询实现两列求和?
Can I Calculate Two Field Sums in a Single Database Query?
Absolutely! You can absolutely compute the sum of both field1 and field2 in one database round-trip—this is way more efficient than running two separate queries, as it cuts down on database communication overhead. Since your original code uses QueryDSL-style syntax (the boxFor method is a dead giveaway), here's how to adjust it:
Single Query Implementation with Tuple
The simplest way is to fetch both sums as a Tuple (QueryDSL's built-in container for query results):
// Initialize your base query QQuery<A> query = controller.getStore().boxFor(A.class).query(); // Define the sum expressions for both fields Expression<Long> sumField1Expr = query.property(A_.field1).sum(); Expression<Long> sumField2Expr = query.property(A_.field2).sum(); // Fetch both sums in one go Tuple sumTuple = query.select(sumField1Expr, sumField2Expr).fetchOne(); // Extract the values (handle nulls if no records exist!) Long sum1 = Objects.requireNonNullElse(sumTuple.get(sumField1Expr), 0L); Long sum2 = Objects.requireNonNullElse(sumTuple.get(sumField2Expr), 0L); // Calculate total if needed Long totalSum = sum1 + sum2;
Alternative: Use a Custom DTO for Cleaner Results
If you prefer a more type-safe approach over Tuple, create a simple DTO class to hold the sums, then use QueryDSL's projections to map the result directly:
Step 1: Create the DTO
public class FieldSums { private final Long sumField1; private final Long sumField2; // Constructor must match the order of selected expressions public FieldSums(Long sumField1, Long sumField2) { this.sumField1 = sumField1; this.sumField2 = sumField2; } // Getters public Long getSumField1() { return sumField1; } public Long getSumField2() { return sumField2; } }
Step 2: Fetch the Result into the DTO
QQuery<A> query = controller.getStore().boxFor(A.class).query(); Expression<Long> sumField1Expr = query.property(A_.field1).sum(); Expression<Long> sumField2Expr = query.property(A_.field2).sum(); FieldSums sums = query.select(Projections.constructor( FieldSums.class, sumField1Expr, sumField2Expr )).fetchOne(); // Access sums safely (again, handle nulls if needed) Long totalSum = Objects.requireNonNullElse(sums.getSumField1(), 0L) + Objects.requireNonNullElse(sums.getSumField2(), 0L);
Key Notes
- This approach generates a single SQL query that looks roughly like:
SELECT SUM(a.field1), SUM(a.field2) FROM A a - If your fields are of type
Integerinstead ofLong, just swap the type in the expressions and DTO. - Always handle
nullvalues! If there are no records in the table,sum()will returnnull—usingObjects.requireNonNullElseensures you get a default0instead of aNullPointerException.
内容的提问来源于stack exchange,提问作者Сергей Кавказов
相关产品推荐
相关产品推荐

