package jef.database.query; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import jef.database.Condition; import jef.database.DbUtils; import jef.database.Field; import jef.database.QueryAlias; import jef.database.Session.PopulateStrategy; import jef.database.meta.ITableMetadata; import jef.database.wrapper.populator.Transformer; public abstract class AbstractJoinImpl implements Join{ //额外的数据属性 protected Map<String,Object> attribute; private int maxResult; private int fetchSize; private int timeout; private boolean cacheable=true; private Transformer t; //调用prepare后,查询进入实例阶段 protected SqlContext context; //只有rootJoin才有Context private Map<Query<?>,List<Condition>> refConditions; @Override public boolean isSelectCustomized() { PopulateStrategy[] s=t.getStrategy(); if(s!=null && s.length>0)return true; return context.getSelectsImpl()!=null; } public EntityMappingProvider getSelectItems() { return context.getSelectsImpl()==null?context:context.getSelectsImpl(); } public void fillAttribute(Query<?> q){ this.attribute=q.getAttributes(); this.t=q.getResultTransformer(); } public void setMaxResult(int size) { this.maxResult=size; } public void setFetchSize(int size) { this.fetchSize=size; } public void setQueryTimeout(int timout) { this.timeout=timout; } public int getMaxResult() { return maxResult; } public int getFetchSize() { return fetchSize; } public int getQueryTimeout() { return timeout; } public Map<String, Object> getAttributes() { return attribute; } /** *得到所有条件 */ public List<Condition> getConditions() { List<Condition> cond=new ArrayList<Condition>(); for(JoinElement je:elements()){ cond.addAll(je.getConditions()); } return cond; } @SuppressWarnings("unchecked") public Map<Query<?>, List<Condition>> getRefConditions() { return refConditions==null?Collections.EMPTY_MAP:refConditions; } public void addRefConditions(Query<?> q,List<Condition> cons) { if(refConditions==null){ refConditions=new HashMap<Query<?>,List<Condition>>(); } refConditions.put(q, cons); } /** * 返回全部排序字段 */ public List<OrderField> getOrderBy(){ List<OrderField> result=new ArrayList<OrderField>(); for(QueryAlias q:this.allElements()){ for(OrderField field: q.getQuery().getOrderBy()){ field.prepareFlow((Query<?>)q.getQuery()); result.add(field); } } return result; } public void setAttribute(String key, Object value) { if(attribute==null){ attribute=new HashMap<String,Object>(); } attribute.put(key, value); } public Object getAttribute(String key) { if(attribute==null){ return null; } return attribute.get(key); } public void setSelectItems(Selects select) { this.context.selectsImpl=(SelectsImpl)select; } public void addOrderBy(boolean asc, Field... orderbys) { List<Query<?>> elements=elements(); Query<?> ele=elements().get(elements.size()-1); for (Field f : orderbys) { if ((f instanceof RefField)) { ele.addOrderBy(asc, f); }else{ ITableMetadata meta=DbUtils.getTableMeta(f); Query<?> q=findBind(meta,elements); if(q==ele){ ele.addOrderBy(asc, f); }else{ ele.addOrderBy(asc, new RefField(q,f)); } } } } private Query<?> findBind(ITableMetadata meta,List<Query<?>> elements) { Query<?> result=null; for(Query<?> ele: elements){ if(meta==ele.getMeta()){ if(result==null){ result=ele; }else{ throw new IllegalStateException("Multiple Query of ["+meta.getSimpleName()+"] in the join, please user RefField to Bind to a special Query."); } } } return result; } public JoinElement orderByAsc(Field... ascFields) { addOrderBy(true, ascFields); return this; } public JoinElement orderByDesc(Field... descFields) { addOrderBy(false, descFields); return this; } public void setOrderBy(boolean asc, Field... orderby) { List<Query<?>> elements=elements(); JoinElement ele=elements().get(elements.size()-1); ele.setOrderBy(asc, orderby); } /** * 清除查询条件 */ public void clearQuery() { for(QueryAlias al:allElements()){ al.getQuery().clearQuery(); } } public Transformer getResultTransformer(){ if(t==null){ t=new Transformer(); } return t; } public void setResultTransformer(Transformer t){ this.t=t; } public boolean isCacheable() { return cacheable; } public void setCacheable(boolean cacheable) { this.cacheable = cacheable; } }