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

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.youkuaiyun.com/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中,这样就
需要从源文件夹中引入,每个模块的所有代码都是在一块的也方面寻找代码。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值