Spring讲述如何创建hibernate配置文件对象

    今天在论坛上看到一位朋友希望自己在java中动态的创建hibernate的配置文件(并不是生成而是创建hibernate配置文件对象),脑海中第一个想到的就是spring源码,因为spring有整合hibernate的功能,于是翻阅了spring的代码一看,果然很简单。下面先发断简单的demo。

     public   static   void  main(String[] args)  throws  Exception {
        Configuration configuration 
=   new  Configuration();
        Properties properties 
=   new  Properties();
        properties.setProperty(
" hibernate.dialect " ,
                
" org.hibernate.dialect.SQLServerDialect " );
        String[] mappingResources 
=   new  String[ 1 ];
        mappingResources[
0 =   " com/syj/domain/Issue.hbm.xml " ;
        
for  ( int  i  =   0 ; i  <  mappingResources.length; i ++ ) {
            Resource resource 
=   new  ClassPathResource(mappingResources[i]
                    .trim(), Thread.currentThread().getContextClassLoader());
            configuration.addInputStream(resource.getInputStream());
        }
        configuration.addProperties(properties);
        configuration.buildSessionFactory();
    }

上面代码中properties还缺少很多属性,因为只是个demo所以我没有填写全部的属性,其实这里的属性就是指hibernate.cfg.xml中那些属性,例如hibernate.connection.provider_class,show_sql等等。添加到properties中就可以了。

为什么想到spring的源码呢,下面来看spring中如何整合的

 

< bean  id ="sessionFactory"
        class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
        
< property  name ="dataSource" >
            
< ref  bean ="dataSource"   />
        
</ property >
        
< property  name ="hibernateProperties" >
            
< props >
                
< prop  key ="hibernate.dialect" > org.hibernate.dialect.SQLServerDialect </ prop >
                
< prop  key ="hibernate.show_sql" > false </ prop >
                
< prop  key ="hibernate.format_sql" > false </ prop >
                
< prop  key ="hibernate.use_sql_comments" > false </ prop >
                
<!--  为单向关联(一对一, 多对一)的外连接抓取(outer join fetch)树设置最大深度. 值为0意味着将关闭默认的外连接抓取  -->
                
< prop  key ="hibernate.max_fetch_depth" > 3 </ prop >
                
<!--  为Hibernate关联的批量抓取设置默认数量  -->
                
< prop  key ="hibernate.default_batch_fetch_size" > 8 </ prop >
                
<!--  强制Hibernate按照被更新数据的主键,为SQL更新排序。这么做将减少在高并发系统中事务的死锁。  -->
                
< prop  key ="hibernate.order_updates" > true </ prop >
                
<!--  session在事务完成后将被自动清洗(flush)  -->
                
< prop  key ="hibernate.transaction.flush_before_completion" > true </ prop >
                
<!--  Oracle限制那些通过JDBC驱动传输的字节数组的数目. 如果你希望使用二进值 (binary)或 可序列化的 (serializable)类型的大对象, 你应该开启 hibernate.jdbc.use_streams_for_binary属性.   -->
                
< prop  key ="hibernate.bytecode.use_reflection_optimizer" > true </ prop >
            
</ props >
        
</ property >
        
< property  name ="mappingResources" >
            
< list >
                
< value > com/xxx/domain/xxx.hbm.xml </ value >
             
</ list >
       
</ property >
</ bean >

大家都知道spring的依赖注入,其实依赖注入很简单这里不做此介绍,我们按照spring的注入流程思考就可以了,下面看看spring优雅的实现把。在这里我们只关注LocalSessionFactoryBean的一个方法:

     protected  SessionFactory buildSessionFactory()  throws  Exception {
        
//  Create Configuration instance.
        Configuration config  =  newConfiguration();

        DataSource dataSource 
=  getDataSource();
        
if  (dataSource  !=   null ) {
            
//  Make given DataSource available for SessionFactory configuration.
            configTimeDataSourceHolder.set(dataSource);
        }
        
if  ( this .jtaTransactionManager  !=   null ) {
            
//  Make Spring-provided JTA TransactionManager available.
            configTimeTransactionManagerHolder.set( this .jtaTransactionManager);
        }
        
if  ( this .lobHandler  !=   null ) {
            
//  Make given LobHandler available for SessionFactory configuration.
            
//  Do early because because mapping resource might refer to custom types.
            configTimeLobHandlerHolder.set( this .lobHandler);
        }

        
//  Analogous to Hibernate EntityManager's Ejb3Configuration:
        
//  Hibernate doesn't allow setting the bean ClassLoader explicitly,
        
//  so we need to expose it as thread context ClassLoader accordingly.
        Thread currentThread  =  Thread.currentThread();
        ClassLoader threadContextClassLoader 
=  currentThread.getContextClassLoader();
        
boolean  overrideClassLoader  =
                (
this .beanClassLoader  !=   null   &&   ! this .beanClassLoader.equals(threadContextClassLoader));
        
if  (overrideClassLoader) {
            currentThread.setContextClassLoader(
this .beanClassLoader);
        }

        
try  {
            
if  ( this .jtaTransactionManager  !=   null ) {
                
//  Set Spring-provided JTA TransactionManager as Hibernate property.
                config.setProperty(
                        Environment.TRANSACTION_MANAGER_STRATEGY, LocalTransactionManagerLookup.
class .getName());
                config.setProperty(
                        Environment.TRANSACTION_STRATEGY, JTATransactionFactory.
class .getName());
            }
            
else  {
                
//  Set connection release mode "on_close" as default.
                
//  This was the case for Hibernate 3.0; Hibernate 3.1 changed
                
//  it to "auto" (i.e. "after_statement" or "after_transaction").
                
//  However, for Spring's resource management (in particular for
                
//  HibernateTransactionManager), "on_close" is the better default.
                config.setProperty(Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.ON_CLOSE.toString());
            }

            
if  (isExposeTransactionAwareSessionFactory()) {
                
//  Set Hibernate 3.1 CurrentSessionContext implementation,
                
//  providing the Spring-managed Session as current Session.
                
//  Can be overridden by a custom value for the corresponding Hibernate property.
                config.setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS, SpringSessionContext. class .getName());
            }

            
if  ( this .entityInterceptor  !=   null ) {
                
//  Set given entity interceptor at SessionFactory level.
                config.setInterceptor( this .entityInterceptor);
            }

            
if  ( this .namingStrategy  !=   null ) {
                
//  Pass given naming strategy to Hibernate Configuration.
                config.setNamingStrategy( this .namingStrategy);
            }

            
if  ( this .typeDefinitions  !=   null ) {
                
//  Register specified Hibernate type definitions.
                Mappings mappings  =  config.createMappings();
                
for  ( int  i  =   0 ; i  <   this .typeDefinitions.length; i ++ ) {
                    TypeDefinitionBean typeDef 
=   this .typeDefinitions[i];
                    mappings.addTypeDef(typeDef.getTypeName(), typeDef.getTypeClass(), typeDef.getParameters());
                }
            }

            
if  ( this .filterDefinitions  !=   null ) {
                
//  Register specified Hibernate FilterDefinitions.
                 for  ( int  i  =   0 ; i  <   this .filterDefinitions.length; i ++ ) {
                    config.addFilterDefinition(
this .filterDefinitions[i]);
                }
            }

            
if  ( this .configLocations  !=   null ) {
                
for  ( int  i  =   0 ; i  <   this .configLocations.length; i ++ ) {
                    
//  Load Hibernate configuration from given location.
                    config.configure( this .configLocations[i].getURL());
                }
            }

            
if  ( this .hibernateProperties  !=   null ) {
                
//  Add given Hibernate properties to Configuration.
                config.addProperties( this .hibernateProperties);
            }

            
if  (dataSource  !=   null ) {
                
boolean  actuallyTransactionAware  =
                        (isUseTransactionAwareDataSource() 
||  dataSource  instanceof  TransactionAwareDataSourceProxy);
                
//  Set Spring-provided DataSource as Hibernate ConnectionProvider.
                config.setProperty(Environment.CONNECTION_PROVIDER,
                        actuallyTransactionAware 
?
                        TransactionAwareDataSourceConnectionProvider.
class .getName() :
                        LocalDataSourceConnectionProvider.
class .getName());
            }

            
if  ( this .mappingResources  !=   null ) {
                
//  Register given Hibernate mapping definitions, contained in resource files.
                 for  ( int  i  =   0 ; i  <   this .mappingResources.length; i ++ ) {
                    Resource resource 
=   new  ClassPathResource( this .mappingResources[i].trim(),  this .beanClassLoader);
                    config.addInputStream(resource.getInputStream());
                }
            }

            
if  ( this .mappingLocations  !=   null ) {
                
//  Register given Hibernate mapping definitions, contained in resource files.
                 for  ( int  i  =   0 ; i  <   this .mappingLocations.length; i ++ ) {
                    config.addInputStream(
this .mappingLocations[i].getInputStream());
                }
            }

            
if  ( this .cacheableMappingLocations  !=   null ) {
                
//  Register given cacheable Hibernate mapping definitions, read from the file system.
                 for  ( int  i  =   0 ; i  <   this .cacheableMappingLocations.length; i ++ ) {
                    config.addCacheableFile(
this .cacheableMappingLocations[i].getFile());
                }
            }

            
if  ( this .mappingJarLocations  !=   null ) {
                
//  Register given Hibernate mapping definitions, contained in jar files.
                 for  ( int  i  =   0 ; i  <   this .mappingJarLocations.length; i ++ ) {
                    Resource resource 
=   this .mappingJarLocations[i];
                    config.addJar(resource.getFile());
                }
            }

            
if  ( this .mappingDirectoryLocations  !=   null ) {
                
//  Register all Hibernate mapping definitions in the given directories.
                 for  ( int  i  =   0 ; i  <   this .mappingDirectoryLocations.length; i ++ ) {
                    File file 
=   this .mappingDirectoryLocations[i].getFile();
                    
if  ( ! file.isDirectory()) {
                        
throw   new  IllegalArgumentException(
                                
" Mapping directory location [ "   +   this .mappingDirectoryLocations[i]  +
                                
" ] does not denote a directory " );
                    }
                    config.addDirectory(file);
                }
            }

            
if  ( this .entityCacheStrategies  !=   null ) {
                
//  Register cache strategies for mapped entities.
                 for  (Enumeration classNames  =   this .entityCacheStrategies.propertyNames(); classNames.hasMoreElements();) {
                    String className 
=  (String) classNames.nextElement();
                    String[] strategyAndRegion 
=
                            StringUtils.commaDelimitedListToStringArray(
this .entityCacheStrategies.getProperty(className));
                    
if  (strategyAndRegion.length  >   1 ) {
                        config.setCacheConcurrencyStrategy(className, strategyAndRegion[
0 ], strategyAndRegion[ 1 ]);
                    }
                    
else   if  (strategyAndRegion.length  >   0 ) {
                        config.setCacheConcurrencyStrategy(className, strategyAndRegion[
0 ]);
                    }
                }
            }

            
if  ( this .collectionCacheStrategies  !=   null ) {
                
//  Register cache strategies for mapped collections.
                 for  (Enumeration collRoles  =   this .collectionCacheStrategies.propertyNames(); collRoles.hasMoreElements();) {
                    String collRole 
=  (String) collRoles.nextElement();
                    String[] strategyAndRegion 
=
                            StringUtils.commaDelimitedListToStringArray(
this .collectionCacheStrategies.getProperty(collRole));
                    
if  (strategyAndRegion.length  >   1 ) {
                        config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[
0 ], strategyAndRegion[ 1 ]);
                    }
                    
else   if  (strategyAndRegion.length  >   0 ) {
                        config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[
0 ]);
                    }
                }
            }

            
if  ( this .eventListeners  !=   null ) {
                
//  Register specified Hibernate event listeners.
                 for  (Iterator it  =   this .eventListeners.entrySet().iterator(); it.hasNext();) {
                    Map.Entry entry 
=  (Map.Entry) it.next();
                    Assert.isTrue(entry.getKey() 
instanceof  String,  " Event listener key needs to be of type String " );
                    String listenerType 
=  (String) entry.getKey();
                    Object listenerObject 
=  entry.getValue();
                    
if  (listenerObject  instanceof  Collection) {
                        Collection listeners 
=  (Collection) listenerObject;
                        EventListeners listenerRegistry 
=  config.getEventListeners();
                        Object[] listenerArray 
=
                                (Object[]) Array.newInstance(listenerRegistry.getListenerClassFor(listenerType), listeners.size());
                        listenerArray 
=  listeners.toArray(listenerArray);
                        config.setListeners(listenerType, listenerArray);
                    }
                    
else  {
                        config.setListener(listenerType, listenerObject);
                    }
                }
            }

            
//  Perform custom post-processing in subclasses.
            postProcessConfiguration(config);

            
//  Build SessionFactory instance.
            logger.info( " Building new Hibernate SessionFactory " );
            
this .configuration  =  config;
            
return  newSessionFactory(config);
        }

        
finally  {
            
if  (dataSource  !=   null ) {
                
//  Reset DataSource holder.
                configTimeDataSourceHolder.set( null );
            }
            
if  ( this .jtaTransactionManager  !=   null ) {
                
//  Reset TransactionManager holder.
                configTimeTransactionManagerHolder.set( null );
            }
            
if  ( this .lobHandler  !=   null ) {
                
//  Reset LobHandler holder.
                configTimeLobHandlerHolder.set( null );
            }
            
if  (overrideClassLoader) {
                
//  Reset original thread context ClassLoader.
                currentThread.setContextClassLoader(threadContextClassLoader);
            }
        }
    }

你可能感兴趣的:(spring,Hibernate,String,properties,object,null)