📄 abstractqueryimpl.java
字号:
//$Id: AbstractQueryImpl.java 9003 2006-01-10 12:48:09Z steveebersole $
package org.hibernate.impl;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import org.hibernate.CacheMode;
import org.hibernate.FlushMode;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.NonUniqueResultException;
import org.hibernate.PropertyNotFoundException;
import org.hibernate.Query;
import org.hibernate.QueryException;
import org.hibernate.engine.QueryParameters;
import org.hibernate.engine.RowSelection;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.TypedValue;
import org.hibernate.engine.query.ParameterMetadata;
import org.hibernate.hql.classic.ParserHelper;
import org.hibernate.property.Getter;
import org.hibernate.proxy.HibernateProxyHelper;
import org.hibernate.type.SerializableType;
import org.hibernate.type.Type;
import org.hibernate.type.TypeFactory;
import org.hibernate.util.ArrayHelper;
import org.hibernate.util.MarkerObject;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.StringHelper;
/**
* Abstract implementation of the Query interface.
*
* @author Gavin King, Max Andersen
*/
public abstract class AbstractQueryImpl implements Query {
private static final Object UNSET_PARAMETER = new MarkerObject("<unset parameter>");
private static final Object UNSET_TYPE = new MarkerObject("<unset type>");
private final String queryString;
protected final SessionImplementor session;
protected final ParameterMetadata parameterMetadata;
// parameter bind values...
private List values = new ArrayList(4);
private List types = new ArrayList(4);
private Map namedParameters = new HashMap(4);
private Map namedParameterLists = new HashMap(4);
private Object optionalObject;
private Serializable optionalId;
private String optionalEntityName;
private RowSelection selection;
private boolean cacheable;
private String cacheRegion;
private String comment;
private FlushMode flushMode;
private CacheMode cacheMode;
private FlushMode sessionFlushMode;
private CacheMode sessionCacheMode;
private Serializable collectionKey;
private boolean readOnly;
public AbstractQueryImpl(
String queryString,
FlushMode flushMode,
SessionImplementor session,
ParameterMetadata parameterMetadata) {
this.session = session;
this.queryString = queryString;
this.selection = new RowSelection();
this.flushMode = flushMode;
this.cacheMode = null;
this.parameterMetadata = parameterMetadata;
}
public String toString() {
return StringHelper.unqualify( getClass().getName() ) + '(' + queryString + ')';
}
public final String getQueryString() {
return queryString;
}
//TODO: maybe call it getRowSelection() ?
public RowSelection getSelection() {
return selection;
}
public Query setFlushMode(FlushMode flushMode) {
this.flushMode = flushMode;
return this;
}
public Query setCacheMode(CacheMode cacheMode) {
this.cacheMode = cacheMode;
return this;
}
public Query setCacheable(boolean cacheable) {
this.cacheable = cacheable;
return this;
}
public Query setCacheRegion(String cacheRegion) {
if (cacheRegion != null)
this.cacheRegion = cacheRegion.trim();
return this;
}
public Query setComment(String comment) {
this.comment = comment;
return this;
}
public Query setFirstResult(int firstResult) {
selection.setFirstRow( new Integer(firstResult) );
return this;
}
public Query setMaxResults(int maxResults) {
selection.setMaxRows( new Integer(maxResults) );
return this;
}
public Query setTimeout(int timeout) {
selection.setTimeout( new Integer(timeout) );
return this;
}
public Query setFetchSize(int fetchSize) {
selection.setFetchSize( new Integer(fetchSize) );
return this;
}
public Type[] getReturnTypes() throws HibernateException {
return session.getFactory().getReturnTypes( queryString );
}
public String[] getReturnAliases() throws HibernateException {
return session.getFactory().getReturnAliases( queryString );
}
public Query setCollectionKey(Serializable collectionKey) {
this.collectionKey = collectionKey;
return this;
}
public boolean isReadOnly() {
return readOnly;
}
public Query setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
return this;
}
public void setOptionalEntityName(String optionalEntityName) {
this.optionalEntityName = optionalEntityName;
}
public void setOptionalId(Serializable optionalId) {
this.optionalId = optionalId;
}
public void setOptionalObject(Object optionalObject) {
this.optionalObject = optionalObject;
}
SessionImplementor getSession() {
return session;
}
protected abstract Map getLockModes();
// Parameter handling code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/**
* Returns a shallow copy of the named parameter value map.
*
* @return Shallow copy of the named parameter value map
*/
protected Map getNamedParams() {
return new HashMap( namedParameters );
}
/**
* Returns an array representing all named parameter names encountered
* during (intial) parsing of the query.
* <p/>
* Note <i>initial</i> here means different things depending on whether
* this is a native-sql query or an HQL/filter query. For native-sql, a
* precursory inspection of the query string is performed specifically to
* locate defined parameters. For HQL/filter queries, this is the
* information returned from the query-translator. This distinction
* holds true for all parameter metadata exposed here.
*
* @return Array of named parameter names.
* @throws HibernateException
*/
public String[] getNamedParameters() throws HibernateException {
return ArrayHelper.toStringArray( parameterMetadata.getNamedParameterNames() );
}
/**
* Does this query contain named parameters?
*
* @return True if the query was found to contain named parameters; false
* otherwise;
*/
public boolean hasNamedParameters() {
return parameterMetadata.getNamedParameterNames().size() > 0;
}
/**
* Retreive the value map for any named parameter lists (i.e., for
* auto-expansion) bound to this query.
*
* @return The parameter list value map.
*/
protected Map getNamedParameterLists() {
return namedParameterLists;
}
/**
* Retreives the list of parameter values bound to this query for
* ordinal parameters.
*
* @return The ordinal parameter values.
*/
protected List getValues() {
return values;
}
/**
* Retreives the list of parameter {@link Type type}s bound to this query for
* ordinal parameters.
*
* @return The ordinal parameter types.
*/
protected List getTypes() {
return types;
}
/**
* Perform parameter validation. Used prior to executing the encapsulated
* query.
*
* @throws QueryException
*/
protected void verifyParameters() throws QueryException {
verifyParameters(false);
}
/**
* Perform parameter validation. Used prior to executing the encapsulated
* query.
*
* @param reserveFirstParameter if true, the first ? will not be verified since
* its needed for e.g. callable statements returning a out parameter
* @throws HibernateException
*/
protected void verifyParameters(boolean reserveFirstParameter) throws HibernateException {
if ( parameterMetadata.getNamedParameterNames().size() != namedParameters.size() + namedParameterLists.size() ) {
Set missingParams = new HashSet( parameterMetadata.getNamedParameterNames() );
missingParams.removeAll( namedParameterLists.keySet() );
missingParams.removeAll( namedParameters.keySet() );
throw new QueryException( "Not all named parameters have been set: " + missingParams, getQueryString() );
}
int positionalValueSpan = 0;
for ( int i = 0; i < values.size(); i++ ) {
Object object = types.get( i );
if( values.get( i ) == UNSET_PARAMETER || object == UNSET_TYPE ) {
if ( reserveFirstParameter && i==0 ) {
continue;
}
else {
throw new QueryException( "Unset positional parameter at position: " + i, getQueryString() );
}
}
positionalValueSpan += ( (Type) object ).getColumnSpan( session.getFactory() );
}
if ( parameterMetadata.getOrdinalParameterCount() != positionalValueSpan ) {
if ( reserveFirstParameter && parameterMetadata.getOrdinalParameterCount() - 1 != positionalValueSpan ) {
throw new QueryException(
"Expected positional parameter count: " +
(parameterMetadata.getOrdinalParameterCount()-1) +
", actual parameters: " +
values,
getQueryString()
);
}
else if ( !reserveFirstParameter ) {
throw new QueryException(
"Expected positional parameter count: " +
parameterMetadata.getOrdinalParameterCount() +
", actual parameters: " +
values,
getQueryString()
);
}
}
}
public Query setParameter(int position, Object val, Type type) {
if ( parameterMetadata.getOrdinalParameterCount() == 0 ) {
throw new IllegalArgumentException("No positional parameters in query: " + getQueryString() );
}
if ( position < 0 || position > parameterMetadata.getOrdinalParameterCount() - 1 ) {
throw new IllegalArgumentException("Positional parameter does not exist: " + position + " in query: " + getQueryString() );
}
int size = values.size();
if ( position < size ) {
values.set( position, val );
types.set( position, type );
}
else {
// prepend value and type list with null for any positions before the wanted position.
for ( int i = 0; i < position - size; i++ ) {
values.add( UNSET_PARAMETER );
types.add( UNSET_TYPE );
}
values.add( val );
types.add( type );
}
return this;
}
public Query setParameter(String name, Object val, Type type) {
if ( !parameterMetadata.getNamedParameterNames().contains( name ) ) {
throw new IllegalArgumentException("Parameter " + name + " does not exist as a named parameter in [" + getQueryString() + "]");
}
else {
namedParameters.put( name, new TypedValue( type, val, session.getEntityMode() ) );
return this;
}
}
public Query setParameter(int position, Object val) throws HibernateException {
if (val == null) {
setParameter( position, val, Hibernate.SERIALIZABLE );
}
else {
setParameter( position, val, determineType( position, val ) );
}
return this;
}
public Query setParameter(String name, Object val) throws HibernateException {
if (val == null) {
Type type = parameterMetadata.getNamedParameterExpectedType( name );
if ( type == null ) {
type = Hibernate.SERIALIZABLE;
}
setParameter( name, val, type );
}
else {
setParameter( name, val, determineType( name, val ) );
}
return this;
}
protected Type determineType(int paramPosition, Object paramValue) throws HibernateException {
Type type = parameterMetadata.getOrdinalParameterExpectedType( paramPosition + 1 );
if ( type == null ) {
type = guessType( paramValue );
}
return type;
}
protected Type determineType(String paramName, Object paramValue) throws HibernateException {
Type type = parameterMetadata.getNamedParameterExpectedType( paramName );
if ( type == null ) {
type = guessType( paramValue );
}
return type;
}
protected Type determineType(String paramName, Class clazz) throws HibernateException {
Type type = parameterMetadata.getNamedParameterExpectedType( paramName );
if ( type == null ) {
type = guessType( clazz );
}
return type;
}
private Type guessType(Object param) throws HibernateException {
Class clazz = HibernateProxyHelper.getClassWithoutInitializingProxy( param );
return guessType( clazz );
}
private Type guessType(Class clazz) throws HibernateException {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -