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

📄 dialect.java

📁 好东西,hibernate-3.2.0,他是一开元的树杖hibernate-3.2.0
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
//$Id: Dialect.java 10307 2006-08-22 19:26:38Z steve.ebersole@jboss.com $
package org.hibernate.dialect;

import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.MappingException;
import org.hibernate.QueryException;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.CastFunction;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.lock.LockingStrategy;
import org.hibernate.dialect.lock.SelectLockingStrategy;
import org.hibernate.engine.Mapping;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.exception.SQLStateConverter;
import org.hibernate.exception.ViolatedConstraintNameExtracter;
import org.hibernate.id.IdentityGenerator;
import org.hibernate.id.SequenceGenerator;
import org.hibernate.id.TableHiLoGenerator;
import org.hibernate.mapping.Column;
import org.hibernate.persister.entity.Lockable;
import org.hibernate.sql.ANSICaseFragment;
import org.hibernate.sql.ANSIJoinFragment;
import org.hibernate.sql.CaseFragment;
import org.hibernate.sql.JoinFragment;
import org.hibernate.type.Type;
import org.hibernate.util.ReflectHelper;
import org.hibernate.util.StringHelper;

/**
 * Represents a dialect of SQL implemented by a particular RDBMS.
 * Subclasses implement Hibernate compatibility with different systems.<br>
 * <br>
 * Subclasses should provide a public default constructor that <tt>register()</tt>
 * a set of type mappings and default Hibernate properties.<br>
 * <br>
 * Subclasses should be immutable.
 *
 * @author Gavin King, David Channon
 */
public abstract class Dialect {

	private static final Log log = LogFactory.getLog( Dialect.class );

	static final String DEFAULT_BATCH_SIZE = "15";
	static final String NO_BATCH = "0";

	private static final Map STANDARD_AGGREGATE_FUNCTIONS = new HashMap();
	
	static {
		STANDARD_AGGREGATE_FUNCTIONS.put( "count", new StandardSQLFunction("count") {
			public Type getReturnType(Type columnType, Mapping mapping) {
				return Hibernate.LONG;
			}
		} );

		STANDARD_AGGREGATE_FUNCTIONS.put( "avg", new StandardSQLFunction("avg") {
			public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
				int[] sqlTypes;
				try {
					sqlTypes = columnType.sqlTypes( mapping );
				}
				catch ( MappingException me ) {
					throw new QueryException( me );
				}
				if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in avg()" );
				return Hibernate.DOUBLE;
			}
		} );

		STANDARD_AGGREGATE_FUNCTIONS.put( "max", new StandardSQLFunction("max") );
		STANDARD_AGGREGATE_FUNCTIONS.put( "min", new StandardSQLFunction("min") );
		STANDARD_AGGREGATE_FUNCTIONS.put( "sum", new StandardSQLFunction("sum") {
			public Type getReturnType(Type columnType, Mapping mapping) {
				//pre H3.2 behavior: super.getReturnType(ct, m);
				int[] sqlTypes;
				try {
					sqlTypes = columnType.sqlTypes( mapping );
				}
				catch ( MappingException me ) {
					throw new QueryException( me );
				}
				if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in sum()" );
				int sqlType = sqlTypes[0];
				
				// First allow the actual type to control the return value. (the actual underlying sqltype could actually be different)
				if ( columnType == Hibernate.BIG_INTEGER ) {
					return Hibernate.BIG_INTEGER;
				}
				else if ( columnType == Hibernate.BIG_DECIMAL ) {
					return Hibernate.BIG_DECIMAL;
				}
				else if ( columnType == Hibernate.LONG || columnType == Hibernate.SHORT || columnType == Hibernate.INTEGER) {
					return Hibernate.LONG;
				}
				else if ( columnType == Hibernate.FLOAT || columnType == Hibernate.DOUBLE) {
					return Hibernate.DOUBLE;
				} 
				
				// finally use the sqltype if == on Hibernate types did not find a match.
				if ( sqlType == Types.NUMERIC ) {
					return columnType; //because numeric can be anything  
				} 
				else if ( sqlType == Types.FLOAT || sqlType == Types.DOUBLE || sqlType == Types.DECIMAL || sqlType == Types.REAL) {
					return Hibernate.DOUBLE;
				} 
				else if ( sqlType == Types.BIGINT || sqlType == Types.INTEGER || sqlType == Types.SMALLINT || sqlType == Types.TINYINT ) {
					return Hibernate.LONG;
				}
				else {
					return columnType;
				}				
			}
		});
	}

	private final TypeNames typeNames = new TypeNames();
	private final TypeNames hibernateTypeNames = new TypeNames();

	private final Properties properties = new Properties();
	private final Map sqlFunctions = new HashMap();
	private final Set sqlKeywords = new HashSet();

	
	protected Dialect() {
		log.info( "Using dialect: " + this );
		sqlFunctions.putAll( STANDARD_AGGREGATE_FUNCTIONS );

		// standard sql92 functions (can be overridden by subclasses)
		registerFunction( "substring", new SQLFunctionTemplate( Hibernate.STRING, "substring(?1, ?2, ?3)" ) );
		registerFunction( "locate", new SQLFunctionTemplate( Hibernate.INTEGER, "locate(?1, ?2, ?3)" ) );
		registerFunction( "trim", new SQLFunctionTemplate( Hibernate.STRING, "trim(?1 ?2 ?3 ?4)" ) );
		registerFunction( "length", new StandardSQLFunction( "length", Hibernate.INTEGER ) );
		registerFunction( "bit_length", new StandardSQLFunction( "bit_length", Hibernate.INTEGER ) );
		registerFunction( "coalesce", new StandardSQLFunction( "coalesce" ) );
		registerFunction( "nullif", new StandardSQLFunction( "nullif" ) );
		registerFunction( "abs", new StandardSQLFunction( "abs" ) );
		registerFunction( "mod", new StandardSQLFunction( "mod", Hibernate.INTEGER) );
		registerFunction( "sqrt", new StandardSQLFunction( "sqrt", Hibernate.DOUBLE) );
		registerFunction( "upper", new StandardSQLFunction("upper") );
		registerFunction( "lower", new StandardSQLFunction("lower") );
		registerFunction( "cast", new CastFunction() );
		registerFunction( "extract", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(?1 ?2 ?3)") );
		
		//map second/minute/hour/day/month/year to ANSI extract(), override on subclasses
		registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(second from ?1)") );
		registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(minute from ?1)") );
		registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(hour from ?1)") );
		registerFunction( "day", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(day from ?1)") );
		registerFunction( "month", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(month from ?1)") );
		registerFunction( "year", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(year from ?1)") );
		
		registerFunction( "str", new SQLFunctionTemplate(Hibernate.STRING, "cast(?1 as char)") );

        // register hibernate types for default use in scalar sqlquery type auto detection
		registerHibernateType( Types.BIGINT, Hibernate.BIG_INTEGER.getName() );
		registerHibernateType( Types.BINARY, Hibernate.BINARY.getName() );
		registerHibernateType( Types.BIT, Hibernate.BOOLEAN.getName() );
		registerHibernateType( Types.CHAR, Hibernate.CHARACTER.getName() );
		registerHibernateType( Types.DATE, Hibernate.DATE.getName() );
		registerHibernateType( Types.DOUBLE, Hibernate.DOUBLE.getName() );
		registerHibernateType( Types.FLOAT, Hibernate.FLOAT.getName() );
		registerHibernateType( Types.INTEGER, Hibernate.INTEGER.getName() );
		registerHibernateType( Types.SMALLINT, Hibernate.SHORT.getName() );
		registerHibernateType( Types.TINYINT, Hibernate.BYTE.getName() );
		registerHibernateType( Types.TIME, Hibernate.TIME.getName() );
		registerHibernateType( Types.TIMESTAMP, Hibernate.TIMESTAMP.getName() );
		registerHibernateType( Types.VARCHAR, Hibernate.STRING.getName() );
		registerHibernateType( Types.VARBINARY, Hibernate.BINARY.getName() );
		registerHibernateType( Types.NUMERIC, Hibernate.BIG_DECIMAL.getName() );
		registerHibernateType( Types.DECIMAL, Hibernate.BIG_DECIMAL.getName() );
		registerHibernateType( Types.BLOB, Hibernate.BLOB.getName() );
		registerHibernateType( Types.CLOB, Hibernate.CLOB.getName() );
		
	}

	public String toString() {
		return getClass().getName();
	}

	/**
	 * Characters used for quoting SQL identifiers
	 */
	public static final String QUOTE = "`\"[";
	public static final String CLOSED_QUOTE = "`\"]";


	/**
	 * Get the name of the database type associated with the given
	 * <tt>java.sql.Types</tt> typecode.
	 *
	 * @param code <tt>java.sql.Types</tt> typecode
	 * @return the database type name
	 * @throws HibernateException
	 */
	public String getTypeName(int code) throws HibernateException {
		String result = typeNames.get( code );
		if ( result == null ) {
			throw new HibernateException( "No default type mapping for (java.sql.Types) " + code );
		}
		return result;
	}

	
	public String getHibernateTypeName(int code) throws HibernateException {
		String result = hibernateTypeNames.get( code );
		if ( result == null ) {
			throw new HibernateException( 
					"No Hibernate type mapping for java.sql.Types code: " +
					code);
		}
		return result;
	}

	public String getHibernateTypeName(int code, int length, int precision, int scale) throws HibernateException {
		String result = hibernateTypeNames.get( code, length, precision, scale );
		if ( result == null ) {
			throw new HibernateException( 
					"No Hibernate type mapping for java.sql.Types code: " +
					code +
					", length: " +
					length 
				);
		}
		return result;		
	}

	/**
	 * Get the name of the database type associated with the given
	 * <tt>java.sql.Types</tt> typecode.
	 * @param code      <tt>java.sql.Types</tt> typecode
	 * @param length    the length or precision of the column
	 * @param precision the precision of the column
	 * @param scale the scale of the column
	 *
	 * @return the database type name
	 * @throws HibernateException
	 */
	public String getTypeName(int code, int length, int precision, int scale) throws HibernateException {
		String result = typeNames.get( code, length, precision, scale );
		if ( result == null ) {
			throw new HibernateException( 
					"No type mapping for java.sql.Types code: " +
					code +
					", length: " +
					length 
				);
		}
		return result;
	}
	
	public String getCastTypeName(int code) {
		return getTypeName(
				code, 
				Column.DEFAULT_LENGTH, 
				Column.DEFAULT_PRECISION, 
				Column.DEFAULT_SCALE 
			);
	}

	protected void registerFunction(String name, SQLFunction function) {
		sqlFunctions.put( name, function );
	}

	protected void registerKeyword(String word) {
		sqlKeywords.add(word);
	}
	
	public Set getKeywords() {
		return sqlKeywords;
	}

	/**
	 * Subclasses register a typename for the given type code and maximum
	 * column length. <tt>$l</tt> in the type name with be replaced by the
	 * column length (if appropriate).
	 *
	 * @param code     <tt>java.sql.Types</tt> typecode
	 * @param capacity maximum length of database type
	 * @param name     the database type name
	 */
	protected void registerColumnType(int code, int capacity, String name) {
		typeNames.put( code, capacity, name );
	}

	/**
	 * Subclasses register a typename for the given type code. <tt>$l</tt> in
	 * the type name with be replaced by the column length (if appropriate).
	 *
	 * @param code <tt>java.sql.Types</tt> typecode
	 * @param name the database type name
	 */
	protected void registerColumnType(int code, String name) {
		typeNames.put( code, name );
	}
	
	protected void registerHibernateType(int sqlcode, String name) {
		hibernateTypeNames.put( sqlcode, name);
	}

	protected void registerHibernateType(int sqlcode, int capacity, String name) {
		hibernateTypeNames.put( sqlcode, capacity, name);
	}

	/**
	 * Does this dialect support the <tt>ALTER TABLE</tt> syntax?
	 *
	 * @return boolean
	 */
	public boolean hasAlterTable() {
		return true;
	}

	/**
	 * Do we need to drop constraints before dropping tables in this dialect?
	 *
	 * @return boolean
	 */
	public boolean dropConstraints() {
		return true;
	}

	/**
	 * Do we need to qualify index names with the schema name?
	 *
	 * @return boolean
	 */
	public boolean qualifyIndexName() {
		return true;
	}

	/**
	 * Does the <tt>FOR UPDATE OF</tt> syntax specify particular
	 * columns?
	 */
	public boolean forUpdateOfColumns() {
		return false;
	}

	/**
	 * Retrieves the <tt>FOR UPDATE OF column_list</tt> syntax specific to this
	 * dialect, where the given aliases represent the aliases of the columns
	 * which are to be write locked.
	 *
	 * @return The appropriate <tt>FOR UPDATE OF column_list</tt> clause string.
	 */
	public String getForUpdateString(String aliases) {

⌨️ 快捷键说明

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