⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 outerjoinloader.java

📁 用Java实现的23个常用设计模式源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
//$Id: OuterJoinLoader.java,v 1.25.2.27 2003/11/15 09:49:06 oneovthafew Exp $package net.sf.hibernate.loader;import java.util.ArrayList;import java.util.Arrays;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import net.sf.hibernate.LockMode;import net.sf.hibernate.MappingException;import net.sf.hibernate.collection.CollectionPersister;import net.sf.hibernate.collection.QueryableCollection;import net.sf.hibernate.dialect.Dialect;import net.sf.hibernate.engine.SessionFactoryImplementor;import net.sf.hibernate.persister.ClassPersister;import net.sf.hibernate.persister.Joinable;import net.sf.hibernate.persister.Loadable;import net.sf.hibernate.sql.Alias;import net.sf.hibernate.sql.ConditionFragment;import net.sf.hibernate.sql.DisjunctionFragment;import net.sf.hibernate.sql.JoinFragment;import net.sf.hibernate.type.AbstractComponentType;import net.sf.hibernate.type.AssociationType;import net.sf.hibernate.type.EntityType;import net.sf.hibernate.type.OneToOneType;import net.sf.hibernate.type.Type;import net.sf.hibernate.util.ArrayHelper;import net.sf.hibernate.util.StringHelper;/** * Implements logic for walking a tree of associated classes and generating an SQL select string * containing all properties of those classes. Tables are joined using an ANSI-style left outer * join. * @author Gavin King, Jon Lipsky */public abstract class OuterJoinLoader extends Loader {		public static final int EAGER = 1;	public static final int AUTO = 0;	public static final int LAZY = -1;		protected Loadable[] classPersisters;	protected LockMode[] lockModeArray;	protected int[] owners;	protected String sql;	protected String[] suffixes;	private Dialect dialect;		public OuterJoinLoader(Dialect dialect) {		this.dialect=dialect;	}		/**	 * Override on subclasses to enable or suppress joining of some associations,	 * especially in the case of dynamic fetch settings	 */	protected boolean isJoinedFetchEnabled(Type type, boolean mappingDefault, String path, String table, String[] foreignKeyColumns) {		return type.isEntityType() && mappingDefault;	}		protected int getJoinType(AssociationType type, int config, String path, String table, String[] foreignKeyColumns, SessionFactoryImplementor factory) 	throws MappingException {		boolean mappingDefault = isJoinedFetchEnabledByDefault(config, type, factory);		return isJoinedFetchEnabled(type, mappingDefault, path, table, foreignKeyColumns) ?			JoinFragment.LEFT_OUTER_JOIN :			-1;	}		public static final class OuterJoinableAssociation {		Joinable joinable;		String[] foreignKeyColumns; // belong to other persister		String subalias;		String[] primaryKeyColumns;		String tableName;		int owner; // the position of the persister we came from in the list		int joinType;		//public String foreignKeyalias;		boolean isOneToOne;	}		/**	 * For an entity class, return a list of associations to be fetched by outerjoin	 */	protected final List walkTree(Loadable persister, String alias, SessionFactoryImplementor factory) throws MappingException {		List associations = new ArrayList();		walkClassTree(persister, alias, associations, new HashSet(), StringHelper.EMPTY_STRING, 0, factory);		return associations;	}		/**	 * For a collection role, return a list of associations to be fetched by outerjoin	 */	protected final List walkCollectionTree(QueryableCollection persister, String alias, SessionFactoryImplementor factory) 	throws MappingException {		return walkCollectionTree(persister, alias, new ArrayList(), new HashSet(), StringHelper.EMPTY_STRING, 0, factory);		//TODO: when this is the entry point, we should use an INNER_JOIN for fetching the many-to-many elements!	}		/**	 * For a collection role, return a list of associations to be fetched by outerjoin	 */	private final List walkCollectionTree(QueryableCollection persister, String alias, List associations, Set visitedPersisters, String path, int currentDepth, SessionFactoryImplementor factory) 	throws MappingException {				if ( persister.isOneToMany() ) {			walkClassTree( persister.getElementPersister(), alias, associations, visitedPersisters, path, currentDepth, factory );		} 		else {			Type type = persister.getElementType();			if ( type.isAssociationType() ) {				// a many-to-many				AssociationType etype = (AssociationType) type;				int joinType = getJoinType( 					etype, persister.enableJoinedFetch(), path, persister.getTableName(), persister.getElementColumnNames(), factory				);				if (joinType>=0) {					String[] columns = StringHelper.qualify( alias, persister.getElementColumnNames() );					walkAssociationTree(						etype, 						columns, 						persister, 						alias, 						associations,						visitedPersisters,						path,						currentDepth,						joinType,						factory					);				}			}			else if ( type.isComponentType() ) {				walkCompositeElementTree( 					(AbstractComponentType) type, 					persister.getElementColumnNames(), 					persister, 					alias, 					associations, 					new HashSet(), 					path,					currentDepth, 					factory				);			}		}							return associations;	}		/**	 * Is this an association that we cannot possibly load by outer	 * join, no matter what the mapping or subclass specifies?	 */	private boolean isJoinedFetchAlwaysDisabled(Loadable persister, AssociationType etype, int propertyNumber) {		//NOTE: workaround for problem with 1-to-1 defined on a subclass "accidently" picking up an object		//TODO: really, this should use the "key" columns of the subclass table, then we don't need this check!		//      (I *think*)		return etype.isEntityType() && 			( (EntityType) etype ).isOneToOne() &&			persister.isDefinedOnSubclass(propertyNumber);	}		private final void walkAssociationTree(		AssociationType etype,  		Loadable persister, 		int propertyNumber,		String alias, 		List associations, 		Set visitedPersisters, 		String path,		int currentDepth,		SessionFactoryImplementor factory) 		throws MappingException {				String[] aliasedForeignKeyColumns = getAliasedForeignKeyColumns( 			persister, alias, etype, persister.toColumns(alias, propertyNumber) 		);		String[] foreignKeyColumns = getForeignKeyColumns( 			persister, etype, persister.getSubclassPropertyColumnNames(propertyNumber)		);		if ( isJoinedFetchAlwaysDisabled(persister, etype, propertyNumber) ) return;					String subpath = subPath( path, persister.getSubclassPropertyName(propertyNumber) );		int joinType = getJoinType( 			etype, persister.enableJoinedFetch(propertyNumber), subpath, persister.getSubclassPropertyTableName(propertyNumber), foreignKeyColumns, factory 		);		if (joinType >= 0 ) walkAssociationTree(			etype, 			aliasedForeignKeyColumns, 			persister, 			alias, 			associations, 			visitedPersisters, 			subpath, 			currentDepth, 			joinType,			factory		);	}		/**	 * For an entity class, add to a list of associations to be fetched by outerjoin	 */	private final void walkClassTree(		final Loadable persister, 		String alias, 		List associations, 		Set visitedPersisters, 		String path,		int currentDepth,		SessionFactoryImplementor factory) throws MappingException {				int n = persister.countSubclassProperties();		for ( int i=0; i<n; i++ ) {			Type type = persister.getSubclassPropertyType(i);			if ( type.isAssociationType() ) {				walkAssociationTree( 					(AssociationType) type, 					persister, 					i,					alias, 					associations, 					visitedPersisters,					path,					currentDepth,					factory				);			}			else if ( type.isComponentType() ) {				walkComponentTree( 					(AbstractComponentType) type, 					i, 					persister.getSubclassPropertyColumnNames(i), 					persister.toColumns(alias, i), 					persister, 					alias, 					associations, 					visitedPersisters, 					subPath( path, persister.getSubclassPropertyName(i) ),					currentDepth,					factory				);			}		}	}		/**	 * For a component, add to a list of associations to be fetched by outerjoin	 */	private void walkComponentTree(		AbstractComponentType componentType, 		int propertyNumber, 		String[] cols, 		String[] aliasedCols, 		Loadable persister, 		String alias, 		List associations, 		Set visitedPersisters, 		String path, 		int currentDepth,		SessionFactoryImplementor factory	) throws MappingException {				Type[] types = componentType.getSubtypes();		String[] propertyNames = ( componentType ).getPropertyNames();		int begin = 0;		for ( int i=0; i <types.length; i++ ) {			int length = types[i].getColumnSpan(factory);			String[] range = ArrayHelper.slice(cols, begin, length);			String[] aliasedRange = ArrayHelper.slice(aliasedCols, begin, length);						if ( types[i].isAssociationType() ) {				AssociationType associationType = (AssociationType) types[i];						if ( isJoinedFetchAlwaysDisabled(persister, associationType, propertyNumber) ) return;								String[] aliasedFkColumns = getAliasedForeignKeyColumns(persister, alias, associationType, aliasedRange);				String[] fkColumns = getForeignKeyColumns(persister, associationType, range);				String subpath = subPath( path, propertyNames[i] );				int joinType = getJoinType( 					associationType, componentType.enableJoinedFetch(i), subpath, persister.getSubclassPropertyTableName(propertyNumber), fkColumns, factory 				);				if (joinType>=0) walkAssociationTree(					associationType, 					aliasedFkColumns, 					persister, 					alias, 					associations, 					visitedPersisters, 					subpath, 					currentDepth,					joinType, 					factory				);			}			else if ( types[i].isComponentType() ) {				String subpath = subPath( path, propertyNames[i] );				walkComponentTree( 					(AbstractComponentType) types[i], 					propertyNumber, 					range, 					aliasedRange, 					persister, 					alias, 					associations, 					visitedPersisters, 					subpath, 					currentDepth,					factory				);			}			begin+=length;		}	}		/**	 * For a composite element, add to a list of associations to be fetched by outerjoin	 */	private void walkCompositeElementTree(		AbstractComponentType compositeType, 		String[] cols, 		QueryableCollection persister, 		String alias, 		List associations, 		Set visitedPersisters, 		String path,		int currentDepth,		SessionFactoryImplementor factory	) throws MappingException {

⌨️ 快捷键说明

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