帆软使用的第三方框架。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

235 lines
6.7 KiB

/*
* 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 com.fr.third.org.hibernate.loader.plan.exec.query.internal;
import com.fr.third.org.hibernate.LockMode;
import com.fr.third.org.hibernate.LockOptions;
import com.fr.third.org.hibernate.dialect.Dialect;
import com.fr.third.org.hibernate.internal.util.StringHelper;
/**
* Largely a copy of the {@link com.fr.third.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.
*
* @param dialect The dialect.
*/
public SelectStatementBuilder(Dialect dialect) {
this.dialect = dialect;
}
/**
* 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.
*
* @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.
*
* @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.
*
* @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.
*
* @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.
*
* @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.
*
* @param comment The comment.
*/
public void setComment(String comment) {
this.comment = comment;
this.guesstimatedBufferSize += comment.length();
}
/**
* 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.
*
* @param lockOptions The lock options.
*/
public void setLockOptions(LockOptions lockOptions) {
LockOptions.copy( lockOptions, this.lockOptions );
}
/**
* 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( Dialect.escapeComment(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;
}
}