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

📄 sqlloader.java

📁 人力资源管理系统 系统把几乎所有与人力资源相关的数据统一管理
💻 JAVA
字号:
//$Id: SQLLoader.java,v 1.1.2.18 2003/12/13 12:25:12 oneovthafew Exp $package net.sf.hibernate.loader;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.ArrayList;import java.util.Collection;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 net.sf.hibernate.HibernateException;import net.sf.hibernate.LockMode;import net.sf.hibernate.QueryException;import net.sf.hibernate.engine.QueryParameters;import net.sf.hibernate.engine.SessionFactoryImplementor;import net.sf.hibernate.engine.SessionImplementor;import net.sf.hibernate.engine.TypedValue;import net.sf.hibernate.hql.ParserHelper;import net.sf.hibernate.persister.Loadable;import net.sf.hibernate.persister.SQLLoadable;import net.sf.hibernate.type.Type;import net.sf.hibernate.util.ArrayHelper;import net.sf.hibernate.util.StringHelper;/** * A loader that uses a native SQL query string provided by the user * @see net.sf.hibernate.persister.SQLLoadable * @author Max Andersen */public class SQLLoader extends OuterJoinLoader {	private int parameterCount = 0;	private final Map namedParameters = new HashMap();	private final String sqlQuery;	private final Map alias2Persister;	private final String[] aliases;	private Set querySpaces = new HashSet();	private Type[] resultTypes;		public Set getQuerySpaces() {		return querySpaces;	}	public SQLLoader(		final String[] aliases, 		final SQLLoadable[] persisters, 		final SessionFactoryImplementor factory, 		final String sqlQuery, 		final Collection additionalQuerySpaces) 	throws HibernateException {		super( factory.getDialect() );		this.sqlQuery = sqlQuery;		this.aliases = aliases;		alias2Persister = new HashMap(persisters.length);		List resultTypeList = new ArrayList();		for (int i = 0; i < persisters.length; i++) {			SQLLoadable persister = persisters[i];			alias2Persister.put( aliases[i], persister );			ArrayHelper.addAll( querySpaces, persister.getPropertySpaces() ); //TODO: Does not consider any other tables referenced in the query			resultTypeList.add( persister.getType() );		}		if (additionalQuerySpaces!=null) querySpaces.addAll(additionalQuerySpaces);		resultTypes = (Type[]) resultTypeList.toArray(ArrayHelper.EMPTY_TYPE_ARRAY);		renderStatement(persisters);		postInstantiate();	}	private void renderStatement(Loadable[] persisters) throws QueryException {		int loadables = persisters.length;		// is called persisters in QueryTranslator, but classPersisters in OuterJoinLoader..go figure ;)		classPersisters = persisters;		suffixes = generateSuffixes(loadables);		lockModeArray = createLockModeArray(loadables, LockMode.NONE);		sql = substituteBrackets();		sql = substituteParams();	}	public List list(SessionImplementor session, QueryParameters queryParameters)	throws HibernateException, SQLException {		return list(session, queryParameters, querySpaces, resultTypes);	}	protected Object getResultColumnOrRow(Object[] row, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException {		if (classPersisters.length == 1) {			return row[row.length - 1];		}		else {			return row;		}	}	// Inspired by the parsing done in TJDO	// TODO: should "record" how many properties we have reffered to - and if we don't get'em'all we throw an exception! Way better than trial and error ;)	public String substituteBrackets() throws QueryException {		String sqlString = sqlQuery;		StringBuffer result = new StringBuffer();		int left, right;		// replace {....} with corresponding column aliases		for (int curr = 0; curr < sqlString.length(); curr = right + 1) {			if ( (left = sqlString.indexOf('{', curr) ) < 0) {				result.append( sqlString.substring(curr) );				break;			}			result.append( sqlString.substring(curr, left ) );			if ( (right = sqlString.indexOf('}', left + 1) ) < 0)				throw new QueryException("Unmatched braces for alias path", sqlString);			String aliasPath = sqlString.substring(left + 1, right);			int firstDot = aliasPath.lastIndexOf('.');			String aliasName = firstDot == -1 ? aliasPath : aliasPath.substring(0, firstDot);			SQLLoadable currentPersister = getPersisterByResultAlias(aliasName);			if (currentPersister == null) throw new QueryException(				"Alias [" + aliasName + "] does not correspond to any of the supplied return aliases = {" +				ArrayHelper.asString(aliases) + "}", sqlQuery			);			int currentPersisterIndex = getPersisterIndex(currentPersister);			if (firstDot == -1) {				// TODO: should this one also be aliased/qouted instead of just directly inserted ?				result.append(aliasPath);			}			else {				if ( !aliasName.equals( aliases[currentPersisterIndex] ) ) throw new QueryException(					"Alias [" + aliasName + "] does not correspond to return alias " +					aliases[currentPersisterIndex], sqlQuery				);				String propertyName = aliasPath.substring(firstDot + 1);				if ( "*".equals(propertyName) ) {					result.append( currentPersister.selectFragment(aliasName, suffixes[currentPersisterIndex]) );				}				else {					// here it would be nice just to be able to do;					//result.append( getAliasFor(currentPersister, propertyName) );					// but that requires more exposure of the internal maps of the persister...					// but it should be possible as propertyname should be unique for all persisters					String[] columnAliases;					/*if ( AbstractEntityPersister.ENTITY_CLASS.equals(propertyName) ) {						columnAliases = new String[1];						columnAliases[0] = currentPersister.getDiscriminatorAlias(suffixes[currentPersisterIndex]);					}					else {*/						columnAliases = currentPersister.getSubclassPropertyColumnAliases(propertyName, suffixes[currentPersisterIndex]);					//}					if (columnAliases == null || columnAliases.length == 0) {						throw new QueryException("No column name found for property [" + propertyName + "]", sqlQuery);					}					if (columnAliases.length != 1) {						throw new QueryException("SQL queries only support properties mapped to a single column. Property [" + propertyName + "] is mapped to " + columnAliases.length + " columns.", sqlQuery);					}					// here we need to find the field of the aliasName					// Find by alias first					// Find by class second ?					//result.append("$" + aliasName + "/" + propertyName + "$");					result.append(columnAliases[0]);				}			}		}		// Possibly handle :something parameters for the query ?		return result.toString();	}	private String substituteParams() {		String sqlString = sql;		StringBuffer result = new StringBuffer( sql.length() ); // can be shorter, but definitly not longer than sql.length		int left, right;		//	replace :... with ? and record the parameter. Naively just replaces ALL occurences of :... - including whatever is BEFORE FROM..		// do not "fast-forward to the first or last FROM as "weird" sql might have parameters in places we do not know of, right ? ;)		for (int curr = 0; curr < sqlString.length(); curr = right + 1) {			if ( (left = sqlString.indexOf(ParserHelper.HQL_VARIABLE_PREFIX, curr) ) < 0) {				result.append( sqlString.substring(curr) );				break;			}			result.append( sqlString.substring(curr, left) );			// Find first place of a HQL_SEPERATOR char			right = StringHelper.firstIndexOfChar(sqlString, ParserHelper.HQL_SEPARATORS, left + 1);							// did we find a HQL_SEPERATOR ?			boolean foundSeperator = right > 0;			int chopLocation = -1;			if (right < 0) {				chopLocation = sqlString.length();			} 			else {				chopLocation = right;			}							String param = sqlString.substring(left+1, chopLocation);			addNamedParameter(param);			result.append("?");			if (foundSeperator) {				result.append( sqlString.charAt(right) );			} 			else {				break;			}		}		return result.toString();	}	private int getPersisterIndex(Loadable currentPersister) {		for (int i = 0; i < classPersisters.length; i++) {			if (currentPersister == classPersisters[i])				return i;		}		return -1;	}	private SQLLoadable getPersisterByResultAlias(String aliasName) {		return (SQLLoadable) alias2Persister.get(aliasName);	}	// NAMED PARAMETERS SUPPORT, copy/pasted from QueryTranslator!	void addNamedParameter(String name) {		Integer loc = new Integer(parameterCount++);		Object o = namedParameters.get(name);		if (o == null) {			namedParameters.put(name, loc);		}		else if (o instanceof Integer) {			ArrayList list = new ArrayList(4);			list.add(o);			list.add(loc);			namedParameters.put(name, list);		}		else {			( (List) o ).add(loc);		}	}	protected int[] getNamedParameterLocs(String name) throws QueryException {		Object o = namedParameters.get(name);		if (o == null) {			QueryException qe = new QueryException("Named parameter does not appear in Query: " + name, sqlQuery);			throw qe;		}		if (o instanceof Integer) {			return new int[] { ( (Integer) o ).intValue() };		}		else {			return ArrayHelper.toIntArray( (List) o );		}	}	protected int bindNamedParameters(PreparedStatement ps, Map namedParams, int start, SessionImplementor session) 	throws SQLException, HibernateException {		if (namedParams != null) {			// assumes that types are all of span 1			Iterator iter = namedParams.entrySet().iterator();			int result = 0;			while ( iter.hasNext() ) {				Map.Entry e = (Map.Entry) iter.next();				String name = (String) e.getKey();				TypedValue typedval = (TypedValue) e.getValue();				int[] locs = getNamedParameterLocs(name);				for (int i = 0; i < locs.length; i++) {					typedval.getType().nullSafeSet(ps, typedval.getValue(), locs[i] + start, session);				}				result += locs.length;			}			return result;		}		else {			return 0;		}	}}

⌨️ 快捷键说明

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