我使用OpenJPA 1.2.x 我想創建漂亮的過濾功能。現在看起來很糟糕。也許有人有過練習,如果是的話,請建議它如何看起來更好。 這個想法是:我有一個實體事件。此實體有幾種類型(EventType,CommunicationType等等)。事件可以使用這些類型和日期範圍進行過濾。 問題是每個新的過濾標準都會導致方法中出現新的spagetti。證據消失,方法將變得難以維繫。JPQL多個連接,同時動態查詢建立
需要最佳實踐,請建議。 請參閱我的通心粉:
@Override
@SuppressWarnings("unchecked")
public List<Event> listEvents(Filter filter){
List<Event> dayEvents = null;
StringBuilder sbQuery = new StringBuilder(128); //dynamic query building
StringBuilder sbQueryJoins = new StringBuilder(128); //joins of nested entities
HashMap<String, Object> queryParams = new HashMap<String, Object>(); //keeps namedParam=>value
boolean hasCondition = false; //has any condition or not
/** replace #->JOINS<-# before creating JPQL Query object. */
sbQuery.append("select evt from Event evt #->JOINS<-# where ");
/**
* Set date period.
* Attention, {@link Filter#getTimePeriod()} can't be null.
* */
if(filter.getSelectedDate()!=null){
DateUtil.Period period = new DateUtil.Period(filter.getTimePeriod(), filter.getSelectedDate());
queryParams.put("startOfPeriod",period.getBegin());
queryParams.put("endOfPeriod", period.getEnd());
sbQuery.append(" (evt.beginDate >= :startOfPeriod and evt.beginDate <= :endOfPeriod) ");
hasCondition = true;
}
if(filter.getDepartmentId()!=null){
throw new MethodNotImplementedException("Filtering on Event.departments is not implemented yet. Do not provide Deparments as filter parameters");
}
if(filter.getEventCommunicationId()!=null && filter.getEventCommunicationId()!= Filter.ALL_EVENTS_OF_TYPE){
if(hasCondition){
sbQuery.append(" and ");
}
sbQueryJoins.append(" JOIN evt.eventCommunication evtCommunucation ");
sbQuery.append(" evtCommunucation.id = :eventCommunicationId ");
queryParams.put("eventCommunicationId", filter.getEventCommunicationId());
hasCondition = true;
}
if(filter.getEventImportanceId()!=null && filter.getEventImportanceId()!= Filter.ALL_EVENTS_OF_TYPE){
if(hasCondition){
sbQuery.append(" and ");
}
sbQueryJoins.append(" JOIN evt.eventImportance evtImportance ");
sbQuery.append(" evtImportance.id = :eventImportanceId ");
queryParams.put("eventImportanceId", filter.getEventImportanceId());
hasCondition = true;
}
if(filter.getEventTypeId()!=null && filter.getEventTypeId()!= Filter.ALL_EVENTS_OF_TYPE){
if(hasCondition){
sbQuery.append(" and ");
}
sbQueryJoins.append(" JOIN evt.eventType evtType ");
sbQuery.append(" evtType.id = :eventTypeId ");
queryParams.put("eventTypeId", filter.getEventTypeId());
hasCondition = true;
}
// ordering
sbQuery.append(" order by evt.beginDate asc ");
sbQuery.replace(sbQuery.indexOf("#->"), sbQuery.indexOf("<-#")+3, sbQueryJoins.toString());
LOG.trace("#listEvents -> Trying to execute JPQL query [{}] with params[{}]:",sbQuery, queryParams);
Query query = em.createQuery(sbQuery.toString());
for(Map.Entry<String, Object> entry : queryParams.entrySet()){
query.setParameter(entry.getKey(), entry.getValue());
}
dayEvents = query.getResultList();
return dayEvents;
}
1.這是一個直接的方式來分割地獄:) – Sergey 2010-11-09 10:47:12
哎呀,對不起,雙重職位。 2.不能使用專有,不能升級:( – Sergey 2010-11-09 10:48:01
@Sergey:是的,1.不會給你高度可維護的代碼。你需要一些番茄醬嗎? – 2010-11-09 11:17:24