标准查询JPA-CriteriaBuilder eclipseLink优化

时间:2016-03-09 08:17:41

标签: java jpa eclipselink criteria

我正在使用eclipse链接开发标准JPA标准构建器查询,但是当路径导航超过两个对象时,我不知道如何优化。例如,如果我的类被称为Car,Car.objectA.objectB.objectC .. CriteriaBuilder重复加入'表

这是我的查询代码:

public List<T> getOrderedByFieldsValues(String sortField, SortOrder sortOrder, Map<String, Object> fieldValues) {
        //@formatter:off
        List<T> retorno = new ArrayList<T>();
        CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
        CriteriaQuery<T> criteriaQuery = criteriaBuilder.createQuery(getEntityClass());

        Root<T> from = criteriaQuery.from(getEntityClass());
        Predicate fullPredicate = null;
        if (!fieldValues.isEmpty()) {
            for (String fieldName : fieldValues.keySet()) {
                if (!fieldName.contains(".")) {
                    if(predicateCompleto == null){
                    predicateCompleto = criteriaBuilder.equal(from.get(fieldName), fieldValues.get(fieldName));
                }else{
                    predicateCompleto = criteriaBuilder.and(predicateCompleto,criteriaBuilder.equal(from.get(fieldName), fieldValues.get(fieldName)));
                }
                } else {
                    String[] campos = fieldName.split("\\.");
                    if (campos.length > 0) {// @formatter:off
                        if (campos.length <= 2) { 
                            Join<T, T> p = from.join(campos[0]);
                            if(fullPredicate == null){
                                fullPredicate = criteriaBuilder.equal(p.get(campos[1]), fieldValues.get(fieldName));
                            }else{
                                fullPredicate = criteriaBuilder.and(fullPredicate , criteriaBuilder.equal(p.get(campos[1]), fieldValues.get(fieldName)));
                            }
                        } else {
                           //GENERATE DUPLICATE JOIN!!
                            Join<T, T>[]x = new Join[10];
                           //More than 10 joins is a party
                            for (int i = 0; i < campos.length; i++) {
                                if(!(i == (campos.length-1))){
                                    if(i==0){
                                        String valor = campos[i];
                                        x[i] = from.join(valor);
                                    }else{
                                        if(i == 1){
                                            x[i] = x[0].join(campos[i]);
                                        }else{
                                            //añadimos a la join anterior
                                            x[i-1] = x[i-1].join(campos[i]);
                                        }
                                    }
                                }else{
                                    if(fullPredicate == null){
                                        fullPredicate = criteriaBuilder.equal(x[i-1].get(campos[i]), fieldValues.get(fieldName));
                                    }else{
                                        fullPredicate  = criteriaBuilder.and(fullPredicate , criteriaBuilder.equal(x[i-1].get(campos[i]), fieldValues.get(fieldName)));
                                    }
                                }
                            }
                        }
                    }   
                }
            }
            // WHERE 
            criteriaQuery.where(predicateCompleto);
        }
        if (sortField != null) {
            String[] fields = sortField.split("\\.");
            if (fields.length > 0) {
                Path<Object> path = from.get(fields[0]);
                for (int i = 1; i < fields.length; i++) {
                    path = path.get(fields[i]);
                }
                if (sortOrder == SortOrder.ASCENDING) {
                    criteriaQuery.orderBy(new Order[] { criteriaBuilder.asc(path) });
                } else if (sortOrder == SortOrder.DESCENDING) {
                    criteriaQuery.orderBy(new Order[] { criteriaBuilder.desc(path) });
                }
            }
        }

        TypedQuery<T> typedQuery = getEntityManager().createQuery(criteriaQuery);
        retorno = typedQuery.getResultList();

        if(LOGGER.isDebugEnabled()){
            LOGGER.info("QUERY - QUERY: " + typedQuery.unwrap(JpaQuery.class).getDatabaseQuery().getSQLString());
        }

        return retorno;
    }

使用这些参数从同一个表中生成差异别名..

HashMap<String, Object> params = new HashMap<String, Object>();
        params.put("label.labelId", labelId);
        params.put("collection.collectionId", collectionId);
        params.put("label.format.formatId", 1L);//3 objects path
        params.put("label.kindOfLabel.tipoLabelId", 1L);//3 path  

结果SQL QUERY:

SELECT t1.LABEL_COLECCTIONS_ID,
  t1.ACTIVE,
  t1.COMMENTS,
  t1.CREATED_BY,
  t1.CREATION_DATE,
  t1.FILE_SUPPLIER,
  t1.FILE_SUPPLIER_CONTENT_TYPE,
  t1.LAST_UPDATE_DATE,
  t1.LAST_UPDATED_BY,
  t1.REVISION,
  t1.SAMPLE,
  t1.COLLECTION_ID,
  t1.LABEL_ID,
  t1.RELATED_LABEL_COLLECTION_ID,
  t1.RELATED_SEASON_ID
FROM BET_LABELS t6,
  BET_COLLECTION t5,
  BET_FORMATO t4,
  BET_LABELS t3,
  BET_TIPO_LABEL t2,
  BET_LABEL_COLLECTIONS t1,
  BET_LABELS t0
WHERE (((((t0.TIPO_LABEL_ID = ?)
AND (t1.COLLECTION_ID       = ?))
AND (t1.LABEL_ID            = ?))
AND (t3.FORMATO_ID          = ?))
AND ((((((t0.LABEL_ID       = t1.LABEL_ID)
AND (t3.LABEL_ID            = t1.LABEL_ID))
AND (t2.TIPO_LABEL_ID       = t0.TIPO_LABEL_ID))
AND (t4.FORMATO_ID          = t3.FORMATO_ID))
AND (t5.COLLECTION_ID       = t1.COLLECTION_ID))
AND (t6.LABEL_ID            = t1.LABEL_ID)))

我正在研究解决方案,但也许有些人发现这是一个有趣的问题,任何线索都会感激不尽。 TY。

0 个答案:

没有答案