collectionloader.java

来自「hibernate-3.0.5 中文文档」· Java 代码 · 共 201 行

JAVA
201
字号
//$Id: CollectionLoader.java,v 1.9 2005/05/19 07:28:57 steveebersole Exp $package org.hibernate.loader.collection;import java.io.Serializable;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.hibernate.FetchMode;import org.hibernate.HibernateException;import org.hibernate.LockMode;import org.hibernate.MappingException;import org.hibernate.engine.SessionFactoryImplementor;import org.hibernate.engine.SessionImplementor;import org.hibernate.loader.OuterJoinLoader;import org.hibernate.loader.OuterJoinableAssociation;import org.hibernate.persister.collection.QueryableCollection;import org.hibernate.sql.JoinFragment;import org.hibernate.sql.Select;import org.hibernate.type.AssociationType;import org.hibernate.type.Type;import org.hibernate.util.CollectionHelper;import org.hibernate.util.StringHelper;/** * Loads a collection of values or a many-to-many association. * <br> * The collection persister must implement <tt>QueryableCOllection<tt>. For * other collections, create a customized subclass of <tt>Loader</tt>. * * @see OneToManyLoader * @author Gavin King */public class CollectionLoader extends OuterJoinLoader implements CollectionInitializer {	private static final Log log = LogFactory.getLog(CollectionLoader.class);	private final QueryableCollection collectionPersister;	public CollectionLoader(			QueryableCollection collectionPersister, 			SessionFactoryImplementor session, 			Map enabledFilters)	throws MappingException {		this(collectionPersister, 1, session, enabledFilters);	}	public CollectionLoader(			QueryableCollection collectionPersister, 			int batchSize, 			SessionFactoryImplementor factory, 			Map enabledFilters)	throws MappingException {		this(collectionPersister, batchSize, null, factory, enabledFilters);	}		public CollectionLoader(			QueryableCollection collectionPersister, 			int batchSize, 			String subquery, 			SessionFactoryImplementor factory, 			Map enabledFilters)	throws MappingException {		super(factory, enabledFilters);		this.collectionPersister = collectionPersister;		String alias = generateRootAlias( collectionPersister.getRole() );		final List associations = walkCollectionTree(collectionPersister, alias);		List allAssociations = new ArrayList();		allAssociations.addAll(associations);		allAssociations.add( new OuterJoinableAssociation( 				collectionPersister.getCollectionType(),				null, 				null, 				alias, 				JoinFragment.LEFT_OUTER_JOIN, 				getFactory(), 				CollectionHelper.EMPTY_MAP 			) );		initPersisters(allAssociations, LockMode.NONE);		initStatementString(alias, associations, batchSize, subquery);		postInstantiate();		log.debug( "Static select for collection " + collectionPersister.getRole() + ": " + getSQLString() );	}	public void initialize(Serializable id, SessionImplementor session)	throws HibernateException {		loadCollection( session, id, getKeyType() );	}	private void initStatementString(		final String alias,		final List associations,		final int batchSize,		final String subquery)	throws MappingException {		final int joins = countEntityPersisters( associations );		final int collectionJoins = countCollectionPersisters( associations ) + 1;		suffixes = generateSuffixes( joins );		collectionSuffixes = generateSuffixes( joins, collectionJoins );		StringBuffer whereString = whereString(alias, collectionPersister.getKeyColumnNames(), batchSize, subquery);		String filter = collectionPersister.filterFragment( alias, getEnabledFilters() );		if ( collectionPersister.isManyToMany() ) {			// from the collection of associations, locate OJA for the			// ManyToOne corresponding to this persister to fully			// define the many-to-many; we need that OJA so that we can			// use its alias here			// TODO : is there a better way here?			Iterator itr = associations.iterator();			AssociationType associationType = ( AssociationType ) collectionPersister.getElementType();			while ( itr.hasNext() ) {				OuterJoinableAssociation oja = ( OuterJoinableAssociation ) itr.next();				if ( oja.getJoinableType() == associationType ) {					// we found it					filter += collectionPersister.getManyToManyFilterFragment( oja.getRHSAlias(), getEnabledFilters() );				}			}		}		whereString.insert( 0, StringHelper.moveAndToBeginning( filter ) );		JoinFragment ojf = mergeOuterJoins(associations);		Select select = new Select( getDialect() )			.setSelectClause(				collectionPersister.selectFragment(alias, collectionSuffixes[0] ) +				selectString(associations)			)			.setFromClause( collectionPersister.getTableName(), alias )			.setWhereClause( whereString.toString()	)			.setOuterJoins(				ojf.toFromFragmentString(),				ojf.toWhereFragmentString()			);		select.setOrderByClause( orderBy(associations, collectionPersister.getSQLOrderByString(alias) ) );		if ( getFactory().getSettings().isCommentsEnabled() ) {			select.setComment( "load collection " + collectionPersister.getRole() );		}		sql = select.toStatementString();	}	/**	 * We can use an inner join for first many-to-many association	 */	protected int getJoinType(			AssociationType type, 			FetchMode config, 			String path, 			Set visitedAssociations,			String lhsTable,			String[] lhsColumns,			boolean nullable,			int currentDepth)	throws MappingException {		int joinType = super.getJoinType(				type, 				config, 				path, 				visitedAssociations, 				lhsTable, 				lhsColumns, 				nullable, 				currentDepth		);		//we can use an inner join for the many-to-many		if ( joinType==JoinFragment.LEFT_OUTER_JOIN && "".equals(path) ) {			joinType=JoinFragment.INNER_JOIN;		}		return joinType;	}		protected Type getKeyType() {		return collectionPersister.getKeyType();	}	public String toString() {		return getClass().getName() + '(' + collectionPersister.getRole() + ')';	}	protected boolean isSubselectLoadingEnabled() {		return hasSubselectLoadableCollections();	}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?