javascript
Spring+Mybatis多数据源配置(二)——databaseIdProvider的使用
歡迎跳轉到本文的原文鏈接:https://honeypps.com/java/spring-mybatis-multi-datasource-props-2/
?
?在上一篇同系列的博文中,講到配置多數據源,然后根據config.properties配置不同的數據庫,進行切換。而且需要根據不同的數據庫,配置不同的mybatis sql映射配置文件,如下:
?
<property name="mapperLocations"><list><value>classpath:com/shr/dao/resources/${dataSource}mappers/*_mapper.xml</value></list></property>?
? ? 這樣根據dataSource名稱匹配不同的mybatis sql映射配置文件,大家都知道mysql和oracle是有一些語法差異的,但是大多數的語法是一樣的,我們能否只針對這些有語法差異的sql語句進行多重配置,其余的相同的語法的就使用同一份配置呢?答案當然是肯定的。
這里需要應用到mybatis的org.apache.ibatis.mapping.VendorDatabaseIdProvider。通過在mybatis sql映射配置文件中添加databaseId的屬性,來區分不同的數據庫。
? ? 舉個例子:
上面是一個獲取用戶信息的sql語句,可以看到mysql和oracle的sql語句有略微的差異(asc和desc),當配置文件config.properties中的dataSource字段配置為mysql或者為oracle時都可以獲取相應的結果。當dataSource配置為oracle然后在上面的代碼中刪掉:
<select id="selectUserInfo" resultMap="userResultMap" databaseId="oracle">select user_id, user_name, user_password, user_privilege, user_alias, create_date, invalid_date from user_define order by user_id desc</select>這一段內容,運行測試用例:
?
?
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("file:WebContent/WEB-INF/applicationContext.xml")@Transactional@TransactionConfiguration(transactionManager="transactionManager",defaultRollback=false)public class UserManageServiceTest {@Injectprivate UserManageService userManageService;@Testpublic void testGetUserListInfo(){List<UserListInfo> list = userManageService.getUserListInfo();for(UserListInfo user : list){System.out.println(user.getUser_name());}}}會報如下錯誤:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.shr.dao.mapper.IuserManageMapper.selectUserInfoat org.apache.ibatis.binding.MapperMethod$SqlCommand.<init>(MapperMethod.java:189)at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:43)at org.apache.ibatis.binding.MapperProxy.cachedMapperMethod(MapperProxy.java:58)at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:51)at com.sun.proxy.$Proxy29.selectUserInfo(Unknown Source)at com.shr.service.userManage.UserManageService.getUserListInfo(UserManageService.java:98)at com.shr.service.userManage.UserManageServiceTest.testGetUserListInfo(UserManageServiceTest.java:35)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)at java.lang.reflect.Method.invoke(Unknown Source)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)at org.junit.runners.ParentRunner.run(ParentRunner.java:300)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)通過報錯信息,大概可以知道沒有相應的配置映射關系。由此可以證明(把config.properties中的dataSource配置成mysql然后刪掉databaseId="mysql"的配置,結果也會報相同的錯誤),mysql對應的是databaseId="mysql"的sql語句,而oracle對應的是databaseId="oracle"的配置語句。或者如果兩個數據庫中用戶表數據是相同的話,通過測試用例打印出來的用戶名稱一個是正序一個是倒序,也可以得出相同的結論。
? ? 最后奉上applicationContext.xml的配置:
?
歡迎跳轉到本文的原文鏈接:???????https://honeypps.com/java/spring-mybatis-multi-datasource-props-2/
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。?
?
總結
以上是生活随笔為你收集整理的Spring+Mybatis多数据源配置(二)——databaseIdProvider的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring+Mybatis多数据源配置
- 下一篇: Spring+Mybatis多数据源配置