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

📄 joinwalker.java

📁 一个Java持久层类库
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	throws MappingException {		Type[] types = compositeType.getSubtypes();		String[] propertyNames = compositeType.getPropertyNames();		int begin = 0;		for ( int i=0; i <types.length; i++ ) {			int length = types[i].getColumnSpan( getFactory() );			String[] lhsColumns = ArrayHelper.slice(cols, begin, length);			if ( types[i].isAssociationType() ) {				AssociationType associationType = (AssociationType) types[i];				// simple, because we can't have a one-to-one or a collection 				// (or even a property-ref) in a composite-element:				String[] aliasedLhsColumns = StringHelper.qualify(alias, lhsColumns);				String subpath = subPath( path, propertyNames[i] );				final boolean[] propertyNullability = compositeType.getPropertyNullability();				final int joinType = getJoinType(						associationType,						compositeType.getFetchMode(i),						subpath,						persister.getTableName(),						lhsColumns,						propertyNullability==null || propertyNullability[i],						currentDepth, 						compositeType.getCascadeStyle(i)					);				addAssociationToJoinTreeIfNecessary(						associationType,						aliasedLhsColumns,						alias,						subpath,						currentDepth,						joinType					);			}			else if ( types[i].isComponentType() ) {				String subpath = subPath( path, propertyNames[i] );				walkCompositeElementTree(						(AbstractComponentType) types[i],						lhsColumns,						persister,						alias,						subpath,						currentDepth					);			}			begin+=length;		}	}	/**	 * Extend the path by the given property name	 */	private static String subPath(String path, String property) {		if ( path==null || path.length()==0) {			return property;		}		else {			return StringHelper.qualify(path, property);		}	}	/**	 * Get the join type (inner, outer, etc) or -1 if the	 * association should not be joined. Override on	 * subclasses.	 */	protected int getJoinType(			AssociationType type, 			FetchMode config, 			String path, 			String lhsTable,			String[] lhsColumns,			boolean nullable,			int currentDepth, 			CascadeStyle cascadeStyle)	throws MappingException {				if  ( !isJoinedFetchEnabled(type, config, cascadeStyle) ) return -1;				if ( isTooDeep(currentDepth) || ( type.isCollectionType() && isTooManyCollections() ) ) return -1;				final boolean dupe = isDuplicateAssociation(lhsTable,  lhsColumns, type);		if (dupe) return -1;				return getJoinType(nullable, currentDepth);			}		/**	 * Use an inner join if it is a non-null association and this	 * is the "first" join in a series	 */	protected int getJoinType(boolean nullable, int currentDepth) {		//TODO: this is too conservative; if all preceding joins were 		//      also inner joins, we could use an inner join here		return !nullable && currentDepth==0 ? 					JoinFragment.INNER_JOIN : 					JoinFragment.LEFT_OUTER_JOIN;	}	protected boolean isTooDeep(int currentDepth) {		Integer maxFetchDepth = getFactory().getSettings().getMaximumFetchDepth();		return maxFetchDepth!=null && currentDepth >= maxFetchDepth.intValue();	}		protected boolean isTooManyCollections() {		return false;	}		/**	 * Does the mapping, and Hibernate default semantics, specify that	 * this association should be fetched by outer joining	 */	protected boolean isJoinedFetchEnabledInMapping(FetchMode config, AssociationType type) 	throws MappingException {		if ( !type.isEntityType() && !type.isCollectionType() ) {			return false;		}		else {			if (config==FetchMode.JOIN) return true;			if (config==FetchMode.SELECT) return false;			if ( type.isEntityType() ) {				//TODO: look at the owning property and check that it 				//      isn't lazy (by instrumentation)				EntityType entityType =(EntityType) type;				EntityPersister persister = getFactory().getEntityPersister( entityType.getAssociatedEntityName() );				return !persister.hasProxy();			}			else {				return false;			}		}	}	/**	 * Override on subclasses to enable or suppress joining 	 * of certain association types	 */	protected boolean isJoinedFetchEnabled(AssociationType type, FetchMode config, CascadeStyle cascadeStyle) {		return type.isEntityType() && isJoinedFetchEnabledInMapping(config, type) ;	}		protected String generateTableAlias(			final int n,			final String path,			final Joinable joinable	) {		return StringHelper.generateAlias( joinable.getName(), n );	}	protected String generateRootAlias(final String description) {		return StringHelper.generateAlias(description, 0);	}	/**	 * Used to detect circularities in the joined graph, note that 	 * this method is side-effecty	 */	protected boolean isDuplicateAssociation(		final String foreignKeyTable, 		final String[] foreignKeyColumns	) {		AssociationKey associationKey = new AssociationKey(foreignKeyColumns, foreignKeyTable);		return !visitedAssociationKeys.add( associationKey );	}		/**	 * Used to detect circularities in the joined graph, note that 	 * this method is side-effecty	 */	protected boolean isDuplicateAssociation(		final String lhsTable,		final String[] lhsColumnNames,		final AssociationType type	) {		final String foreignKeyTable;		final String[] foreignKeyColumns;		if ( type.getForeignKeyDirection()==ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT ) {			foreignKeyTable = lhsTable;			foreignKeyColumns = lhsColumnNames;		}		else {			foreignKeyTable = type.getAssociatedJoinable( getFactory() ).getTableName();			foreignKeyColumns = JoinHelper.getRHSColumnNames( type, getFactory() );		}		return isDuplicateAssociation(foreignKeyTable, foreignKeyColumns);	}		/**	 * Uniquely identifier a foreign key, so that we don't	 * join it more than once, and create circularities	 */	private static final class AssociationKey {		private String[] columns;		private String table;		private AssociationKey(String[] columns, String table) {			this.columns = columns;			this.table = table;		}		public boolean equals(Object other) {			AssociationKey that = (AssociationKey) other;			return that.table.equals(table) && Arrays.equals(columns, that.columns);		}		public int hashCode() {			return table.hashCode(); //TODO: inefficient		}	}		/**	 * Should we join this association?	 */	protected boolean isJoinable(		final int joinType,		final Set visitedAssociationKeys, 		final String lhsTable,		final String[] lhsColumnNames,		final AssociationType type,		final int depth	) {		if (joinType<0) return false;				if (joinType==JoinFragment.INNER_JOIN) return true;				Integer maxFetchDepth = getFactory().getSettings().getMaximumFetchDepth();		final boolean tooDeep = maxFetchDepth!=null && 			depth >= maxFetchDepth.intValue();				return !tooDeep && !isDuplicateAssociation(lhsTable, lhsColumnNames, type);	}		protected String orderBy(final List associations, final String orderBy) {		return mergeOrderings( orderBy( associations ), orderBy );	}	protected static String mergeOrderings(String ordering1, String ordering2) {		if ( ordering1.length() == 0 ) {			return ordering2;		}		else if ( ordering2.length() == 0 ) {			return ordering1;		}		else {			return ordering1 + ", " + ordering2;		}	}		/**	 * Generate a sequence of <tt>LEFT OUTER JOIN</tt> clauses for the given associations.	 */	protected final JoinFragment mergeOuterJoins(List associations)	throws MappingException {		JoinFragment outerjoin = getDialect().createOuterJoinFragment();		Iterator iter = associations.iterator();		OuterJoinableAssociation last = null;		while ( iter.hasNext() ) {			OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();			if ( last != null && last.isManyToManyWith( oj ) ) {				oj.addManyToManyJoin( outerjoin, ( QueryableCollection ) last.getJoinable() );			}			else {				oj.addJoins(outerjoin);			}			last = oj;		}		last = null;		return outerjoin;	}	/**	 * Count the number of instances of Joinable which are actually	 * also instances of Loadable, or are one-to-many associations	 */	protected static final int countEntityPersisters(List associations)	throws MappingException {		int result = 0;		Iterator iter = associations.iterator();		while ( iter.hasNext() ) {			OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();			if ( oj.getJoinable().consumesEntityAlias() ) {				result++;			}		}		return result;	}		/**	 * Count the number of instances of Joinable which are actually	 * also instances of PersistentCollection which are being fetched	 * by outer join	 */	protected static final int countCollectionPersisters(List associations)	throws MappingException {		int result = 0;		Iterator iter = associations.iterator();		while ( iter.hasNext() ) {			OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();			if ( oj.getJoinType()==JoinFragment.LEFT_OUTER_JOIN && oj.getJoinable().isCollection() ) {				result++;			}		}		return result;	}		/**	 * Get the order by string required for collection fetching	 */	protected static final String orderBy(List associations)	throws MappingException {		StringBuffer buf = new StringBuffer();		Iterator iter = associations.iterator();		OuterJoinableAssociation last = null;		while ( iter.hasNext() ) {			OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();			if ( oj.getJoinType() == JoinFragment.LEFT_OUTER_JOIN ) { // why does this matter?				if ( oj.getJoinable().isCollection() ) {					final QueryableCollection queryableCollection = (QueryableCollection) oj.getJoinable();					if ( queryableCollection.hasOrdering() ) {						final String orderByString = queryableCollection.getSQLOrderByString( oj.getRHSAlias() );						buf.append( orderByString ).append(", ");					}				}				else {					// it might still need to apply a collection ordering based on a					// many-to-many defined order-by...					if ( last != null && last.getJoinable().isCollection() ) {						final QueryableCollection queryableCollection = (QueryableCollection) last.getJoinable();						if ( queryableCollection.isManyToMany() && last.isManyToManyWith( oj ) ) {							if ( queryableCollection.hasManyToManyOrdering() ) {								final String orderByString = queryableCollection.getManyToManyOrderByString( oj.getRHSAlias() );								buf.append( orderByString ).append(", ");							}						}					}				}			}			last = oj;		}		if ( buf.length()>0 ) buf.setLength( buf.length()-2 );		return buf.toString();	}		/**	 * Render the where condition for a (batch) load by identifier / collection key	 */	protected StringBuffer whereString(String alias, String[] columnNames, int batchSize) {		if ( columnNames.length==1 ) {			// if not a composite key, use "foo in (?, ?, ?)" for batching			// if no batch, and not a composite key, use "foo = ?"			InFragment in = new InFragment().setColumn( alias, columnNames[0] );			for ( int i=0; i<batchSize; i++ ) in.addValue("?");			return new StringBuffer( in.toFragmentString() );		}		else {			//a composite key			ConditionFragment byId = new ConditionFragment()					.setTableAlias(alias)					.setCondition( columnNames, "?" );				StringBuffer whereString = new StringBuffer();			if ( batchSize==1 ) {				// if no batch, use "foo = ? and bar = ?"				whereString.append( byId.toFragmentString() );			}			else {				// if a composite key, use "( (foo = ? and bar = ?) or (foo = ? and bar = ?) )" for batching				whereString.append('('); //TODO: unnecessary for databases with ANSI-style joins				DisjunctionFragment df = new DisjunctionFragment();				for ( int i=0; i<batchSize; i++ ) {					df.addCondition(byId);				}				whereString.append( df.toFragmentString() );				whereString.append(')'); //TODO: unnecessary for databases with ANSI-style joins			}			return whereString;		}	}	protected void initPersisters(final List associations, final LockMode lockMode) throws MappingException {				final int joins = countEntityPersisters(associations);		final int collections = countCollectionPersisters(associations);		collectionOwners = collections==0 ? null : new int[collections];		collectionPersisters = collections==0 ? null : new CollectionPersister[collections];		collectionSuffixes = BasicLoader.generateSuffixes( joins + 1, collections );		persisters = new Loadable[joins];		aliases = new String[joins];		owners = new int[joins];		ownerAssociationTypes = new EntityType[joins];		lockModeArray = ArrayHelper.fillArray(lockMode, joins);				int i=0;		int j=0;		Iterator iter = associations.iterator();		while ( iter.hasNext() ) {			final OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();			if ( !oj.isCollection() ) {								persisters[i] = (Loadable) oj.getJoinable();				aliases[i] = oj.getRHSAlias();				owners[i] = oj.getOwner(associations);				ownerAssociationTypes[i] = (EntityType) oj.getJoinableType();				i++;							}			else {								QueryableCollection collPersister = (QueryableCollection) oj.getJoinable();				if ( oj.getJoinType()==JoinFragment.LEFT_OUTER_JOIN ) {					//it must be a collection fetch					collectionPersisters[j] = collPersister;					collectionOwners[j] = oj.getOwner(associations);					j++;				}					if ( collPersister.isOneToMany() ) {					persisters[i] = (Loadable) collPersister.getElementPersister();					aliases[i] = oj.getRHSAlias();					i++;				}			}		}			if ( ArrayHelper.isAllNegative(owners) ) owners = null;		if ( collectionOwners!=null && ArrayHelper.isAllNegative(collectionOwners) ) {			collectionOwners = null;		}	}	/**	 * Generate a select list of columns containing all properties of the entity classes	 */	protected final String selectString(List associations)	throws MappingException {		if ( associations.size()==0 ) {			return "";		}		else {			StringBuffer buf = new StringBuffer( associations.size() * 100 )				.append(", ");			int entityAliasCount=0;			int collectionAliasCount=0;			for ( int i=0; i<associations.size(); i++ ) {				OuterJoinableAssociation join = (OuterJoinableAssociation) associations.get(i);				OuterJoinableAssociation next = (i == associations.size() - 1)				        ? null				        : ( OuterJoinableAssociation ) associations.get( i + 1 );				final Joinable joinable = join.getJoinable();				final String entitySuffix = ( suffixes == null || entityAliasCount >= suffixes.length )				        ? null				        : suffixes[entityAliasCount];				final String collectionSuffix = ( collectionSuffixes == null || collectionAliasCount >= collectionSuffixes.length )				        ? null				        : collectionSuffixes[collectionAliasCount];				final String selectFragment = joinable.selectFragment(						next == null ? null : next.getJoinable(),						next == null ? null : next.getRHSAlias(),						join.getRHSAlias(),						entitySuffix,				        collectionSuffix,						join.getJoinType()==JoinFragment.LEFT_OUTER_JOIN				);				buf.append(selectFragment);				if ( joinable.consumesEntityAlias() ) entityAliasCount++;				if ( joinable.consumesCollectionAlias() && join.getJoinType()==JoinFragment.LEFT_OUTER_JOIN ) collectionAliasCount++;				if (					i<associations.size()-1 &&					selectFragment.trim().length()>0				) {					buf.append(", ");				}			}			return buf.toString();		}	}}

⌨️ 快捷键说明

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