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 + -
显示快捷键?