📄 criteriaquerytranslator.java
字号:
//$Id: CriteriaQueryTranslator.java 9636 2006-03-16 14:14:48Z max.andersen@jboss.com $package org.hibernate.loader.criteria;import java.util.ArrayList;import java.util.Arrays;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.StringTokenizer;import java.util.LinkedHashMap;import org.hibernate.Criteria;import org.hibernate.EntityMode;import org.hibernate.HibernateException;import org.hibernate.LockMode;import org.hibernate.MappingException;import org.hibernate.QueryException;import org.hibernate.hql.ast.util.SessionFactoryHelper;import org.hibernate.criterion.CriteriaQuery;import org.hibernate.criterion.Projection;import org.hibernate.engine.QueryParameters;import org.hibernate.engine.RowSelection;import org.hibernate.engine.SessionFactoryImplementor;import org.hibernate.engine.TypedValue;import org.hibernate.impl.CriteriaImpl;import org.hibernate.persister.entity.Loadable;import org.hibernate.persister.entity.PropertyMapping;import org.hibernate.persister.entity.Queryable;import org.hibernate.type.AssociationType;import org.hibernate.type.Type;import org.hibernate.type.NullableType;import org.hibernate.util.ArrayHelper;import org.hibernate.util.StringHelper;/** * @author Gavin King */public class CriteriaQueryTranslator implements CriteriaQuery { public static final String ROOT_SQL_ALIAS = Criteria.ROOT_ALIAS + '_'; private CriteriaQuery outerQueryTranslator; private final CriteriaImpl rootCriteria; private final String rootEntityName; private final String rootSQLAlias; private int aliasCount = 0; private final Map criteriaEntityNames = new LinkedHashMap(); private final Map criteriaSQLAliasMap = new HashMap(); private final Map aliasCriteriaMap = new HashMap(); private final Map associationPathCriteriaMap = new LinkedHashMap(); private final Map associationPathJoinTypesMap = new LinkedHashMap(); private final SessionFactoryImplementor sessionFactory; public CriteriaQueryTranslator( final SessionFactoryImplementor factory, final CriteriaImpl criteria, final String rootEntityName, final String rootSQLAlias, CriteriaQuery outerQuery) throws HibernateException { this( factory, criteria, rootEntityName, rootSQLAlias ); outerQueryTranslator = outerQuery; } public CriteriaQueryTranslator( final SessionFactoryImplementor factory, final CriteriaImpl criteria, final String rootEntityName, final String rootSQLAlias) throws HibernateException { this.rootCriteria = criteria; this.rootEntityName = rootEntityName; this.sessionFactory = factory; this.rootSQLAlias = rootSQLAlias; createAliasCriteriaMap(); createAssociationPathCriteriaMap(); createCriteriaEntityNameMap(); createCriteriaSQLAliasMap(); } public String generateSQLAlias() { return StringHelper.generateAlias( Criteria.ROOT_ALIAS, aliasCount ) + '_'; } public String getRootSQLALias() { return rootSQLAlias; } private Criteria getAliasedCriteria(String alias) { return ( Criteria ) aliasCriteriaMap.get( alias ); } public boolean isJoin(String path) { return associationPathCriteriaMap.containsKey( path ); } public int getJoinType(String path) { Integer result = ( Integer ) associationPathJoinTypesMap.get( path ); return ( result == null ? Criteria.INNER_JOIN : result.intValue() ); } public Criteria getCriteria(String path) { return ( Criteria ) associationPathCriteriaMap.get( path ); } public Set getQuerySpaces() { Set result = new HashSet(); Iterator iter = criteriaEntityNames.values().iterator(); while ( iter.hasNext() ) { String entityName = ( String ) iter.next(); result.addAll( Arrays.asList( getFactory().getEntityPersister( entityName ).getQuerySpaces() ) ); } return result; } private void createAliasCriteriaMap() { aliasCriteriaMap.put( rootCriteria.getAlias(), rootCriteria ); Iterator iter = rootCriteria.iterateSubcriteria(); while ( iter.hasNext() ) { Criteria subcriteria = ( Criteria ) iter.next(); if ( subcriteria.getAlias() != null ) { Object old = aliasCriteriaMap.put( subcriteria.getAlias(), subcriteria ); if ( old != null ) { throw new QueryException( "duplicate alias: " + subcriteria.getAlias() ); } } } } private void createAssociationPathCriteriaMap() { Iterator iter = rootCriteria.iterateSubcriteria(); while ( iter.hasNext() ) { CriteriaImpl.Subcriteria crit = ( CriteriaImpl.Subcriteria ) iter.next(); String wholeAssociationPath = getWholeAssociationPath( crit ); Object old = associationPathCriteriaMap.put( wholeAssociationPath, crit ); if ( old != null ) { throw new QueryException( "duplicate association path: " + wholeAssociationPath ); } int joinType = crit.getJoinType(); old = associationPathJoinTypesMap.put( wholeAssociationPath, new Integer( joinType ) ); if ( old != null ) { // TODO : not so sure this is needed... throw new QueryException( "duplicate association path: " + wholeAssociationPath ); } } } private String getWholeAssociationPath(CriteriaImpl.Subcriteria subcriteria) { String path = subcriteria.getPath(); // some messy, complex stuff here, since createCriteria() can take an // aliased path, or a path rooted at the creating criteria instance Criteria parent = null; if ( path.indexOf( '.' ) > 0 ) { // if it is a compound path String testAlias = StringHelper.root( path ); if ( !testAlias.equals( subcriteria.getAlias() ) ) { // and the qualifier is not the alias of this criteria // -> check to see if we belong to some criteria other // than the one that created us parent = ( Criteria ) aliasCriteriaMap.get( testAlias ); } } if ( parent == null ) { // otherwise assume the parent is the the criteria that created us parent = subcriteria.getParent(); } else { path = StringHelper.unroot( path ); } if ( parent.equals( rootCriteria ) ) { // if its the root criteria, we are done return path; } else { // otherwise, recurse return getWholeAssociationPath( ( CriteriaImpl.Subcriteria ) parent ) + '.' + path; } } private void createCriteriaEntityNameMap() { criteriaEntityNames.put( rootCriteria, rootEntityName ); Iterator iter = associationPathCriteriaMap.entrySet().iterator(); while ( iter.hasNext() ) { Map.Entry me = ( Map.Entry ) iter.next(); criteriaEntityNames.put( me.getValue(), //the criteria instance getPathEntityName( ( String ) me.getKey() ) ); } } private String getPathEntityName(String path) { Queryable persister = ( Queryable ) sessionFactory.getEntityPersister( rootEntityName ); StringTokenizer tokens = new StringTokenizer( path, "." ); String componentPath = ""; while ( tokens.hasMoreTokens() ) { componentPath += tokens.nextToken(); Type type = persister.toType( componentPath ); if ( type.isAssociationType() ) { AssociationType atype = ( AssociationType ) type; persister = ( Queryable ) sessionFactory.getEntityPersister( atype.getAssociatedEntityName( sessionFactory ) ); componentPath = ""; } else if ( type.isComponentType() ) { componentPath += '.'; } else { throw new QueryException( "not an association: " + componentPath ); } } return persister.getEntityName(); } public int getSQLAliasCount() { return criteriaSQLAliasMap.size(); } private void createCriteriaSQLAliasMap() { int i = 0; Iterator criteriaIterator = criteriaEntityNames.entrySet().iterator(); while ( criteriaIterator.hasNext() ) { Map.Entry me = ( Map.Entry ) criteriaIterator.next(); Criteria crit = ( Criteria ) me.getKey(); String alias = crit.getAlias(); if ( alias == null ) { alias = ( String ) me.getValue(); // the entity name } criteriaSQLAliasMap.put( crit, StringHelper.generateAlias( alias, i++ ) ); } criteriaSQLAliasMap.put( rootCriteria, rootSQLAlias ); } public CriteriaImpl getRootCriteria() { return rootCriteria; } public QueryParameters getQueryParameters() { List values = new ArrayList(); List types = new ArrayList(); Iterator iter = rootCriteria.iterateExpressionEntries(); while ( iter.hasNext() ) { CriteriaImpl.CriterionEntry ce = ( CriteriaImpl.CriterionEntry ) iter.next(); TypedValue[] tv = ce.getCriterion().getTypedValues( ce.getCriteria(), this ); for ( int i = 0; i < tv.length; i++ ) { values.add( tv[i].getValue() ); types.add( tv[i].getType() ); } } Object[] valueArray = values.toArray(); Type[] typeArray = ArrayHelper.toTypeArray( types ); RowSelection selection = new RowSelection(); selection.setFirstRow( rootCriteria.getFirstResult() ); selection.setMaxRows( rootCriteria.getMaxResults() ); selection.setTimeout( rootCriteria.getTimeout() ); selection.setFetchSize( rootCriteria.getFetchSize() ); Map lockModes = new HashMap(); iter = rootCriteria.getLockModes().entrySet().iterator(); while ( iter.hasNext() ) { Map.Entry me = ( Map.Entry ) iter.next(); final Criteria subcriteria = getAliasedCriteria( ( String ) me.getKey() ); lockModes.put( getSQLAlias( subcriteria ), me.getValue() ); } iter = rootCriteria.iterateSubcriteria(); while ( iter.hasNext() ) { CriteriaImpl.Subcriteria subcriteria = ( CriteriaImpl.Subcriteria ) iter.next(); LockMode lm = subcriteria.getLockMode(); if ( lm != null ) { lockModes.put( getSQLAlias( subcriteria ), lm ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -