Spring整合Mybatis使用<context:property-placeholder>时的坑

 更新时间:2016年06月24日 11:27:27   作者:永志  
这篇文章主要介绍了Spring整合Mybatis使用<context:property-placeholder>时的坑 的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下

背景

  最近项目要上线,需要开发一个数据迁移程序。程序的主要功能就是将一个数据库里的数据,查询出来经过一系列处理后导入另一个数据库。考虑到开发的方便快捷。自然想到用spring和mybatis整合一下。甚至用mybatis的自动代码生成,可以省下大量dao层的开发。

整合的坑

之前的项目:以前也有过这种类似的程序,就把spring和mybatis整合的配置直接拿来修改下用。之前的整合配置是这样子的:

   1、考虑到数据库url、用户名密码的可配置性,将这些信息放入properties文件。在spring配置文件里使用了

  <context:property-placeholder location="classpath:config.properties" />

    2、在spring配置文件里的mybatis和spring的整合配置是这样

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.lagou.chat.record.transfer.dao" />
</bean> 

  以上配置是没有问题的。所以就直接将配置拷贝到新项目

 当前项目:将老项目的配置拷贝过来,但是新的项目要连接两个数据库,自然需要两个数据源(record和im),就对老的配置做了如下修改

    1、使用properties文件的配置不变

    2、之前因为就一个数据源(一个sqlSessionFactory),所以没有在MapperScannerConfigurer下配置<property name="sqlSessionFactory" ref="sqlSessionFactory"/>。因为默认使用sqlSessionFactory。但现在两个数据源了,不指定肯定导致混乱。所以配置修改为如下

<bean id="record_sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="record_dataSource" />
</bean>
<bean id="config1" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xxx.util.rollback.record.dao" />
<property name="sqlSessionFactory" ref="record_sqlSessionFactory"/>
</bean> 
<bean id="im_sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="im_dataSource" />
</bean>
<bean id="config2" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xxx.util.rollback.im.dao" />
<property name="sqlSessionFactory" ref="im_sqlSessionFactory"/>
</bean> 

  结果就是运行新项目时,spring配置文件里的${jdbc.url},${jdbc.name}等属性无法被properties里的指定值替换。一开始自然想不到是因为spring和mybatis整合的原因,所以一度不断检查spring配置文件是否有误,properties文件是否有误,是不是properties文件没被引用到或者properties文件没有被编译到classpath目录下等。当然,分析没有分析出问题的原因,自然就不可能找到解决问题的办法。只好求助于网络。最终还是找到了答案

  修正方式:将配置需改为如下,问题得到了解决:

<bean id="record_sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="record_dataSource" />
</bean>
<bean id="config1" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xxx.util.rollback.record.dao" />
<property name="sqlSessionFactoryBeanName" value="record_sqlSessionFactory"/>
</bean> 
<bean id="im_sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="im_dataSource" />
</bean>
<bean id="config2" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xxx.util.rollback.im.dao" />
<property name="sqlSessionFactoryBeanName" value="im_sqlSessionFactory"/>
</bean> 

  就是将sqlSessionFactory属性改为sqlSessionFactoryBeanName。当然也得将ref改为value。因为sqlSessionFactoryBeanName属性是字符串类型

原因

  spring里使用org.mybatis.spring.mapper.MapperScannerConfigurer 进行自动扫描的时候,设置了sqlSessionFactory 的话,可能会导致PropertyPlaceholderConfigurer失效,也就是用${jdbc.username}这样之类的表达式,将无法获取到properties文件里的内容。

  导致这一原因是因为,MapperScannerConigurer实际是在解析加载bean定义阶段的,这个时候要是设置sqlSessionFactory的话,会导致提前初始化一些类,这个时候,PropertyPlaceholderConfigurer还没来得及替换定义中的变量,导致把表达式当作字符串复制了。 但如果不设置sqlSessionFactory 属性的话,就必须要保证sessionFactory在spring中名称一定要是sqlSessionFactory ,否则就无法自动注入。

以上所述是小编给大家介绍的Spring整合Mybatis使用<context:property-placeholder>时的坑 ,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • SpringBoot应用程序启动监听功能的常见方法

    SpringBoot应用程序启动监听功能的常见方法

    应用启动监听在 Spring Boot 和其他框架中扮演着重要的角色,它们的主要作用是在应用启动或关闭时触发特定的操作或任务,本文给大家介绍了SpringBoot应用程序启动监听功能的常见方法,需要的朋友可以参考下
    2024-05-05
  • Java8的常用时间api实用指南

    Java8的常用时间api实用指南

    这篇文章主要给大家介绍了关于Java8的常用时间api的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • SpringMVC如何接收参数各种场景

    SpringMVC如何接收参数各种场景

    这篇文章主要介绍了SpringMVC如何接收参数各种场景,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • 支撑Java NIO与NodeJS的底层技术

    支撑Java NIO与NodeJS的底层技术

    这篇文章主要为大家详细介绍了支撑Java NIO与NodeJS的底层技术,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • java实现滑动验证解锁

    java实现滑动验证解锁

    这篇文章主要为大家详细介绍了java实现滑动验证解锁,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • Java实现文件变化监听代码实例

    Java实现文件变化监听代码实例

    这篇文章主要介绍了Java实现文件变化监听代码实例,通过定时任务,轮训查询文件的最后修改时间,与上一次进行对比,如果发生变化,则说明文件已经修改,进行重新加载或对应的业务逻辑处理,需要的朋友可以参考下
    2024-01-01
  • 最新springboot解决跨域的几种方式小结

    最新springboot解决跨域的几种方式小结

    跨域指的是浏览器不能执⾏其他⽹站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制,这篇文章主要介绍了springboot解决跨域的几种方式,需要的朋友可以参考下
    2022-05-05
  • Java基础之ClassLoader详解

    Java基础之ClassLoader详解

    这篇文章主要介绍了Java基础之ClassLoader详解,文中对ClassLoader有非常详细的解说,对正在学习java基础的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04
  • Java调用Python脚本传递数据并返回计算结果

    Java调用Python脚本传递数据并返回计算结果

    实际工程项目中可能会用到Java和python两种语言结合进行,这样就会涉及到一个问题,Java如何调用Python脚本,感兴趣的可以了解一下
    2021-05-05
  • SpringBoot之如何指定配置文件启动

    SpringBoot之如何指定配置文件启动

    这篇文章主要介绍了SpringBoot之如何指定配置文件启动问题,具有很好的参考价值,希望对大家有所帮助。
    2023-04-04

最新评论