原由是羣內某個朋友在使用JPA構建查詢的時候遇到了一個問題,上了羣裏尋求答案。當時我覺得只是簡單的多列查詢,就寫了使用EntityManager的方式建立多列查詢的代碼貼出去,羣友看了以後告訴我他想要的是 SUM(A*B) 的狀況,當時我有點懵逼,也想不到怎麼解決。java
結果今天在查看QueryDSL的案例demo的時候翻閱到ObjectDB網站的文檔中,無心間竟然發現了當時那個問題的答案( ObjectDB網頁鏈接)mysql
@Service public class DemoBiz{ @PersistenceContext private EntityManager em; /* * Specification寫法是實現toPredicate方法: * Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb); */ /** * 多列查詢 */ public void showTupleResult() { // 獲取CriteriaBuilder對象,也就是Specification寫法裏面的cb CriteriaBuilder cb = em.getCriteriaBuilder(); // 構建多列Query,也就是Specification寫法裏面的query CriteriaQuery<Tuple> query = cb.createTupleQuery(); // 經過from方法獲取Users類的Root,也就是Specification寫法的root /* * Users表包含int id, String name, int age, int gender, 列 */ Root<Users> root = query.from(Users.class); // 獲取id和name列的path Path<Integer> pathId = root.get("id"); Path<String> pathName = root.get("name"); // 設置select列代碼 query.select(cb.tuple(pathId, pathName)); // 經過query構建TypedQuery TypedQuery<Tuple> resultQuery = em.createQuery(query); // 開始查詢,得到結果集 List<Tuple> resultList = typedQuery.getResultList(); // 遍歷輸出 for (Tuple tuple : resultList) { Object id = tuple.get(0); Object name = tuple.get(1); System.out.println(id + "\t" + name); } } }
CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Tuple> query = cb.createTupleQuery(); // 獲取書桌Root,Desk包含int id, double width, double Length, int type列 Root<Desk> root = query.from(Desk.class); Path<double> width = root.get("width"); Path<double> length = root.get("length"); Path<int> type = root.get("type"); // 計算兩個列的乘積 Expression<double> prod = cb.prod(width,length); // 求和 Expression<double> sum = cb.sum(prod); // 查詢 sum(width, length), width, length, type 四個列 query.select(cb.tuple(sum, amount, fee, orderId)); // mysql的group by支持非聚合函數和group by字段外的列 query.groupBy(orderId); TypedQuery<Tuple> resultQuery = em.createQuery(query); List<Tuple> resultList = resultQuery.getResultList(); System.out.printf("%-20s%-20s%-20s%-20s\n","總面積","長","寬","分類"); System.out.println("--------------------------------------------------------------------------------------------"); for (Tuple tuple : resultList) { System.out.printf("%-20s%-20s%-20s%-20s\n",tuple.get(0), tuple.get(1), tuple.get(2), tuple.get(3)); }
最開始咱們日常加減乘除求餘的寫法通常是 add(+), sub(-), mul(*), div(/) , mod(%),可是CriteriaBuilder的下的函數命名有一些些不同,可能不太熟悉的就找不到,前面就吃了這個虧了,prod也有"乘積"的意思在裏面,具體操做代碼以下(參考連接)sql
// Create path and parameter expressions: Expression<Integer> path = country.get("population"); Expression<Integer> param = cb.parameter(Integer.class); // Addition (+) Expression<Integer> sum1 = cb.sum(path, param); // expression + expression Expression<Integer> sum2 = cb.sum(path, 1000); // expression + number Expression<Integer> sum3 = cb.sum(1000, path); // number + expression // Subtraction (-) Expression<Integer> diff1 = cb.diff(path, param); // expression - expression Expression<Integer> diff2 = cb.diff(path, 1000); // expression - number Expression<Integer> diff3 = cb.diff(1000, path); // number - expression // Multiplication (*) Expression<Integer> prod1 = cb.prod(path, param); // expression * expression Expression<Integer> prod2 = cb.prod(path, 1000); // expression * number Expression<Integer> prod3 = cb.prod(1000, path); // number * expression // Division (/) Expression<Integer> quot1 = cb.quot(path, param); // expression / expression Expression<Integer> quot2 = cb.quot(path, 1000); // expression / number Expression<Integer> quot3 = cb.quot(1000, path); // number / expression // Modulo (%) Expression<Integer> mod1 = cb.mod(path, param); // expression % expression Expression<Integer> mod2 = cb.mod(path, 1000); // expression % number Expression<Integer> mod3 = cb.mod(1000, path); // number % expression // Math(abs, exp, sqrt) Expression<Integer> abs = cb.abs(param); // ABS(expression) Expression<Integer> neg = cb.neg(path); // -expression Expression<Integer> sqrt = cb.sqrt(cb.literal(100)); // SQRT(expression)