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

本文介绍如何在Java中动态创建Hibernate配置文件对象,包括使用Configuration类和Properties类来设置数据库方言及映射资源,并展示了如何在Spring框架中整合Hibernate。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    今天在论坛上看到一位朋友希望自己在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);
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值