我使用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