从施用角度看Hibernate源码(一):Hibernate配置文件
从应用角度看Hibernate源码(一):Hibernate配置文件???????? Hibernate可以说伴随着我的整个Java历程。从我
从应用角度看Hibernate源码(一):Hibernate配置文件
???????? Hibernate可以说伴随着我的整个Java历程。从我一开始工作,我就在一次意外的机会认识了它。以前,在使用语言上我是非常激进的。因为公司不采用Hibernate,我辞去了两份工作。可今天我们搞门户网站的时候,我却第一个反对使用Hibernate。总之,Hibernate让我彻夜难眠。
??????? 刚开始接触Hibernate时,自然就要接触Hibernate配置文件,众所周知,Hibernate有两种配置模式:一个采用属性文件,一个采用XML配置文件。一般在早期Hibernate2时,大家都喜欢采用属性文件,现在大家都喜欢用XML配置文件。现在不妨贴一段基本XML配置给大家看看:
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,肯定表明是唯一性。secondPassCompile();
这句话啥意思,我看源码时没找到出处。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);}
看到这些,如果你不是很笨,应该明白是怎么一回事了吧。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函数。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 collectionlog.debug( "processing foreign key constraints" );iter = getTableMappings();Set done = new HashSet();while ( iter.hasNext() ) {secondPassCompileForeignKeys( (Table) iter.next(), done );}}
意图非常的明显,重新加载各种属性,在源码中被多次用到。
public class Configuration implements Serializable { ......}
这个配置文件是是序列化的,其实Hibernate把全局的类对象都给序列化了。
public Configuration addJar(File jar) throws MappingException {log.info( "Searching for mapping documents in jar: " + jar.getName() );JarFile jarFile = null;try {try {jarFile = new JarFile( jar );}catch (IOException ioe) {throw new InvalidMappingException("Could not read mapping documents from jar: " + jar.getName(), "jar", jar.getName(),ioe);}Enumeration jarEntries = jarFile.entries();while ( jarEntries.hasMoreElements() ) {ZipEntry ze = (ZipEntry) jarEntries.nextElement();if ( ze.getName().endsWith( ".hbm.xml" ) ) {log.info( "Found mapping document in jar: " + ze.getName() );try {addInputStream( jarFile.getInputStream( ze ) );}catch (Exception e) {throw new InvalidMappingException("Could not read mapping documents from jar: " + jar.getName(),"jar",jar.getName(),e);}}}}finally {try {if ( jarFile != null ) {jarFile.close();}}catch (IOException ioe) {log.error("could not close jar", ioe);}}return this;}
这个方法是我们不常用的方法,用于加载jar包里面*.hbm.xml文件。其实我们从中学到的不仅仅是Hibernate的一个功能,而是学到了如何对Jar文件进行合理的操作。如果有一天需要对jar文件进行操作,到Hibernate源码里看看就行了。 12 楼 fuwang 2007-10-09 fu80008 写道这个帖子,不是对Hibernate性能的讨论,这里只做简单的介绍。Hibernate有很多致命的弱点。最重要的是Hibernate是单库(可以说单实例)解决方案。尽管Hibernate现在除了一个新的多库解决方案。但目前是不成熟的。
就写这么多吧。我怕引发争议,偏离了主题。
我也觉得这是hibernate一个很值得讨论的问题。
你能否以此为主题另开新贴,让高手们都来参与一下。 13 楼 myyate 2007-10-09 奇怪,这个帖子写的还可以吧,怎么投隐藏了? 14 楼 fu80008 2007-10-09 好酒不怕巷子深。只要是好东西,会有人发现的。至于Hibernate的优劣,也懒得去讨论了,一般没有什么结果。就是一帮不懂的人在瞎侃。没劲
这个帖子就写到这儿吧,如果有什么好的思想,大家可以来补充。 15 楼 fuwang 2007-10-09 你怎么能说别人不懂hibernate呢,几百万上千万的项目都是这样的人做出来的! 16 楼 fu80008 2007-10-09 大哥,就这样吧。别难为我了,你要是觉得合适你也可以去开辟一个专栏试试。 17 楼 fuwang 2007-10-09 不是啊,我觉得你写得很好,那个投隐藏的太可耻了。
你写了这么多条,全部都切合"从应用角度看hibernate源码"的主题,虽然有几条稍微浅显点,但总的来说,对那些刚入门者、甚至用了几年hibernate的人都极具启发意义。当然,对于那些"不屑编码"者,"忽悠"者,确实没有用。我觉得这是篇很好的帖子,希望楼主继续(可另开帖)。
还有我建议你再开专栏时,尽量把前面几楼、甚至首页自己给占了,免得让别人说废话,影响气氛。 18 楼 fu80008 2007-10-09 谢谢,兄台的关注。 19 楼 javachs 2007-10-10 写的不错,顶,眼高手低者务扰。 20 楼 zhouzhibo 2007-12-04 写得不错,顶
我的异常网推荐解决方案:org.hibernate.MappingException: Association references unmapped class,http://www.myexception.cn/j2ee/326371.html