/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.loader.plan.exec.query.internal;

import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.dialect.Dialect;
import org.hibernate.internal.util.StringHelper;

Largely a copy of the Select class, but changed up slightly to better meet needs of building a SQL SELECT statement from a LoadPlan
Author:Steve Ebersole, Gavin King
/** * Largely a copy of the {@link org.hibernate.sql.Select} class, but changed up slightly to better meet needs * of building a SQL SELECT statement from a LoadPlan * * @author Steve Ebersole * @author Gavin King */
public class SelectStatementBuilder { public final Dialect dialect; private StringBuilder selectClause = new StringBuilder(); private StringBuilder fromClause = new StringBuilder(); // private StringBuilder outerJoinsAfterFrom; private String outerJoinsAfterFrom; private StringBuilder whereClause; // private StringBuilder outerJoinsAfterWhere; private String outerJoinsAfterWhere; private StringBuilder orderByClause; private String comment; private LockOptions lockOptions = new LockOptions(); private int guesstimatedBufferSize = 20;
Constructs a select statement builder object.
Params:
  • dialect – The dialect.
/** * Constructs a select statement builder object. * * @param dialect The dialect. */
public SelectStatementBuilder(Dialect dialect) { this.dialect = dialect; }
Appends a select clause fragment
Params:
  • selection – The selection fragment
/** * Appends a select clause fragment * * @param selection The selection fragment */
public void appendSelectClauseFragment(String selection) { if ( this.selectClause.length() > 0 ) { this.selectClause.append( ", " ); this.guesstimatedBufferSize += 2; } this.selectClause.append( selection ); this.guesstimatedBufferSize += selection.length(); }
Appends the from clause fragment.
Params:
  • fragment – The from cause fragment.
/** * Appends the from clause fragment. * * @param fragment The from cause fragment. */
public void appendFromClauseFragment(String fragment) { if ( this.fromClause.length() > 0 ) { this.fromClause.append( ", " ); this.guesstimatedBufferSize += 2; } this.fromClause.append( fragment ); this.guesstimatedBufferSize += fragment.length(); }
Appends the specified table name and alias as a from clause fragment.
Params:
  • tableName – The table name.
  • alias – The table alias.
/** * Appends the specified table name and alias as a from clause fragment. * * @param tableName The table name. * @param alias The table alias. */
public void appendFromClauseFragment(String tableName, String alias) { appendFromClauseFragment( tableName + ' ' + alias ); }
Appends the specified restrictions after "cleaning" the specified value (by trimming and removing 'and ' from beginning and ' and' from the end). If the where clause already exists, this method ensure that ' and ' prefixes the cleaned restrictions.
Params:
  • restrictions – The restrictions.
/** * Appends the specified restrictions after "cleaning" the specified value * (by trimming and removing 'and ' from beginning and ' and' from the end). * If the where clause already exists, this method ensure that ' and ' * prefixes the cleaned restrictions. * * @param restrictions The restrictions. */
public void appendRestrictions(String restrictions) { final String cleaned = cleanRestrictions( restrictions ); if ( StringHelper.isEmpty( cleaned ) ) { return; } this.guesstimatedBufferSize += cleaned.length(); if ( whereClause == null ) { whereClause = new StringBuilder( cleaned ); } else { whereClause.append( " and " ).append( cleaned ); this.guesstimatedBufferSize += 5; } } private String cleanRestrictions(String restrictions) { restrictions = restrictions.trim(); if ( restrictions.startsWith( "and " ) ) { restrictions = restrictions.substring( 4 ); } if ( restrictions.endsWith( " and" ) ) { restrictions = restrictions.substring( 0, restrictions.length()-4 ); } return restrictions; }
Sets the outer join fragments to be added to the "from" and "where" clauses.
Params:
  • outerJoinsAfterFrom – The outer join fragment to be appended to the "from" clause.
  • outerJoinsAfterWhere – The outer join fragment to be appended to the "where" clause.
/** * Sets the outer join fragments to be added to the "from" and "where" clauses. * * @param outerJoinsAfterFrom The outer join fragment to be appended to the "from" clause. * @param outerJoinsAfterWhere The outer join fragment to be appended to the "where" clause. */
public void setOuterJoins(String outerJoinsAfterFrom, String outerJoinsAfterWhere) { this.outerJoinsAfterFrom = outerJoinsAfterFrom; final String cleanRestrictions = cleanRestrictions( outerJoinsAfterWhere ); this.outerJoinsAfterWhere = cleanRestrictions; this.guesstimatedBufferSize += outerJoinsAfterFrom.length() + cleanRestrictions.length(); }
Appends the "order by" fragment, prefixed by a comma if the "order by" fragment already exists.
Params:
  • ordering – The "order by" fragment to append.
/** * Appends the "order by" fragment, prefixed by a comma if the "order by" fragment already * exists. * * @param ordering The "order by" fragment to append. */
public void appendOrderByFragment(String ordering) { if ( this.orderByClause == null ) { this.orderByClause = new StringBuilder(); } else { this.orderByClause.append( ", " ); this.guesstimatedBufferSize += 2; } this.orderByClause.append( ordering ); }
Sets the comment for the select statement.
Params:
  • comment – The comment.
/** * Sets the comment for the select statement. * * @param comment The comment. */
public void setComment(String comment) { this.comment = comment; this.guesstimatedBufferSize += comment.length(); }
Sets the lock mode for the select statement.
Params:
  • lockMode – The lock mode.
/** * Sets the lock mode for the select statement. * * @param lockMode The lock mode. */
public void setLockMode(LockMode lockMode) { this.lockOptions.setLockMode( lockMode ); }
Sets the lock options for the select statement.
Params:
  • lockOptions – The lock options.
/** * Sets the lock options for the select statement. * * @param lockOptions The lock options. */
public void setLockOptions(LockOptions lockOptions) { LockOptions.copy( lockOptions, this.lockOptions ); }
Construct an SQL SELECT statement from the given clauses.
Returns:the SQL SELECT statement.
/** * Construct an SQL <tt>SELECT</tt> statement from the given clauses. * * @return the SQL <tt>SELECT</tt> statement. */
public String toStatementString() { StringBuilder buf = new StringBuilder( guesstimatedBufferSize ); if ( StringHelper.isNotEmpty( comment ) ) { buf.append( "/* " ).append( comment ).append( " */ " ); } buf.append( "select " ) .append( selectClause ) .append( " from " ) .append( fromClause ); if ( StringHelper.isNotEmpty( outerJoinsAfterFrom ) ) { buf.append( outerJoinsAfterFrom ); } if ( isNotEmpty( whereClause ) || isNotEmpty( outerJoinsAfterWhere ) ) { buf.append( " where " ); // the outerJoinsAfterWhere needs to come before where clause to properly // handle dynamic filters if ( StringHelper.isNotEmpty( outerJoinsAfterWhere ) ) { buf.append( outerJoinsAfterWhere ); if ( isNotEmpty( whereClause ) ) { buf.append( " and " ); } } if ( isNotEmpty( whereClause ) ) { buf.append( whereClause ); } } if ( orderByClause != null ) { buf.append( " order by " ).append( orderByClause ); } if ( lockOptions.getLockMode() != LockMode.NONE ) { buf = new StringBuilder(dialect.applyLocksToSql( buf.toString(), lockOptions, null ) ); } return dialect.transformSelectString( buf.toString() ); } private boolean isNotEmpty(String string) { return StringHelper.isNotEmpty( string ); } private boolean isNotEmpty(StringBuilder builder) { return builder != null && builder.length() > 0; } }