📄 querytranslator.java
字号:
void setCollectionToFetch(String role, String name, String ownerName, String entityName) throws QueryException { fetchName = name; collectionPersister = getCollectionPersister(role); collectionOwnerName = ownerName; if ( collectionPersister.getElementType().isEntityType() ) addEntityToFetch(entityName); } protected String[] getSuffixes() { return suffixes; } /** * Used for collection filters */ protected void addFromAssociation(final String elementName, final String collectionRole) throws QueryException { //q.addCollection(collectionName, collectionRole); Type collectionElementType = getCollectionPersister(collectionRole).getElementType(); if ( !collectionElementType.isEntityType() ) throw new QueryException( "collection of values in filter: " + elementName ); QueryableCollection persister = getCollectionPersister(collectionRole); String[] keyColumnNames = persister.getKeyColumnNames(); //if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: " + collectionRole); String collectionName; JoinFragment join = createJoinFragment(false); collectionName = persister.isOneToMany() ? elementName : createNameForCollection(collectionRole); join.addCrossJoin( persister.getTableName(), collectionName ); if ( !persister.isOneToMany() ) { //many-to-many addCollection(collectionName, collectionRole); Queryable p = (Queryable) persister.getElementPersister(); String[] idColumnNames = p.getIdentifierColumnNames(); String[] eltColumnNames = persister.getElementColumnNames(); join.addJoin( p.getTableName(), elementName, StringHelper.qualify(collectionName, eltColumnNames), idColumnNames, JoinFragment.INNER_JOIN ); } join.addCondition(collectionName, keyColumnNames, " = ?"); if ( persister.hasWhere() ) join.addCondition( persister.getSQLWhereString(collectionName) ); EntityType elemType = (EntityType) collectionElementType; addFrom(elementName, elemType.getAssociatedClass(), join); } private final Map pathAliases = new HashMap(); private final Map pathJoins = new HashMap(); String getPathAlias(String path) { return (String) pathAliases.get(path); } JoinFragment getPathJoin(String path) { return (JoinFragment) pathJoins.get(path); } void addPathAliasAndJoin(String path, String alias, JoinFragment join) { pathAliases.put(path, alias); pathJoins.put( path, join.copy() ); } 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; } } public List list(SessionImplementor session, QueryParameters queryParameters) throws HibernateException, SQLException { logQuery(queryString, sqlString); return list(session, queryParameters, getQuerySpaces(), actualReturnTypes); } /** * Return the query results as an iterator */ public Iterator iterate(QueryParameters queryParameters, SessionImplementor session) throws HibernateException, SQLException { logQuery(queryString, sqlString); PreparedStatement st = prepareQueryStatement( applyLocks( getSQLString(), queryParameters.getLockModes(), session.getFactory().getDialect() ), queryParameters, false, session ); ResultSet rs = getResultSet(st, queryParameters.getRowSelection(), session); return new IteratorImpl( rs, st, session, returnTypes, getScalarColumnNames() ); } /** * Return the query results, as an instance of <tt>ScrollableResults</tt> */ public ScrollableResults scroll(QueryParameters queryParameters, SessionImplementor session) throws HibernateException, SQLException { logQuery(queryString, sqlString); PreparedStatement st = prepareQueryStatement( applyLocks( getSQLString(), queryParameters.getLockModes(), session.getFactory().getDialect() ), queryParameters, true, session ); ResultSet rs = getResultSet(st, queryParameters.getRowSelection(), session); return new ScrollableResultsImpl( rs, st, session, returnTypes, getScalarColumnNames() ); } /** * Handle Hibernate "implicit" polymorphism, by translating the query string into * several "concrete" queries against mapped classes. */ public static String[] concreteQueries(String query, SessionFactoryImplementor factory) { //scan the query string for class names appearing in the from clause and replace //with all persistent implementors of the class/interface, returning multiple //query strings (make sure we don't pick up a class in the select clause!) //TODO: this is one of the ugliest and most fragile pieces of code in Hibernate.... String[] tokens = StringHelper.split( ParserHelper.WHITESPACE + "(),", query, true ); if (tokens.length==0) return new String[] { query }; // just especially for the trivial collection filter ArrayList placeholders = new ArrayList(); ArrayList replacements = new ArrayList(); StringBuffer templateQuery = new StringBuffer(40); int count=0; String last = null; int nextIndex = 0; String next = null; templateQuery.append( tokens[0] ); for ( int i=1; i<tokens.length; i++ ) { //update last non-whitespace token, if necessary if ( !ParserHelper.isWhitespace( tokens[i-1] ) ) last = tokens[i-1].toLowerCase(); String token = tokens[i]; if ( !ParserHelper.isWhitespace(token) || last==null ) { //scan for next non-whitespace token if (nextIndex<=i) { for ( nextIndex=i+1; nextIndex<tokens.length; nextIndex++ ) { next = tokens[nextIndex].toLowerCase(); if ( !ParserHelper.isWhitespace(next) ) break; } } if ( Character.isJavaIdentifierStart( token.charAt(0) ) && ( ( BEFORE_CLASS_TOKENS.contains(last) && !NOT_AFTER_CLASS_TOKENS.contains(next) ) || "class".equals(last) ) ){ Class clazz= getImportedClass(token, factory); if (clazz!=null) { String[] implementors = factory.getImplementors(clazz); String placeholder = "$clazz" + count++ + "$"; if ( implementors!=null ) { placeholders.add(placeholder); replacements.add(implementors); } token = placeholder; // Note this!! } } } templateQuery.append(token); } String[] results = StringHelper.multiply( templateQuery.toString(), placeholders.iterator(), replacements.iterator() ); if (results.length==0) log.warn("no persistent classes found for query class: " + query); return results; } private static final Set BEFORE_CLASS_TOKENS = new HashSet(); private static final Set NOT_AFTER_CLASS_TOKENS = new HashSet(); static { BEFORE_CLASS_TOKENS.add("from"); //beforeClassTokens.add("new"); DEFINITELY DON'T HAVE THIS!! BEFORE_CLASS_TOKENS.add(","); NOT_AFTER_CLASS_TOKENS.add("in"); //notAfterClassTokens.add(","); NOT_AFTER_CLASS_TOKENS.add("from"); NOT_AFTER_CLASS_TOKENS.add(")"); } Class getImportedClass(String name) { return getImportedClass(name, factory); } private static Class getImportedClass(String name, SessionFactoryImplementor factory) { try { return ReflectHelper.classForName( factory.getImportedClassName(name) ); } catch (Throwable e) { return null; } } private static String[][] generateColumnNames(Type[] types, SessionFactoryImplementor f) throws MappingException { String[][] columnNames = new String[types.length][]; for (int i=0; i<types.length; i++) { int span = types[i].getColumnSpan(f); columnNames[i] = new String[span]; for ( int j=0; j<span; j++ ) { columnNames[i][j] = scalarName(i, j); } } return columnNames; } protected Object getResultColumnOrRow(Object[] row, ResultSet rs, SessionImplementor session) throws SQLException, HibernateException { row = toResultRow(row); if (hasScalars) { String[][] scalarColumns = getScalarColumnNames(); int queryCols = returnTypes.length; if ( holderClass==null && queryCols==1 ) { return returnTypes[0].nullSafeGet( rs, scalarColumns[0], session, null ); } else { row = new Object[queryCols]; for ( int i=0; i<queryCols; i++ ) row[i] = returnTypes[i].nullSafeGet( rs, scalarColumns[i], session, null ); return row; } } else if (holderClass==null) { return row.length==1 ? row[0] : row; } else { return row; } } protected List getResultList(List results) throws QueryException { if (holderClass!=null) { for (int i=0; i<results.size(); i++) { Object[] row = (Object[]) results.get(i); try { results.set( i, holderConstructor.newInstance(row) ); } catch (Exception e) { throw new QueryException("could not instantiate: " + holderClass, e); } } } return results; } private Object[] toResultRow(Object[] row) { if (selectLength==row.length) { return row; } else { Object[] result = new Object[selectLength]; int j=0; for (int i=0; i<row.length; i++) { if ( includeInSelect[i] ) result[j++] = row[i]; } return result; } } QueryJoinFragment createJoinFragment(boolean useThetaStyleInnerJoins) { return new QueryJoinFragment( factory.getDialect(), useThetaStyleInnerJoins ); } void setHolderClass(Class clazz) { holderClass = clazz; } protected LockMode[] getLockModes(Map lockModes) { // unfortunately this stuff can't be cached because // it is per-invocation, not constant for the // QueryTranslator instance HashMap nameLockModes = new HashMap(); if (lockModes!=null) { Iterator iter = lockModes.entrySet().iterator(); while ( iter.hasNext() ) { Map.Entry me = (Map.Entry) iter.next(); nameLockModes.put( getAliasName( (String) me.getKey() ), me.getValue() ); } } LockMode[] lockModeArray = new LockMode[names.length]; for ( int i=0; i<names.length; i++ ) { LockMode lm = (LockMode) nameLockModes.get( names[i] ); if (lm==null) lm = LockMode.NONE; lockModeArray[i] = lm; } return lockModeArray; } protected String applyLocks(String sql, Map lockModes, Dialect dialect) throws QueryException { // can't cache this stuff either (per-invocation) if ( lockModes==null || lockModes.size()==0 ) { return sql; } else { Map aliasedLockModes = new HashMap(); Iterator iter = lockModes.entrySet().iterator(); while ( iter.hasNext() ) { Map.Entry me = (Map.Entry) iter.next(); aliasedLockModes.put( getAliasName( (String) me.getKey() ), me.getValue() ); } return sql + new ForUpdateFragment(aliasedLockModes).toFragmentString(dialect); } } protected boolean upgradeLocks() { return true; } protected int getCollectionOwner() { return collectionOwnerColumn; } protected void setFactory(SessionFactoryImplementor factory) { this.factory = factory; } protected SessionFactoryImplementor getFactory() { return factory; } protected boolean isCompiled() { return compiled; } public String toString() { return queryString; } protected int[] getOwners() { return owners; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -