今天突然想到,学习一下SSM框架多数据源配置问题,于是上网查了查,发现配置都很简单,这里就不做过多的讲解了,说一下,我遇到的问题
就一个问题,配置按照网上说的配置了之后,测试N遍还是调用的默认的数据库
问什么?
查了半天时间,一直追查到底层才发现,自己配置没有完全配置好,哪里没配置好呢?
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dynamicDataSource" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:zkwyht/com/mapper/*.xml"></property>
</bean>
这个熟悉SSM的都应该知道,不做过多解释,回到原话,哪里没配置好呢,就是这个 <property name="dataSource" ref="dynamicDataSource" /> 这里的ref,
原本我的ref调用的是dataSource,也就是默认的数据库,而dynamicDataSource这里才是多数据源的配置
<bean id="dynamicDataSource" class="zkwyht.com.utils.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- 指定lookupKey和与之对应的数据源 -->
<entry key="dataSource" value-ref="dataSource"></entry>
<entry key="dataSource2" value-ref="dataSource2"></entry>
</map>
</property>
<!-- 这里可以指定默认的数据源 -->
<property name="defaultTargetDataSource" ref="dataSource" />
</bean>
也就是为什么我们一直测试调用的都是默认的原因
网上说的很多事务需要在AOP控制,优先调用AOP等,多添加一个新数据库的事务等,其实这些都没错,但是和一直调用默认的数据库关系不算大,为什么呢?
你自己这样配置好之后,你可以试试把事务关掉,发现并没多大影响,因为问题的源头不一样(当然我也是慢慢看着这些大神的摸索到最后这个原理)
讲下原理:这个从SSM项目启动的第一步开始,
第一步:SSM项目启动优先执行web.xml,里面有SSM配置的执行顺序(和这个问题关系不大,正常配置顺序即可)
第二步:当它运行到spring-db.xml(连接数据库的xml),这里会从上往下执行,而你里面配置的假如是多个,其实它也记录下来了,
第三步:当程序执行的时候,与数据库交互的时候,它把记录下来的连接方式,信息等开始进行连接,后面就是增删改查了
而最重要的是,它只是记录了,而去调那个,或者怎么调,却是在spring-db.xml里面的(为了方便,多粘贴一下)
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" scope="prototype">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/zkwy" />
<property name="username" value="root" /> <!-- root-->
<property name="password" value="openq11" />
<property name="initialSize" value="0"></property>
<property name="maxActive" value="100"></property>
<property name="maxIdle" value="100"></property>
<property name="minIdle" value="1"></property>
<property name="maxWait" value="60000"></property>
</bean>
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" scope="prototype">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/baoxian" />
<property name="username" value="root" /> <!-- root-->
<property name="password" value="openq11" />
<property name="initialSize" value="0"></property>
<property name="maxActive" value="100"></property>
<property name="maxIdle" value="100"></property>
<property name="minIdle" value="1"></property>
<property name="maxWait" value="60000"></property>
</bean>
<bean id="dynamicDataSource" class="zkwyht.com.utils.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<!-- 指定lookupKey和与之对应的数据源 -->
<entry key="dataSource" value-ref="dataSource"></entry>
<entry key="dataSource2" value-ref="dataSource2"></entry>
</map>
</property>
<!-- 这里可以指定默认的数据源 -->
<property name="defaultTargetDataSource" ref="dataSource" />
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dynamicDataSource" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:zkwyht/com/mapper/*.xml"></property>
</bean>
这里来决定调那个,也就是说,当你的项目运行的时候,项目就通过这段代码 <property name="dataSource" ref="dynamicDataSource" />
来决定调那个数据库了,而当我们配置成这样的时候,项目就不确定调那个数据库了,需要你
@Override
protected Object determineCurrentLookupKey() {
// 从自定义的位置获取数据源标识
//System.out.println(DynamicDataSourceHolder.getDataSource());
return DynamicDataSourceHolder.getDataSource();
}
这段代码来告诉他,去执行那个数据库信息
所以,最终的解决方法是要从
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dynamicDataSource" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:zkwyht/com/mapper/*.xml"></property>
</bean>
这里来入手,它才是控制数据库连接的关键,其它是为了给他提供数据库信息等而产生的
所以本人学习的时候,测试了N遍,项目也不报错,但就是无法灵活切换数据源,一直死调默认的数据源的解决原因(还是对SSM运行流程,运行方式不清楚的原因,实力问题)
希望有人碰到这类相同的问题,可以少走一些弯路,顺便自己也记下来,方便回顾,哈哈