spring整合mybatis使用 時的坑


背景

  最近項目要上線,需要開發一個數據遷移程序。程序的主要功能就是將一個數據庫里的數據,查詢出來經過一系列處理后導入另一個數據庫。考慮到開發的方便快捷。自然想到用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 ,否則就無法自動注入。

 

 

 

 

 

 

 

 

 

 

 

ASD


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM