我使用Spring Data和QueryDSL 3.2.4,我想用QueryDSLs本机SQL API实现以下SQL查询:
WITH ORDER_GROUP AS ( -- TODO have to merge this subquery into the main query
SELECT
ordergroup
,count(ID) AS nofOrdersPerGroup
,MIN(priority) as minPriority
,MIN(requesteddeliverytime) as minRequestedDeliveryTime
,MIN(creationtime) as minCreationTime
FROM ORDERHEADER hh
group by orderGroup
),
ALL_ORDERS AS ( -- TODO have to merge this subquery into the main query
SELECT h.ordercode
, h.ordergroup
, h.priority
, h.requesteddeliverytime
, h.creationtime
, h.statecode
, (SELECT COUNT(ID)
FROM orderposition p
WHERE p.orderheaderid = h.ID
) AS nof_positions_per_order
, CASE
WHEN h.ordergroup IS NOT NULL
THEN g.nofOrdersPerGroup
ELSE 1
END AS nof_orders_per_group
, CASE
WHEN h.ordergroup IS NOT NULL
THEN g.minPriority
ELSE h.priority
END AS most_important_prio
, CASE
WHEN h.ordergroup IS NOT NULL
THEN g.minRequestedDeliveryTime
ELSE h.requesteddeliverytime
END AS earliest_del_time
, CASE
WHEN h.ordergroup IS NOT NULL
THEN g.minCreationTime
ELSE h.creationtime
END AS earliest_cre_time
FROM ORDERHEADER h left outer join ORDER_GROUP g on h.ordergroup = g.ordergroup
WHERE 1=1 -- TODO have to add filter clauses here
)
SELECT ordercode
, ordergroup
, priority
, requesteddeliverytime
, creationtime
, statecode
, nof_positions_per_order
, nof_orders_per_group
, most_important_prio
, earliest_del_time
, earliest_cre_time
FROM ALL_ORDERS
ORDER BY most_important_prio
, earliest_del_time
, earliest_cre_time
, priority
, requesteddeliverytime
, creationtime;
连接不在FK列上,而是在子查询ORDER_GROUP的某些任意属性上。此子查询在OrderHeader上聚合了一些最小/最大值,以便以后用于排序。
查询类型为:
package com.stoecklin.wms.entity;
import static com.mysema.query.types.PathMetadataFactory.*;
import com.mysema.query.types.path.*;
import com.mysema.query.types.PathMetadata;
import javax.annotation.Generated;
import com.mysema.query.types.Path;
import com.mysema.query.types.path.PathInits;
/**
* QOrderHeader is a Querydsl query type for OrderHeader
*/
@Generated("com.mysema.query.codegen.EntitySerializer")
public class QOrderHeader extends EntityPathBase<OrderHeader> {
private static final long serialVersionUID = 2006939562;
public static final QOrderHeader orderHeader = new QOrderHeader("orderHeader");
public final com.stoecklin.utility.database.QBaseEntity _super = new com.stoecklin.utility.database.QBaseEntity(this);
public final DateTimePath<java.util.Date> actualDeliveryTime = createDateTime("actualDeliveryTime", java.util.Date.class);
public final StringPath creationMode = createString("creationMode");
//inherited
public final DateTimePath<java.util.Date> creationTime = _super.creationTime;
public final StringPath customerCode = createString("customerCode");
public final StringPath customerOrderCode = createString("customerOrderCode");
public final StringPath deliveryCode = createString("deliveryCode");
public final StringPath deliveryNote = createString("deliveryNote");
public final StringPath headerText = createString("headerText");
public final NumberPath<Integer> hostId = createNumber("hostId", Integer.class);
public final NumberPath<Long> id = createNumber("id", Long.class);
//inherited
public final DateTimePath<java.util.Date> lastUpdateTime = _super.lastUpdateTime;
public final StringPath orderCode = createString("orderCode");
public final StringPath orderGroup = createString("orderGroup");
public final ListPath<OrderPosition, QOrderPosition> orderPositions = this.<OrderPosition, QOrderPosition>createList("orderPositions", OrderPosition.class, QOrderPosition.class, PathInits.DIRECT2);
public final StringPath orderTypeCode = createString("orderTypeCode");
public final StringPath priority = createString("priority");
public final DateTimePath<java.util.Date> requestedDeliveryTime = createDateTime("requestedDeliveryTime", java.util.Date.class);
public final StringPath setupType = createString("setupType");
public final StringPath shippingMode = createString("shippingMode");
public final StringPath stagingArea = createString("stagingArea");
public final EnumPath<com.stoecklin.wms.enums.OrderHeaderState> stateCode = createEnum("stateCode", com.stoecklin.wms.enums.OrderHeaderState.class);
public final StringPath stateReason = createString("stateReason");
public final DateTimePath<java.util.Date> stateTime = createDateTime("stateTime", java.util.Date.class);
//inherited
public final NumberPath<Long> version = _super.version;
public QOrderHeader(String variable) {
super(OrderHeader.class, forVariable(variable));
}
public QOrderHeader(Path<? extends OrderHeader> path) {
super(path.getType(), path.getMetadata());
}
public QOrderHeader(PathMetadata<?> metadata) {
super(OrderHeader.class, metadata);
}
}
和
package com.stoecklin.wms.entity;
import static com.mysema.query.types.PathMetadataFactory.*;
import com.mysema.query.types.path.*;
import com.mysema.query.types.PathMetadata;
import javax.annotation.Generated;
import com.mysema.query.types.Path;
import com.mysema.query.types.path.PathInits;
/**
* QOrderPosition is a Querydsl query type for OrderPosition
*/
@Generated("com.mysema.query.codegen.EntitySerializer")
public class QOrderPosition extends EntityPathBase<OrderPosition> {
private static final long serialVersionUID = 2091670278;
private static final PathInits INITS = PathInits.DIRECT2;
public static final QOrderPosition orderPosition = new QOrderPosition("orderPosition");
public final com.stoecklin.utility.database.QBaseEntity _super = new com.stoecklin.utility.database.QBaseEntity(this);
public final StringPath articleCode = createString("articleCode");
//inherited
public final DateTimePath<java.util.Date> creationTime = _super.creationTime;
public final NumberPath<Integer> customerOrderPos = createNumber("customerOrderPos", Integer.class);
public final NumberPath<Float> deliveredQuantity = createNumber("deliveredQuantity", Float.class);
public final StringPath fromWarehouseCode = createString("fromWarehouseCode");
public final StringPath hostData = createString("hostData");
public final StringPath hostRef = createString("hostRef");
public final NumberPath<Long> id = createNumber("id", Long.class);
//inherited
public final DateTimePath<java.util.Date> lastUpdateTime = _super.lastUpdateTime;
public final StringPath lotCode = createString("lotCode");
public final NumberPath<Float> missingQuantity = createNumber("missingQuantity", Float.class);
public final QOrderHeader orderHeader;
public final NumberPath<Integer> orderPos = createNumber("orderPos", Integer.class);
public final StringPath ownerCode = createString("ownerCode");
public final StringPath posText = createString("posText");
public final NumberPath<Float> requestedQuantity = createNumber("requestedQuantity", Float.class);
public final EnumPath<com.stoecklin.wms.enums.OrderPositionState> stateCode = createEnum("stateCode", com.stoecklin.wms.enums.OrderPositionState.class);
public final StringPath stateReason = createString("stateReason");
public final DateTimePath<java.util.Date> stateTime = createDateTime("stateTime", java.util.Date.class);
public final StringPath toBePicked = createString("toBePicked");
public final StringPath toLocation = createString("toLocation");
//inherited
public final NumberPath<Long> version = _super.version;
public QOrderPosition(String variable) {
this(OrderPosition.class, forVariable(variable), INITS);
}
public QOrderPosition(Path<? extends OrderPosition> path) {
this(path.getType(), path.getMetadata(), path.getMetadata().isRoot() ? INITS : PathInits.DEFAULT);
}
public QOrderPosition(PathMetadata<?> metadata) {
this(metadata, metadata.isRoot() ? INITS : PathInits.DEFAULT);
}
public QOrderPosition(PathMetadata<?> metadata, PathInits inits) {
this(OrderPosition.class, metadata, inits);
}
public QOrderPosition(Class<? extends OrderPosition> type, PathMetadata<?> metadata, PathInits inits) {
super(type, metadata, inits);
this.orderHeader = inits.isInitialized("orderHeader") ? new QOrderHeader(forProperty("orderHeader")) : null;
}
}
现在问题:
如何在ALL_ORDERS子查询的底部进行连接?我已经尝试了以下内容:
QOrderHeader orderHeader = QOrderHeader.orderHeader;
QOrderHeader orderHeaderGroup = new QOrderHeader("orderHeaderGroup");
QOrderPosition orderPosition = QOrderPosition.orderPosition;
List<Tuple> tuples = query.from(orderHeader)
.leftJoin(orderHeader, orderHeaderGroup).on(orderHeader.orderGroup.eq(orderHeaderGroup.orderGroup))
.list(
orderHeader.orderGroup,
orderHeader.id
);
但是这甚至不会编译,因为没有匹配的方法leftJoin可用。 连接不在FK列上,而是在某个任意属性上。子查询ORDER_GROUP
顶部显示的SQL在某种程度上针对效率进行了优化。出于这个原因,我决定使用本机SQL,因为我们周围都有子查询。
感谢任何帮助。
答案 0 :(得分:1)
如果你想使用Querydsl和SQL,你需要以不同的方式创建元模型,这里描述http://www.querydsl.com/static/querydsl/3.2.4/reference/html/ch02s03.html
还有更具体的问题:
1)FROM ORDERHEADER h左外连接ORDER_GROUP g on h.ordergroup = g.ordergroup
from(h).leftJoin(g).on(h.ordergroup.eq(g.ordergroup))
2)案例 当h.ordergroup不是NULL时 然后g.nofOrdersPerGroup ELSE 1 END AS nof_orders_per_group
new CaseBuilder()
.when(h.ordergroup.isNotNull()).then(g.nofOrderPerGroup)
.otherwise(1)
关于查询构造,连接工作与JPA不同
Querydsl JPA
query.join(entity.property, reference)
Querydsl SQL
query.join(table).on(condition)
或者
query.join(table.fk, otherTable)