package jef.database.query; import java.io.Serializable; import java.util.AbstractList; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import jef.database.Condition; import jef.database.Condition.Operator; import jef.database.DbUtils; import jef.database.Field; import jef.database.IConditionField; import jef.database.IQueryableEntity; import jef.database.ORMConfig; import jef.database.SelectProcessor; import jef.database.Session.PopulateStrategy; import jef.database.dialect.DatabaseDialect; import jef.database.dialect.type.ColumnMapping; import jef.database.meta.AbstractMetadata; import jef.database.meta.EntityType; import jef.database.meta.ITableMetadata; import jef.database.meta.MetaHolder; import jef.database.meta.Reference; import jef.database.routing.PartitionResult; import jef.database.wrapper.clause.BindSql; import jef.database.wrapper.clause.GroupClause; import jef.database.wrapper.clause.QueryClause; import jef.database.wrapper.clause.QueryClauseImpl; import jef.database.wrapper.populator.Transformer; import jef.database.wrapper.variable.ConstantVariable; import jef.database.wrapper.variable.Variable; import jef.tools.ArrayUtils; import jef.tools.Assert; @SuppressWarnings("serial") public class PKQuery<T extends IQueryableEntity> extends AbstractQuery<T>{ private List<Serializable> pkValues; private boolean cascadeViaOuterJoin=ORMConfig.getInstance().isUseOuterJoin(); /** * 结果转换器 */ protected final Transformer t; @SuppressWarnings("unchecked") public PKQuery(ITableMetadata clz,Serializable... pks){ if(clz.getType()==EntityType.TEMPLATE){ String key=String.valueOf(pks[0]); pks=(Serializable[]) ArrayUtils.subarray(pks, 1, pks.length); this.type=((AbstractMetadata)clz).getExtension(key).getMeta(); }else{ this.type=clz; } this.instance=(T) clz.newInstance(); if(type.getPKFields().size()>pks.length){ throw new IllegalArgumentException("The primark key count is not match input value:"+type.getPKFields().size()+">"+pks.length); } this.cacheable=type.isCacheable(); t=new Transformer(type); t.setLoadVsOne(type.isUseOuterJoin()); t.setLoadVsMany(true); pkValues=Arrays.asList(pks); context= new SqlContext("t", this); } @SuppressWarnings("unchecked") public PKQuery(ITableMetadata meta, List<Serializable> pkValueSafe, IQueryableEntity obj) { this.type=meta; this.instance=(T) obj; this.cacheable=type.isCacheable(); t=new Transformer(type); pkValues=pkValueSafe; context= new SqlContext("t", this); } public List<Condition> getConditions() { return new AbstractList<Condition>() { @Override public Condition get(int index) { ColumnMapping m=type.getPKFields().get(index); Object value=pkValues.get(index); Assert.notNull(value); return new Condition(m.field(),Operator.EQUALS,value); } @Override public int size() { return type.getPKFields().size(); } }; } @Override public QueryClause toQuerySql(SelectProcessor processor, SqlContext context, boolean order) { String tableName = (String) getAttribute(JoinElement.CUSTOM_TABLE_NAME); if (tableName != null) tableName = MetaHolder.toSchemaAdjustedName(tableName); PartitionResult[] prs = DbUtils.toTableNames(getInstance(), tableName, this, processor.getPartitionSupport()); DatabaseDialect profile = processor.getProfile(prs); BindSql whereResult = toPrepareWhereSql(context, profile); QueryClauseImpl result = new QueryClauseImpl(profile); result.setGrouphavingPart(GroupClause.DEFAULT); result.setSelectPart(SelectProcessor.toSelectSql(context, GroupClause.DEFAULT, profile)); result.setTables(type.getTableName(false), prs); result.setWherePart(whereResult.getSql()); result.setBind(whereResult.getBind()); return result; } public BindSql toPrepareWhereSql(SqlContext context, DatabaseDialect profile) { int size=pkValues.size(); StringBuilder sb=new StringBuilder(128).append(" where "); List<Variable> bind = new ArrayList<Variable>(size); Iterator<ColumnMapping> pkfields=type.getPKFields().iterator(); if(!pkfields.hasNext()){ throw new IllegalArgumentException("The entity ["+type.getName()+"] has no primary key."); } int n=0; ColumnMapping field=pkfields.next(); sb.append(field.getColumnName(profile, true)).append("= ?"); bind.add(new ConstantVariable(field.fieldName(),pkValues.get(n++),field)); while(pkfields.hasNext()){ field=pkfields.next(); sb.append(" and ").append(field.getColumnName(profile, true)).append("= ?"); bind.add(new ConstantVariable(field.fieldName(),pkValues.get(n++),field)); } return new BindSql(sb.toString(), bind); } public EntityMappingProvider getSelectItems() { return context; } public void setSelectItems(Selects select) { throw new UnsupportedOperationException(); } public SqlContext prepare() { return context; } private SqlContext context; public void clearQuery() { } @SuppressWarnings("unchecked") public Collection<OrderField> getOrderBy() { return Collections.EMPTY_LIST; } public void setOrderBy(boolean asc, Field... orderby) { throw new UnsupportedOperationException(); } public void addOrderBy(boolean asc, Field... orderby) { throw new UnsupportedOperationException(); } public void setAttribute(String key, Object value) { throw new UnsupportedOperationException(); } public Object getAttribute(String key) { return null; } @SuppressWarnings("unchecked") public Map<String, Object> getAttributes() { return Collections.EMPTY_MAP; } public Query<T> addExtendQuery(Query<?> querys) { throw new UnsupportedOperationException(); } public Query<T> setAllRecordsCondition() { throw new UnsupportedOperationException(); } public Query<T> addCondition(Field field, Object value) { throw new UnsupportedOperationException(); } public Query<T> addCondition(Field field, Operator oper, Object value) { throw new UnsupportedOperationException(); } public Query<T> addCondition(IConditionField field) { throw new UnsupportedOperationException(); } public Query<T> addCondition(Condition condition) { throw new UnsupportedOperationException(); } @SuppressWarnings("unchecked") public Map<Reference, List<Condition>> getFilterCondition() { return Collections.EMPTY_MAP; } public Query<?>[] getOtherQueryProvider() { return EMPTY_Q; } public void setCustomTableName(String name) { throw new UnsupportedOperationException(); } public Query<T> addCascadeCondition(Condition cond) { throw new UnsupportedOperationException(); } public Query<T> addCascadeCondition(String refName, Condition... conds) { throw new UnsupportedOperationException(); } @Override public String toString() { return type.getName()+"[PK]"; } public boolean isCascadeViaOuterJoin() { return cascadeViaOuterJoin; } public void setCascadeViaOuterJoin(boolean cascadeViaOuterJoin) { this.cascadeViaOuterJoin=cascadeViaOuterJoin; } public void setCascade(boolean cascade) { t.setLoadVsMany(cascade); t.setLoadVsOne(cascade); } @Override public boolean isAll() { return false; } @Override public Transformer getResultTransformer() { return t; } @Override public boolean isSelectCustomized() { PopulateStrategy[] s=t.getStrategy(); if(s!=null && s.length>0)return true; return false; } }