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

📄 abstractcollectionpersister.java

📁 用Java实现的23个常用设计模式源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
//$Id: AbstractCollectionPersister.java,v 1.1.2.12 2003/11/24 03:50:45 oneovthafew Exp $
package net.sf.hibernate.collection;

import net.sf.hibernate.metadata.CollectionMetadata;
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Iterator;

import net.sf.hibernate.AssertionFailure;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.JDBCException;
import net.sf.hibernate.MappingException;
import net.sf.hibernate.QueryException;
import net.sf.hibernate.cache.CacheConcurrencyStrategy;
import net.sf.hibernate.cache.CacheException;
import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.dialect.Dialect;
import net.sf.hibernate.engine.SessionFactoryImplementor;
import net.sf.hibernate.engine.SessionImplementor;
import net.sf.hibernate.id.IdentifierGenerator;
import net.sf.hibernate.impl.MessageHelper;
import net.sf.hibernate.loader.CollectionInitializer;
import net.sf.hibernate.mapping.Collection;
import net.sf.hibernate.mapping.Column;
import net.sf.hibernate.mapping.IdentifierCollection;
import net.sf.hibernate.mapping.IndexedCollection;
import net.sf.hibernate.mapping.Table;
import net.sf.hibernate.persister.ClassPersister;
import net.sf.hibernate.persister.Loadable;
import net.sf.hibernate.persister.PropertyMapping;
import net.sf.hibernate.sql.Alias;
import net.sf.hibernate.sql.SelectFragment;
import net.sf.hibernate.sql.Template;
import net.sf.hibernate.type.AbstractComponentType;
import net.sf.hibernate.type.EntityType;
import net.sf.hibernate.type.PersistentCollectionType;
import net.sf.hibernate.type.Type;
import net.sf.hibernate.util.StringHelper;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * Base implementation of the <tt>QueryableCollection</tt> interface.
 * @see BasicCollectionPersister
 * @see OneToManyPersister
 * @author Gavin King
 */
public abstract class AbstractCollectionPersister implements CollectionMetadata, QueryableCollection {
	// TODO: encapsulate the protected instance variables!
	//private final String sqlSelectString;
	private final String sqlDeleteString;
	private final String sqlInsertRowString;
	private final String sqlUpdateRowString;
	private final String sqlDeleteRowString;
	private final String sqlOrderByString;
	protected final String sqlWhereString;
	private final String sqlOrderByStringTemplate;
	private final String sqlWhereStringTemplate;
	private final boolean hasOrder;
	protected final boolean hasWhere;
	private final boolean hasOrphanDelete;
	//private final boolean isSet;
	private final Type keyType;
	private final Type indexType;
	protected final Type elementType;
	protected final String[] keyColumnNames;
	protected final String[] indexColumnNames;
	protected final String[] elementColumnNames;
	//private final String[] unquotedIndexColumnNames;
	//private final String[] unquotedElementColumnNames;
	//private final String[] unquotedKeyColumnNames;
	protected final String[] rowSelectColumnNames;
	protected final String[] indexColumnAliases;
	protected final String[] elementColumnAliases;
	protected final String[] keyColumnAliases;
	private final Type rowSelectType;
	private final boolean primitiveArray;
	private final boolean array;
	//protected final boolean isOneToMany;
	protected final String qualifiedTableName;
	protected final boolean hasIndex;
	private final boolean isLazy;
	private final boolean isInverse;
	protected final int batchSize;
	private final Class elementClass;
	private final CacheConcurrencyStrategy cache;
	private final PersistentCollectionType collectionType;
	private final int enableJoinedFetch;
	private final Class ownerClass;
	//private final boolean isSorted;
	private final IdentifierGenerator identifierGenerator;
	private final String unquotedIdentifierColumnName;
	private final Type identifierType;
	protected final boolean hasIdentifier;
	protected final String identifierColumnName;
	private final String identifierColumnAlias;
	private final Dialect dialect;
	private final PropertyMapping elementPropertyMapping;
	protected final Loadable elementPersister;
	
	private final CollectionInitializer initializer;
	
	private final String role;
	//private final SessionFactoryImplementor factory;
	
	private static final Log log = LogFactory.getLog(BasicCollectionPersister.class);
	
	public AbstractCollectionPersister(Collection collection, Configuration cfg, SessionFactoryImplementor factory) 
		throws MappingException, CacheException {
		
		dialect = factory.getDialect();
		collectionType = collection.getCollectionType();
		role = collection.getRole();
		ownerClass = collection.getOwnerClass();
		Alias alias = new Alias("__");
		
		sqlOrderByString = collection.getOrderBy();
		hasOrder = sqlOrderByString!=null;
		sqlOrderByStringTemplate = hasOrder ? Template.renderOrderByStringTemplate(sqlOrderByString, dialect) : null;
		sqlWhereString = collection.getWhere();
		hasWhere = sqlWhereString!=null;
		sqlWhereStringTemplate = hasWhere ? Template.renderWhereStringTemplate(sqlWhereString, dialect) : null;
		
		hasOrphanDelete = collection.hasOrphanDelete();
		
		batchSize = collection.getBatchSize();
		
		cache=collection.getCache();
		
		keyType = collection.getKey().getType();
		Iterator iter = collection.getKey().getColumnIterator();
		int keySpan = collection.getKey().getColumnSpan();
		keyColumnNames = new String[keySpan];
		String[] keyAliases = new String[keySpan];
		int k=0;
		while ( iter.hasNext() ) {
			Column col = ( (Column) iter.next() );
			keyColumnNames[k] = col.getQuotedName(dialect);
			keyAliases[k] = col.getAlias();
			k++;
		}
		keyColumnAliases = alias.toAliasStrings(keyAliases);
		//unquotedKeyColumnNames = StringHelper.unQuote(keyColumnAliases);
		java.util.Set distinctColumns = new HashSet();
		checkColumnDuplication( distinctColumns, collection.getKey().getColumnIterator() );
		
		//isSet = collection.isSet();
		//isSorted = collection.isSorted();
		primitiveArray = collection.isPrimitiveArray();
		array = collection.isArray();
		
		int elementSpan = collection.getElement().getColumnSpan();
		iter = collection.getElement().getColumnIterator();
		Table table = collection.getCollectionTable();
		enableJoinedFetch = collection.getElement().getOuterJoinFetchSetting();
		elementType = collection.getElement().getType();
		
		if ( !collection.isOneToMany() ) checkColumnDuplication( distinctColumns, collection.getElement().getColumnIterator() );
		
		if ( elementType.isEntityType() ) {
			//TODO: what if it is just an ordinary ClassPersister, not Loadable
			//      can the collection fwk even handle that?
			elementPersister = (Loadable) factory.getPersister( ( (EntityType) elementType ).getAssociatedClass() );
		}
		else {
			elementPersister = null;
		}

		qualifiedTableName = table.getQualifiedName( dialect, factory.getDefaultSchema() );
		String[] aliases = new String[elementSpan];
		elementColumnNames = new String[elementSpan];
		int j=0;
		while ( iter.hasNext() ) {
			Column col = (Column) iter.next();
			elementColumnNames[j] = col.getQuotedName(dialect);
			aliases[j] = col.getAlias();
			j++;
		}
		
		elementColumnAliases = alias.toAliasStrings(aliases);
		//unquotedElementColumnNames = StringHelper.unQuote(elementColumnAliases);
		
		Type selectColumns;
		String[] selectType;
		if ( hasIndex = collection.isIndexed() ) {
			IndexedCollection indexedCollection = (IndexedCollection) collection;
			indexType = indexedCollection.getIndex().getType();
			int indexSpan = indexedCollection.getIndex().getColumnSpan();
			iter = indexedCollection.getIndex().getColumnIterator();
			indexColumnNames = new String[indexSpan];
			String[] indexAliases = new String[indexSpan];
			int i=0;
			while ( iter.hasNext() ) {
				Column indexCol = (Column) iter.next();
				indexAliases[i] = indexCol.getAlias();
				indexColumnNames[i] = indexCol.getQuotedName(dialect);
				i++;
			}
			selectType = indexColumnNames;
			selectColumns = indexType;
			indexColumnAliases = alias.toAliasStrings(indexAliases);
			//unquotedIndexColumnNames = StringHelper.unQuote(indexColumnAliases);
			checkColumnDuplication( distinctColumns, indexedCollection.getIndex().getColumnIterator() );
		}
		else {
			indexType = null;
			indexColumnNames = null;
			indexColumnAliases = null;
			selectType = elementColumnNames;
			selectColumns = elementType;
		}
		
		if ( hasIdentifier = collection.isIdentified() ) {
			if ( collection.isOneToMany() ) throw new MappingException("one-to-many collections with identifiers are not supported");
			IdentifierCollection idColl = (IdentifierCollection) collection;
			identifierType = idColl.getIdentifier().getType();
			iter = idColl.getIdentifier().getColumnIterator();
			Column col = (Column) iter.next();
			identifierColumnName = col.getQuotedName(dialect);
			selectType = new String[] { identifierColumnName };
			selectColumns = identifierType;
			identifierColumnAlias = alias.toAliasString( col.getAlias() );
			//unquotedIdentifierColumnName = StringHelper.unQuote(identifierColumnAlias);
			unquotedIdentifierColumnName = identifierColumnAlias;
			identifierGenerator = idColl.getIdentifier().createIdentifierGenerator( factory.getDialect() );
			checkColumnDuplication( distinctColumns, idColl.getIdentifier().getColumnIterator() );
		}
		else {
			identifierType = null;
			identifierColumnName = null;
			identifierColumnAlias = null;
			unquotedIdentifierColumnName = null;
			identifierGenerator = null;
		}
		
		rowSelectColumnNames = selectType;
		rowSelectType = selectColumns;
		
		//sqlSelectString = sqlSelectString();
		sqlDeleteString = generateDeleteString();
		//sqlSelectRowString = sqlSelectRowString();
		sqlInsertRowString = generateInsertRowString();
		sqlUpdateRowString = generateUpdateRowString();
		sqlDeleteRowString = generateDeleteRowString();
		isLazy = collection.isLazy();
		
		isInverse = collection.isInverse();
		
		if ( collection.isArray() ) {
			elementClass = ( (net.sf.hibernate.mapping.Array) collection ).getElementClass();
		}
		else {
			// for non-arrays, we don't need to know the element class
			elementClass = null; //elementType.returnedClass();
		}
		
		initializer = createCollectionInitializer(factory);
		
		if ( elementType.isComponentType() ) {
			elementPropertyMapping = new CompositeElementPropertyMapping( 
				elementColumnNames, (AbstractComponentType) elementType, factory 
			);
		}
		else if ( !elementType.isEntityType() ) {
			elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType);
		}
		else {
			ClassPersister persister = factory.getPersister( ( (EntityType) elementType ).getAssociatedClass() );
			if ( persister instanceof PropertyMapping ) { //not all classpersisters implement PropertyMapping!
				elementPropertyMapping = (PropertyMapping) persister;
			}
			else {
				elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType);
			} 
		}
		
	}
	
	public void initialize(Serializable key, SessionImplementor session) throws HibernateException {
		try {
			initializer.initialize(key, session);
		}
		catch (SQLException sqle) {
			throw new JDBCException(
				"could not initialize collection: " + MessageHelper.infoString(this, key), sqle
			);
		}
	}
	
	protected abstract CollectionInitializer createCollectionInitializer(SessionFactoryImplementor factory) throws MappingException;
	
	public CacheConcurrencyStrategy getCache() {
		return cache;
	}
	
	public boolean hasCache() {
		return cache!=null;
	}
	
	public PersistentCollectionType getCollectionType() {
		return collectionType;
	}
	
	public String getSQLWhereString(String alias) {
		return StringHelper.replace(sqlWhereStringTemplate, Template.TEMPLATE, alias);
	}
	
	public String getSQLOrderByString(String alias) {
		return StringHelper.replace(sqlOrderByStringTemplate, Template.TEMPLATE, alias);
	}
	
	public int enableJoinedFetch() {
		return enableJoinedFetch;
	}
	
	public boolean hasOrdering() {
		return hasOrder;
	}
	
	public boolean hasWhere() {
		return hasWhere; 
	}
	
	protected String getSQLDeleteString() {
		return sqlDeleteString;
	}
	
	protected String getSQLInsertRowString() {
		return sqlInsertRowString;
	}
	
	protected String getSQLUpdateRowString() {
		return sqlUpdateRowString;
	}
	
	protected String getSQLDeleteRowString() {
		return sqlDeleteRowString;
	}
	
	public Type getKeyType() {
		return keyType;
	}
	
	public Type getIndexType() {
		return indexType;
	}
	
	public Type getElementType() {
		return elementType;
	}
	
	/**
	 * Return the element class of an array, or null otherwise
	 */
	public Class getElementClass() { //needed by arrays
		return elementClass;
	}
	
	public Object readElement(ResultSet rs, Object owner, SessionImplementor session) throws HibernateException, SQLException {
		Object element = getElementType().nullSafeGet(rs, elementColumnAliases, session, owner);
		return element;
	}
	public Object readIndex(ResultSet rs, SessionImplementor session) throws HibernateException, SQLException {
		Object index = getIndexType().nullSafeGet(rs, indexColumnAliases, session, null);
		if (index==null) throw new HibernateException("null index column for collection: " + role);
		return index;
	}
	
	public Object readIdentifier(ResultSet rs, SessionImplementor session) throws HibernateException, SQLException {
		Object id = getIdentifierType().nullSafeGet(rs, unquotedIdentifierColumnName, session, null);

⌨️ 快捷键说明

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