今天,公司开年会,然后下午就要走了,然后上午一下子发现上次迁移 db 的时候忘记搞双数据源了 = =。于是,赶紧在一个小时内调代码。
代码写完了,感觉对了,一上线,立马错了!!!
错误是怎样的呢
先说下如何配置双数据源
简单来说,我要配置 2 个datasource
, 因为我用的ibatis, 所以我还要配置2个sqlmap
, 最后封装给spring ,于是 还有2个 SqlMapClientTemplate
于是我这样子搞的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> </bean> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="classpath:sqlmap-config.xml" /> <property name="dataSource" ref="dataSource" /> </bean> <bean id="sqlMapp" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> <property name="sqlMapClient" ref="sqlMapClient" /> </bean>
<bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> </bean> <bean id="sqlMapClient2" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="classpath:sqlmap-config2.xml" /> <property name="dataSource" ref="dataSource2" /> </bean> <bean id="sqlMapp" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> <property name="sqlMapClient" ref="sqlMapClient2" /> </bean>
|
看着没错吧,但一跑起来就错了。 sqlmapp的dataSource
永远不是dataSource2
。
因为很急,马上要走了,然后就觉得代码肯定没问题,是我的问题,尼玛。。。
回家后静下心调试了下
1 2 3 4 5 6 7 8
| System.out.println(dataSource); System.out.println(dataSource2);
System.out.println(sqlMapClient.getObject().getDataSource().getConnection()); System.out.println(sqlMapClient2.getObject().getDataSource().getConnection());
System.out.println(sqlMap); System.out.println(sqlMapp);
|
好吧, 问题出在sqlMap, 即org.springframework.orm.ibatis.SqlMapClientTemplate
,看了下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class SqlMapClientTemplate extends JdbcAccessor implements SqlMapClientOperations {
private SqlMapClient sqlMapClient;
public void setSqlMapClient(SqlMapClient sqlMapClient) { this.sqlMapClient = sqlMapClient; }
@Override public DataSource getDataSource() { DataSource ds = super.getDataSource(); return (ds != null ? ds : this.sqlMapClient.getDataSource()); } }
|
再看他的super class => JdbcAccessor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public abstract class JdbcAccessor implements InitializingBean {
private DataSource dataSource;
public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; }
* Return the DataSource used by this template. */ public DataSource getDataSource() { return this.dataSource; } }
|
好吧,他直接根据bean name, 直接set了DataSource
,但尼玛这代码怎么封装的这么蛋疼!!
我的理解,既然sqlMapClient
, 已经配置了DataSource
为什么我把sqlMapClient
set到SqlMapClientTemplate
的时候他应该这么写
1 2 3 4 5 6 7
| public class SqlMapClientTemplate extends JdbcAccessor implements SqlMapClientOperations {
public void setSqlMapClient(SqlMapClient sqlMapClient) { this.sqlMapClient = sqlMapClient; this.dataSource = sqlMapCient.getDataSource(); } }
|
表示他竟然强制逼我再在他里面配置一便DataSource
,真是醉了。。。。
好吧,总结下,写代码,切勿急躁 以及,有些代码封装的真的很蛋疼,一定要看源码。