Spring+SpringMVC+Mybatis 多数据源整合
1、本文采用spring-4.2.3 + springmvc +mybatis-3.3.0 来实现多数据源整合
拷贝对应的jar文件
2.写一个数据库切换的工具类:DataSourceContextHolder,用来切换数据库
public class DataSourceContextHolder { public static final String DATA_SOURCE_DEFAULT = "defaultDataSource"; public static final String DATA_SOURCE_NEW = "newDataSource"; private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static void setDbType(String dbType) { contextHolder.set(dbType); } public static String getDbType() { return contextHolder.get(); } }3、写一个DynamicDataSource(类名随意) 继承 AbstractRoutingDataSource 并重写 determineCurrentLookupKey()方法来实现动态数据源切换
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource{ @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDbType(); } }
4、修改database.properties如下
default.jdbc.driver = com.mysql.jdbc.Driver default.jdbc.url = jdbc:mysql://localhost:3306/temp?characterEncoding=UTF-8 default.jdbc.username = root default.jdbc.password = root newA.jdbc.driver = com.mysql.jdbc.Driver newA.jdbc.url = jdbc:mysql://localhost:3306/tempb?characterEncoding=UTF-8 newA.jdbc.username = root newA.jdbc.password = root
5、创建applicationContext-dao.xml 配置数据源
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--获取数据库配置文件--> <context:property-placeholder location="classpath:config/database.properties"/> <!--设置数据源c3p0--> <bean id="defaultDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${default.jdbc.driver}"/> <property name="jdbcUrl" value="${default.jdbc.url}"/> <property name="user" value="${default.jdbc.username}"/> <property name="password" value="${default.jdbc.password}"/> <property name="maxPoolSize" value="50"/> <property name="minPoolSize" value="2"/> <property name="maxIdleTime" value="60"/> </bean> <bean id="newDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${newA.jdbc.driver}"/> <property name="jdbcUrl" value="${newA.jdbc.url}"/> <property name="user" value="${newA.jdbc.username}"/> <property name="password" value="${default.jdbc.password}"/> <property name="maxPoolSize" value="50"/> <property name="minPoolSize" value="2"/> <property name="maxIdleTime" value="60"/> </bean> <!-- 动态配置数据源 --> <bean id="dynamicDataSource" class="com.ssm.config.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <entry value-ref="defaultDataSource" key="defaultDataSource" /> <entry value-ref="newDataSource" key="newDataSource" /> </map> </property> <!-- 默认使用defaultDataSource的数据源 --> <property name="defaultTargetDataSource" ref="defaultDataSource" /> </bean> <!--sqlsessionFactory bean,配置session工厂 --> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 定义数据源,数据源使用动态的数据源dynamicDataSource --> <property name="dataSource" ref="dynamicDataSource" /> <property name="configLocation" value="classpath:config/mybatis/MybatisConfig.xml"/> </bean> <!--自动扫描mapper接口,并注入sqlsession--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 自动扫描mapping.xml文件 --> <property name="basePackage" value="com.ssm.mapper"/> <property name="sqlSessionFactoryBeanName" value="sqlSession"/> </bean> </beans>6、创建applicationContext-transaction.xml 配置AOP以及事物、事物的传播性
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dynamicDataSource"/> </bean> <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager"> <tx:attributes> <tx:method name="find*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="add*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- 把事务边界定在service层 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.ssm.service.serviceImpl.*.*(..))"/> </aop:config> </beans>7、在tempb数据库创建一个测试表(TempUser),用generatorConfig生成对应的entity类和映射文件。
public class TempUser { private Integer id; private String name; private Integer age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name == null ? null : name.trim(); } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "TempUser{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } }
8、在 Controller 里编写对应的方法 . 注意:每次访问数据库时必须切换到对应的数据库,这里的名字(DATA_SOURCE_DEFAULT = "defaultDataSource")一定要和applicationContext-dao.xml里面配置的数据源的名称一样
@RequestMapping(value = "/test") public Map<String, Object> example() { //切换数据库(temp) temp数据库是默认数据库,第一次访问可以不用切换 DataSourceContextHolder.setDbType(DataSourceContextHolder.DATA_SOURCE_DEFAULT); User user = userService.selectByUserName("user"); System.out.println(user); //切换数据库(tempb) DataSourceContextHolder.setDbType(DataSourceContextHolder.DATA_SOURCE_NEW); TempUser t = tempUserServcie.selectByPrimaryKey(1); return null; }
开启服务访问 localhost:8080/test 就可以访问了