论坛首页 Java企业应用论坛

从应用角度看Hibernate源码(一):Hibernate配置文件

浏览 11486 次
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-10-07  

         Hibernate可以说伴随着我的整个Java历程。从我一开始工作,我就在一次意外的机会认识了它。以前,在使用语言上我是非常激进的。因为公司不采用Hibernate,我辞去了两份工作。可今天我们搞门户网站的时候,我却第一个反对使用Hibernate。总之,Hibernate让我彻夜难眠。

        刚开始接触Hibernate时,自然就要接触Hibernate配置文件,众所周知,Hibernate有两种配置模式:一个采用属性文件,一个采用XML配置文件。一般在早期Hibernate2时,大家都喜欢采用属性文件,现在大家都喜欢用XML配置文件。现在不妨贴一段基本XML配置给大家看看:

java 代码
  1. <?xml version='1.0' encoding='UTF-8'?>   
  2. <!DOCTYPE hibernate-configuration PUBLIC   
  3.           "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
  4.           "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">   
  5.   
  6. <!-- Generated by MyEclipse Hibernate Tools.                   -->   
  7. <hibernate-configuration>   
  8.   
  9.     <session-factory>   
  10.         <property name="dialect">   
  11.             org.hibernate.dialect.MySQLDialect   
  12.         </property>   
  13.         <property name="connection.url">   
  14.             jdbc:mysql://localhost:3306/hibtest   
  15.         </property>   
  16.         <property name="connection.username">root</property>   
  17.         <property name="connection.driver_class">   
  18.             com.mysql.jdbc.Driver   
  19.         </property>   
  20.         <property name="hibernate.fetch">true</property>   
  21.         <property name="hibernate.show_sql">true</property>   
  22.         <property name="hibernate.cache.use_query_cache">true</property>   
  23.         <property name="hibernate.cache.provider_class">   
  24.             org.hibernate.cache.EhCacheProvider   
  25.         </property>   
  26.         <mapping resource="hib/pojo/Canguan.hbm.xml" />   
  27.         <mapping resource="hib/pojo/Kecheng.hbm.xml" />   
  28.         <mapping resource="hib/pojo/Reply.hbm.xml" />   
  29.         <mapping resource="com/edong/pojo/SongGame.hbm.xml" />   
  30.     </session-factory>   
  31.   
  32. </hibernate-configuration>  

上面这段代码,在一般的Hibernate使用者来说再也普通不过了。但如果从本质上去看待这些文件,能够看到很多内容。


(1)作为一个XML首先要注意的就是它的结构。 Hibernate 结构是由hibernate-configuration-3.0.dtd决定的。打开dtd文件自然就可以看到dtd结构。由于篇幅限制,读者可以在源码的src\org\hibernate目录下找到该文件。如果用户对这些dtd不熟悉,可以去看源码\etc目录下的配置demo。如果你还觉得不够, 可以采用Eclipse的提示去达到自己的目的。

(2)大家要注意的是,作为一个配置文件开始的第一个标签是不动的。同样对于以上的配置文件来说,<hibernate-configuration>元素是全局元素。

先吃饭去了,过会儿再继续

   发表时间:2007-10-08  
你吃了一天了?
0 请登录后投票
   发表时间:2007-10-08  
幸亏楼上的老兄提醒。这才发现自己吃了一天了,终于,吃饱了,喝足了。接着说。哈哈!
    续:如果发现开始元素不唯一,建议拆分成多个文件。
(3)通过观察环境dtd文件你会发现,<session-factory>元素是唯一的。这就表明一个配置文件可以创建一个sessionFacotry,也同时表示一个配置环境中可以连接一个的数据库。如果不放心,可以去看org.hibernate.cfg.Configuration下的
public SessionFactory buildSessionFactory() throws HibernateException {
		log.debug( "Preparing to build session factory with filters : " + filterDefinitions );
		secondPassCompile();
		validate();
		Environment.verifyProperties( properties );
		Properties copy = new Properties();
		copy.putAll( properties );
		PropertiesHelper.resolvePlaceHolders( copy );
		Settings settings = buildSettings( copy );

		return new SessionFactoryImpl(
				this,
				mapping,
				settings,
				getInitializedEventListeners()
			);
	}

这个方法在配置文件下,不带参数创建SessionFactory,肯定表明是唯一性。
0 请登录后投票
   发表时间:2007-10-08  
把你前后对hibernate的态度的巨大变化讲一下,是啥让你变了心。
0 请登录后投票
   发表时间:2007-10-08  
secondPassCompile(); 

这句话啥意思,我看源码时没找到出处。
0 请登录后投票
   发表时间:2007-10-08  
(4)SessionFacotry相信大家都用过。在配置时,往往因找不到下面的属性配置,而在网络上东找西找。其实非常简单,只需要打开源码下的\etc\hibernate.properties,真是要啥有啥。而且肯定不用怀疑是否准确。同时Hibernate支持多少种数据库也尽收眼底。
(5)介绍一个重要的属性-dialect。做数据库语句查询时,大家都知道dialect是数据库的方言,但是,当不知道一个Hibernate的HQL函数而抓耳挠腮时,却不知道打开Hibernate方言看看。打开Hibernate所对用的方言。会发现里面挂满了Hibernate所能支持函数的全部。不相信看看如下的Mysql的方言。

public MySQLDialect() {
		super();
		registerColumnType( Types.BIT, "bit" );
		registerColumnType( Types.BIGINT, "bigint" );
		registerColumnType( Types.SMALLINT, "smallint" );
		registerColumnType( Types.TINYINT, "tinyint" );
		registerColumnType( Types.INTEGER, "integer" );
		registerColumnType( Types.CHAR, "char(1)" );
		registerColumnType( Types.FLOAT, "float" );
		registerColumnType( Types.DOUBLE, "double precision" );
		registerColumnType( Types.DATE, "date" );
		registerColumnType( Types.TIME, "time" );
		registerColumnType( Types.TIMESTAMP, "datetime" );
		registerColumnType( Types.VARBINARY, "longblob" );
		registerColumnType( Types.VARBINARY, 16777215, "mediumblob" );
		registerColumnType( Types.VARBINARY, 65535, "blob" );
		registerColumnType( Types.VARBINARY, 255, "tinyblob" );
		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
		registerColumnType( Types.BLOB, "longblob" );
		registerColumnType( Types.BLOB, 16777215, "mediumblob" );
		registerColumnType( Types.BLOB, 65535, "blob" );
		registerColumnType( Types.CLOB, "longtext" );
		registerColumnType( Types.CLOB, 16777215, "mediumtext" );
		registerColumnType( Types.CLOB, 65535, "text" );
		registerVarcharTypes();

		registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
		registerFunction("bin", new StandardSQLFunction("bin", Hibernate.STRING) );
		registerFunction("char_length", new StandardSQLFunction("char_length", Hibernate.LONG) );
		registerFunction("character_length", new StandardSQLFunction("character_length", Hibernate.LONG) );
		registerFunction("lcase", new StandardSQLFunction("lcase") );
		registerFunction("lower", new StandardSQLFunction("lower") );
		registerFunction("length", new StandardSQLFunction("length", Hibernate.LONG) );
		registerFunction("ltrim", new StandardSQLFunction("ltrim") );
		registerFunction("ord", new StandardSQLFunction("ord", Hibernate.INTEGER) );
		registerFunction("quote", new StandardSQLFunction("quote") );
		registerFunction("reverse", new StandardSQLFunction("reverse") );
		registerFunction("rtrim", new StandardSQLFunction("rtrim") );
		registerFunction("soundex", new StandardSQLFunction("soundex") );
		registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING) );
		registerFunction("ucase", new StandardSQLFunction("ucase") );
		registerFunction("upper", new StandardSQLFunction("upper") );
		registerFunction("unhex", new StandardSQLFunction("unhex", Hibernate.STRING) );

		registerFunction("abs", new StandardSQLFunction("abs") );
		registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );

		registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
		registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
		registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
		registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
		registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
		registerFunction("crc32", new StandardSQLFunction("crc32", Hibernate.LONG) );
		registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
		registerFunction("ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
		registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE) );
		registerFunction("log2", new StandardSQLFunction("log2", Hibernate.DOUBLE) );
		registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
		registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
		registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE) );
		registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
		registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
		registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );

		registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
		registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );

		registerFunction("ceiling", new StandardSQLFunction("ceiling", Hibernate.INTEGER) );
		registerFunction("ceil", new StandardSQLFunction("ceil", Hibernate.INTEGER) );
		registerFunction("floor", new StandardSQLFunction("floor", Hibernate.INTEGER) );
		registerFunction("round", new StandardSQLFunction("round", Hibernate.INTEGER) );

		registerFunction("datediff", new StandardSQLFunction("datediff", Hibernate.INTEGER) );
		registerFunction("timediff", new StandardSQLFunction("timediff", Hibernate.TIME) );
		registerFunction("date_format", new StandardSQLFunction("date_format", Hibernate.STRING) );

		registerFunction("curdate", new NoArgSQLFunction("curdate", Hibernate.DATE) );
		registerFunction("curtime", new NoArgSQLFunction("curtime", Hibernate.TIME) );
		registerFunction("current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
		registerFunction("current_time", new NoArgSQLFunction("current_time", Hibernate.TIME, false) );
		registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );
		registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) );
		registerFunction("day", new StandardSQLFunction("day", Hibernate.INTEGER) );
		registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", Hibernate.INTEGER) );
		registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING) );
		registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) );
		registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) );
		registerFunction("from_days", new StandardSQLFunction("from_days", Hibernate.DATE) );
		registerFunction("from_unixtime", new StandardSQLFunction("from_unixtime", Hibernate.TIMESTAMP) );
		registerFunction("hour", new StandardSQLFunction("hour", Hibernate.INTEGER) );
		registerFunction("last_day", new StandardSQLFunction("last_day", Hibernate.DATE) );
		registerFunction("localtime", new NoArgSQLFunction("localtime", Hibernate.TIMESTAMP) );
		registerFunction("localtimestamp", new NoArgSQLFunction("localtimestamp", Hibernate.TIMESTAMP) );
		registerFunction("microseconds", new StandardSQLFunction("microseconds", Hibernate.INTEGER) );
		registerFunction("minute", new StandardSQLFunction("minute", Hibernate.INTEGER) );
		registerFunction("month", new StandardSQLFunction("month", Hibernate.INTEGER) );
		registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING) );
		registerFunction("now", new NoArgSQLFunction("now", Hibernate.TIMESTAMP) );
		registerFunction("quarter", new StandardSQLFunction("quarter", Hibernate.INTEGER) );
		registerFunction("second", new StandardSQLFunction("second", Hibernate.INTEGER) );
		registerFunction("sec_to_time", new StandardSQLFunction("sec_to_time", Hibernate.TIME) );
		registerFunction("sysdate", new NoArgSQLFunction("sysdate", Hibernate.TIMESTAMP) );
		registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) );
		registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) );
		registerFunction("time_to_sec", new StandardSQLFunction("time_to_sec", Hibernate.INTEGER) );
		registerFunction("to_days", new StandardSQLFunction("to_days", Hibernate.LONG) );
		registerFunction("unix_timestamp", new StandardSQLFunction("unix_timestamp", Hibernate.LONG) );
		registerFunction("utc_date", new NoArgSQLFunction("utc_date", Hibernate.STRING) );
		registerFunction("utc_time", new NoArgSQLFunction("utc_time", Hibernate.STRING) );
		registerFunction("utc_timestamp", new NoArgSQLFunction("utc_timestamp", Hibernate.STRING) );
		registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER) );
		registerFunction("weekday", new StandardSQLFunction("weekday", Hibernate.INTEGER) );
		registerFunction("weekofyear", new StandardSQLFunction("weekofyear", Hibernate.INTEGER) );
		registerFunction("year", new StandardSQLFunction("year", Hibernate.INTEGER) );
		registerFunction("yearweek", new StandardSQLFunction("yearweek", Hibernate.INTEGER) );

		registerFunction("hex", new StandardSQLFunction("hex", Hibernate.STRING) );
		registerFunction("oct", new StandardSQLFunction("oct", Hibernate.STRING) );

		registerFunction("octet_length", new StandardSQLFunction("octet_length", Hibernate.LONG) );
		registerFunction("bit_length", new StandardSQLFunction("bit_length", Hibernate.LONG) );

		registerFunction("bit_count", new StandardSQLFunction("bit_count", Hibernate.LONG) );
		registerFunction("encrypt", new StandardSQLFunction("encrypt", Hibernate.STRING) );
		registerFunction("md5", new StandardSQLFunction("md5", Hibernate.STRING) );
		registerFunction("sha1", new StandardSQLFunction("sha1", Hibernate.STRING) );
		registerFunction("sha", new StandardSQLFunction("sha", Hibernate.STRING) );

		registerFunction( "concat", new StandardSQLFunction( "concat", Hibernate.STRING ) );

		getDefaultProperties().setProperty(Environment.MAX_FETCH_DEPTH, "2");
		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
	}

看到这些,如果你不是很笨,应该明白是怎么一回事了吧。
0 请登录后投票
   发表时间:2007-10-08  
(6)打开org.hibernate.Dialect目录还有一件让人兴奋的事情。Hibernate对Mysql的数据库作了区分,如MySQL5Dialect、MySQLDialect、MySQLInnoDBDialect等等。打开MySQL5Dialect代码
public class MySQL5Dialect extends MySQLDialect {
	protected void registerVarcharTypes() {
		registerColumnType( Types.VARCHAR, "longtext" );
		registerColumnType( Types.VARCHAR, 16777215, "mediumtext" );
		registerColumnType( Types.VARCHAR, 65535, "varchar($l)" );
	}
}

从以上代码,你可以知道,MySQL4和MySQL5之间有什么区别。更重要的它告诉了你,Hibernate Dialect是可以扩展的。只要你继承自己所需要的方言就可以扩展自己的函数,或者Mysql方言没有注册的MySQL函数。
0 请登录后投票
   发表时间:2007-10-08  
让我再去吃点东西吧,领导老瞄着我的屏幕。哈哈
0 请登录后投票
   发表时间:2007-10-08  
javachs 写道
secondPassCompile(); 

这句话啥意思,我看源码时没找到出处。


我用的是版本3.2,源码是这样
protected void secondPassCompile() throws MappingException {
		log.debug( "processing extends queue" );

		processExtendsQueue();

		log.debug( "processing collection mappings" );

		Iterator iter = secondPasses.iterator();
		while ( iter.hasNext() ) {
			SecondPass sp = (SecondPass) iter.next();
			if ( ! (sp instanceof QuerySecondPass) ) {
				sp.doSecondPass( classes ); 
				iter.remove();
			}
		}

		log.debug( "processing native query and ResultSetMapping mappings" );
		iter = secondPasses.iterator();
		while ( iter.hasNext() ) {
			SecondPass sp = (SecondPass) iter.next();
			sp.doSecondPass( classes ); 
			iter.remove();
		}

		log.debug( "processing association property references" );

		iter = propertyReferences.iterator();
		while ( iter.hasNext() ) {
			Mappings.PropertyReference upr = (Mappings.PropertyReference) iter.next();

			PersistentClass clazz = getClassMapping( upr.referencedClass );
			if ( clazz == null ) {
				throw new MappingException(
						"property-ref to unmapped class: " +
						upr.referencedClass
					);
			}

			Property prop = clazz.getReferencedProperty( upr.propertyName );
			if ( upr.unique ) {
				( (SimpleValue) prop.getValue() ).setAlternateUniqueKey( true );
			}
		}

		//TODO: Somehow add the newly created foreign keys to the internal collection

		log.debug( "processing foreign key constraints" );

		iter = getTableMappings();
		Set done = new HashSet();
		while ( iter.hasNext() ) {
			secondPassCompileForeignKeys( (Table) iter.next(), done );
		}

	}


  意图非常的明显,重新加载各种属性,在源码中被多次用到。
0 请登录后投票
   发表时间:2007-10-08  
感谢你讲了一些一般人不会注意而实际上很有用的东西,但大家最关心的是你为什么反对在门户网站使用Hibernate。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics