關於在JPA中的多列計算查詢方法

原因

原由是羣內某個朋友在使用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));
}

關於CriteriaBuilder中的一些運算

最開始咱們日常加減乘除求餘的寫法通常是 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)
相關文章
相關標籤/搜索