spring配置hibernate映射文件的4种方式

来源:互联网 发布:金融网络销售是安全吗 编辑:程序博客网 时间:2024/05/21 19:21

spring配置hibernate映射文件的几种方式

在spring中配置hibernate时,即在配置sessionFactory时,
我们一般这样配置:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><property name="hibernateProperties"><props><prop key="hibernate.dialect">${hibernate.dialect}</prop><prop key="hibernate.query.substitutions">true=1,false=0</prop><prop key="hibernate.jdbc.batch_size">25</prop><prop key="hibernate.show_sql">true</prop><prop key="hibernate.format_sql">false</prop><prop key="hibernate.generate_statistics">false</prop><prop key="hibernate.cache.use_query_cache">false</prop><prop key="hibernate.cache.region_prefix">direct</prop><prop key="hibernate.cache.use_structured_entries">false</prop> <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop><prop key="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</prop> <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop></props></property><property name="dataSource"       ref="dataSource"/><property name="mappingDirectoryLocations">       <list>         <value>classpath:/org/first/config/</value>         <value>classpath:/org/second/config/</value>       </list>        </property></bean>

关于Hibernate的映射文件可以有多重配置方式,看一下org.springframework.orm.hibernate3.LocalSessionFactoryBean
这个类的源码就知道了,这里我截取部分变量。

private Class configurationClass;    private Resource configLocations[];    private String mappingResources[];    private Resource mappingLocations[];    private Resource cacheableMappingLocations[];    private Resource mappingJarLocations[];    private Resource mappingDirectoryLocations[];    private Properties hibernateProperties;    private TransactionManager jtaTransactionManager;    private Object cacheRegionFactory;    private CacheProvider cacheProvider;    private LobHandler lobHandler;    private Interceptor entityInterceptor;    private NamingStrategy namingStrategy;    private TypeDefinitionBean typeDefinitions[];    private FilterDefinition filterDefinitions[];    private Properties entityCacheStrategies;    private Properties collectionCacheStrategies;    private Map eventListeners;    private boolean schemaUpdate;    private ClassLoader beanClassLoader;    private Configuration configuration;

关于映射文件的配置有4个变量可以spring注入:
private String mappingResources[];
private Resource mappingLocations[];
private Resource mappingJarLocations[];
private Resource mappingDirectoryLocations[];


现在我们就开始研究怎么使用者4中方式以及4种方式的区别。


mappingResources方式:

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"><property name="hibernateProperties"><props><prop key="hibernate.dialect">${hibernate.dialect}</prop><prop key="hibernate.query.substitutions">true=1,false=0</prop><prop key="hibernate.jdbc.batch_size">25</prop><prop key="hibernate.show_sql">true</prop><prop key="hibernate.format_sql">false</prop><prop key="hibernate.generate_statistics">false</prop><prop key="hibernate.cache.use_query_cache">false</prop><prop key="hibernate.cache.region_prefix">direct</prop><prop key="hibernate.cache.use_structured_entries">false</prop> <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop><prop key="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</prop> <prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop></props></property><property name="dataSource"       ref="dataSource"/><property name="mappingResources">       <list>         <value>classpath:/org/first/config/context_first.xml</value>         <value>classpath:/org/second/config/context_second.xml</value>       </list>        </property></bean>

上面的配置会报错,提示找不到文件
改成下面后正常启动:

<property name="mappingResources">       <list>         <value>/org/first/config/LsyUser.hbm.xml</value>         <value>/org/second/config/LsyDep.hbm.xml</value>       </list>        </property>

这个有点奇怪了,因为我的xml文件时放在源文件夹中的,应该在路径前添加classpath:才正确。
实验的结果却报错,而不加classpath:的反而正确,我的结论:mappingResources这个属性就是要到
classpath下寻找文件,所以写上它反而错。


还有一点路径中<value>/org/first/config/LsyUser.hbm.xml</value>第一个"/"斜杠对于mappingResources
是不用写的,写了也不会报错。原因是spring自己过滤掉了第一个斜杠。
源码:

if(mappingResources != null)
        {
            String as[];
            int j2 = (as = mappingResources).length;
            for(int k = 0; k < j2; k++)
            {
                String mapping = as[k];
                Resource resource = new ClassPathResource(mapping.trim(), beanClassLoader);
                config.addInputStream(resource.getInputStream());
            }


        }




其中ClassPathResource源码:
public ClassPathResource(String path, ClassLoader classLoader)
    {
        Assert.notNull(path, "Path must not be null");
        String pathToUse = StringUtils.cleanPath(path);
        if(pathToUse.startsWith("/"))
            pathToUse = pathToUse.substring(1);
        this.path = pathToUse;
        this.classLoader = classLoader == null ? ClassUtils.getDefaultClassLoader() : classLoader;
    }

关于 classpath: 和 classpath*: 的区别,网上有篇文章介绍的很好:
Spring加载resource时classpath*:与classpath:的区别 
http://blog.csdn.net/kkdelta/article/details/5507799






mappingLocations方式:

把sessionFactory中的<property name="mappingResources">替换成:

<property name="mappingLocations">       <list>         <value>classpath:/org/first/config/LsyUser.hbm.xml</value>         <value>classpath:/org/second/config/LsyDep.hbm.xml</value>       </list>        </property>

正常启动,可见这个mappingLocations是需要添加classpath:属性的,它的类型不是String,而是
Resource。使用它也可以到文件路径下配置(这里我们把xml文件放到了源文件夹中)。
(注意:url中第一个斜杠"/"同样可以省略。)




现在测试文件路径下的加载:
把上面2个文件放到/webapp/WEB-INF/hixml下,同时改变配置如下:

<property name="mappingLocations">       <list>         <value>/WEB-INF/hixml/LsyUser.hbm.xml</value>         <value>/WEB-INF/hixml/LsyDep.hbm.xml</value>       </list>        </property>

启动成功!(注:第一个斜杠"/"可以省略)


也就是说mappingLocations方式可以加载源文件夹中的文件(加前缀classpath:),
也可以加载物理路径中的文件。而mappingResources方式只能加载源文件夹中的文件
(注意:不能加前缀classpath:)。



还有对于url可以使用通配符,如下同上:

<property name="mappingLocations">       <list>         <value>/WEB-INF/hixml/*.hbm.xml</value>       </list>        </property>

mappingJarLocations方式:

这个方式是加载jar里面的文件,感觉不是很常用,不做研究了。


mappingDirectoryLocations方式:

这种方式是加载某个路径下的所有文件。
如下:

<property name="mappingDirectoryLocations">       <list>         <value>classpath:/org/first/config/</value>         <value>classpath:/org/second/config/</value>       </list>        </property>

也可以加载物理路径下的文件,如下同上:

<property name="mappingDirectoryLocations">       <list>         <value>/WEB-INF/hixml</value>       </list>        </property>

*************************总结******************************************


清楚了以上4中方式,对于我们设计整个工程的架构是很有帮助的。


我们可以把所有Hibernate文件放在一个目录下,这样的好处就是不用每次
做新功能都要记得把新文件引入,也不用担心引入的时候写错了url,缺点就是
模块没有做到松耦合。我喜欢把配置文件都放在每个模块的package中,这样就
需要从源文件夹中引入,每个模块的所有代码都是在一块的也方面寻找代码。


原创粉丝点击