📄 sqlbuilder.java
字号:
/** * adds the Criterion-objects from the criteria to the query * @param criteria the criteria from which the Criterion-objects are taken * @param query the query to which the Criterion-objects should be added * @param params the parameters if a prepared statement should be built, * or null if a normal statement should be built. * @throws TorqueException if the Criterion-objects can not be processed */ private static final void processCriterions( final DB db, final DatabaseMap dbMap, final String dbName, final Criteria crit, final Query query, final List params, final QueryCallback qc) throws TorqueException { UniqueList fromClause = query.getFromClause(); UniqueList whereClause = query.getWhereClause(); for (Iterator it = crit.keySet().iterator(); it.hasNext(); ) { String key = (String) it.next(); Criteria.Criterion criterion = crit.getCriterion(key); Criteria.Criterion[] someCriteria = criterion.getAttachedCriterion(); String table = null; for (int i = 0; i < someCriteria.length; i++) { String tableName = someCriteria[i].getTable(); // add the table to the from clause, if it is not already // contained there // it is important that this piece of code is executed AFTER // the joins are processed addTableToFromClause(getFullTableName(tableName, dbName), crit, query); table = crit.getTableForAlias(tableName); if (table == null) { table = tableName; } boolean ignoreCase = ((crit.isIgnoreCase() || someCriteria[i].isIgnoreCase()) && (dbMap.getTable(table) .getColumn(someCriteria[i].getColumn()) .getType() instanceof String)); someCriteria[i].setIgnoreCase(ignoreCase); } criterion.setDB(db); whereClause.add(qc.process(criterion, params)); } } /** * adds the OrderBy-Columns from the criteria to the query * @param criteria the criteria from which the OrderBy-Columns are taken * @param query the query to which the OrderBy-Columns should be added * @throws TorqueException if the OrderBy-Columns can not be processed */ private static final void processOrderBy( final DB db, final DatabaseMap dbMap, final Criteria crit, final Query query) throws TorqueException { UniqueList orderByClause = query.getOrderByClause(); UniqueList selectClause = query.getSelectClause(); UniqueList orderBy = crit.getOrderByColumns(); if (orderBy != null && orderBy.size() > 0) { // Check for each String/Character column and apply // toUpperCase(). for (int i = 0; i < orderBy.size(); i++) { String orderByColumn = (String) orderBy.get(i); String strippedColumnName = removeSQLFunction(orderByColumn); int dotPos = strippedColumnName.lastIndexOf('.'); if (dotPos == -1) { throwMalformedColumnNameException( "order by", orderByColumn); } String tableName = strippedColumnName.substring(0, dotPos); String table = crit.getTableForAlias(tableName); if (table == null) { table = tableName; } // See if there's a space (between the column list and sort // order in ORDER BY table.column DESC). int spacePos = strippedColumnName.indexOf(' '); String columnName; if (spacePos == -1) { columnName = strippedColumnName.substring(dotPos + 1); } else { columnName = strippedColumnName.substring( dotPos + 1, spacePos); } ColumnMap column = dbMap.getTable(table).getColumn(columnName); // only ignore case in order by for string columns // which do not have a function around them if (column.getType() instanceof String && orderByColumn.indexOf('(') == -1) { // find space pos relative to orderByColumn spacePos = orderByColumn.indexOf(' '); if (spacePos == -1) { orderByClause.add( db.ignoreCaseInOrderBy(orderByColumn)); } else { orderByClause.add( db.ignoreCaseInOrderBy( orderByColumn.substring(0, spacePos)) + orderByColumn.substring(spacePos)); } selectClause.add( db.ignoreCaseInOrderBy(tableName + '.' + columnName)); } else { orderByClause.add(orderByColumn); } } } } /** * adds the GroupBy-Columns from the criteria to the query * @param criteria the criteria from which the GroupBy-Columns are taken * @param query the query to which the GroupBy-Columns should be added * @throws TorqueException if the GroupBy-Columns can not be processed */ private static final void processGroupBy( final Criteria crit, final Query query) throws TorqueException { UniqueList groupByClause = query.getGroupByClause(); UniqueList groupBy = crit.getGroupByColumns(); // need to allow for multiple group bys if (groupBy != null) { for (int i = 0; i < groupBy.size(); i++) { String columnName = (String) groupBy.get(i); String column = (String) crit.getAsColumns().get(columnName); if (column == null) { column = columnName; } if (column.indexOf('.') != -1) { groupByClause.add(column); } else { throwMalformedColumnNameException("group by", column); } } } } /** * adds the Having-Columns from the criteria to the query * @param criteria the criteria from which the Having-Columns are taken * @param query the query to which the Having-Columns should be added * @throws TorqueException if the Having-Columns can not be processed */ private static final void processHaving( final Criteria crit, final Query query) throws TorqueException { Criteria.Criterion having = crit.getHaving(); if (having != null) { //String groupByString = null; query.setHaving(having.toString()); } } /** * Throws a TorqueException with the malformed column name error * message. The error message looks like this:<p> * * <code> * Malformed column name in Criteria [criteriaPhrase]: * '[columnName]' is not of the form 'table.column' * </code> * * @param criteriaPhrase a String, one of "select", "join", or "order by" * @param columnName a String containing the offending column name * @throws TorqueException Any exceptions caught during processing will be * rethrown wrapped into a TorqueException. */ public static final void throwMalformedColumnNameException( final String criteriaPhrase, final String columnName) throws TorqueException { StringBuffer sb = new StringBuffer() .append("Malformed column name in Criteria ") .append(criteriaPhrase) .append(": '") .append(StringUtils.isEmpty(columnName) ? "<empty>" : columnName) .append("' is not of the form 'table.column'"); throw new TorqueException(sb.toString()); } /** * Returns the tablename which can be added to a From Clause. * This takes care of any aliases that might be defined. * For example, if an alias "a" for the table AUTHOR is defined * in the Criteria criteria, getTableNameForFromClause("a", criteria) * returns "AUTHOR a". * @param tableName the name of a table * or the alias for a table * @param criteria a criteria object to resolve a possible alias * @return either the tablename itself if tableOrAliasName is not an alias, * or a String of the form "tableName tableOrAliasName" * if tableOrAliasName is an alias for a table name */ public static final String getTableNameForFromClause( final String tableName, final Criteria criteria) { String shortTableName = getUnqualifiedTableName(tableName); // Most of the time, the alias would be for the short name... String aliasName = criteria.getTableForAlias(shortTableName); if (StringUtils.isEmpty(aliasName)) { // But we should also check the FQN... aliasName = criteria.getTableForAlias(tableName); } if (StringUtils.isNotEmpty(aliasName)) { // If the tables have an alias, add an "<xxx> <yyy> statement" // <xxx> AS <yyy> causes problems on oracle return new StringBuffer( tableName.length() + aliasName.length() + 1) .append(aliasName) .append(" ") .append(tableName) .toString(); } return tableName; } /** * Checks if the Tablename tableName is already contained in a from clause. * If tableName and the tablenames in fromClause are generated by * getTablenameForFromClause(String, Criteria), (which they usually are), * then different aliases for the same table are treated * as different tables: E.g. * fromClauseContainsTableName(fromClause, "table_a a") returns false if * fromClause contains only another alias for table_a , * e.g. "table_a aa" and the unaliased tablename "table_a". * Special case: If tableName is null, true is returned. * @param fromClause a list containing only elements of type. * Query.FromElement * @param tableName the tablename to check * @return if the Tablename tableName is already contained in a from clause. * If tableName is null, true is returned. */ public static final boolean fromClauseContainsTableName( final UniqueList fromClause, final String tableName) { if (tableName == null) { // usually this function is called to see if tableName should be // added to the fromClause. As null should not be added, // true is returned. return true; } for ( Iterator it = fromClause.iterator(); it.hasNext();) { Query.FromElement fromElement = (Query.FromElement) it.next(); if (tableName.equals(fromElement.getTableName())) { return true; } } return false; } /** * adds a table to the from clause of a query, if it is not already * contained there. * @param tableOrAliasName the name of a table * or the alias for a table * @param criteria a criteria object to resolve a possible alias * @param query the query where the the tablename should be added * to the from clause * @return the table in the from clause which represents the * supplied tableOrAliasName */ private static final String addTableToFromClause( final String tableName, final Criteria criteria, Query query) { String tableNameForFromClause = getTableNameForFromClause(tableName, criteria); UniqueList queryFromClause = query.getFromClause(); // it is important that this piece of code is executed AFTER // the joins are processed if (!fromClauseContainsTableName( queryFromClause, tableNameForFromClause)) { Query.FromElement fromElement = new Query.FromElement( tableNameForFromClause, null, null); queryFromClause.add(fromElement); } return tableNameForFromClause; } /** * Inner Interface that defines the Callback method for * the Table creation loop. */ public interface TableCallback { /** * Callback Method for getTableSet() * * @param tables The current table name * @param key The current criterion key. * @param crit The Criteria used in getTableSet() */ void process(Set tables, String key, Criteria crit); } /** * Inner Interface that defines the Callback method for * the buildQuery Criterion evaluation */ public interface QueryCallback { /** * The callback for building a query String * * @param criterion The current criterion * @param params The parameter list passed to buildQueryString() * @return WHERE SQL fragment for this criterion */ String process(Criterion criterion, List params); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -