第八章 springboot + mybatis + 多数据源2(解决循环引用)
解决了循环引用
1.application.properties
#the first datasource jdbc.names:1,2 jdbc1.driverClassName = com.mysql.jdbc.Driver jdbc1.url = jdbc:mysql://192.168.37.102:3306/demo_ds_1?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8 jdbc1.username = root jdbc1.password = root #the second datasource jdbc2.driverClassName = com.mysql.jdbc.Driver jdbc2.url = jdbc:mysql://192.168.37.102:3306/demo_ds_2?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8 jdbc2.username = root jdbc2.password = root mybatis.typeAliasesPackage=com.example.abstractroutingdatasource.entity mybatis.mapperLocations:classpath*:mapper/*.xml //在resource文件夹下
2.MyBatisConfig
package com.example.abstractroutingdatasource.config; import com.alibaba.druid.pool.DruidDataSourceFactory; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import org.springframework.context.annotation.Primary; import org.springframework.core.env.Environment; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import javax.sql.DataSource; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; /** * springboot集成mybatis的基本入口 1)创建数据源(如果采用的是默认的tomcat-jdbc数据源,则不需要) * 2)创建SqlSessionFactory 3)配置事务管理器,除非需要使用事务,否则不用配置 */ @Configuration // 该注解类似于spring配置文件 @MapperScan(basePackages = "com.example.abstractroutingdatasource.mapper") public class MyBatisConfig3 { @Autowired private Environment env; /** * @Primary 该注解表示在同一个接口有多个实现类可以注入的时候,默认选择哪一个,而不是让@autowire注解报错 * @Qualifier 根据名称进行注入,通常是在具有相同的多个类型的实例的一个注入(例如有多个DataSource类型的实例) */ @Bean @Primary //此方法的解决了循环引用 public DynamicDataSource dataSource() throws Exception { Map<Object, Object> targetDataSources = new HashMap<>(); String jdbcNames=env.getProperty("jdbc.names"); for (String s:jdbcNames.split(",")) { Properties props = new Properties(); props.put("driverClassName", env.getProperty("jdbc"+s+".driverClassName")); props.put("url", env.getProperty("jdbc"+s+".url")); props.put("username", env.getProperty("jdbc"+s+".username")); props.put("password", env.getProperty("jdbc"+s+".password")); targetDataSources.put(s,DruidDataSourceFactory.createDataSource(props) ); } DynamicDataSource dataSource = new DynamicDataSource(); dataSource.setTargetDataSources(targetDataSources);// 该方法是AbstractRoutingDataSource的方法 dataSource.setDefaultTargetDataSource(targetDataSources.get("1"));// 默认的datasource设置为myTestDbDataSource return dataSource; } /** * 根据数据源创建SqlSessionFactory */ // @Bean // public SqlSessionFactory sqlSessionFactory(@Qualifier("myTestDbDataSource") DataSource myTestDbDataSource, // @Qualifier("myTestDb2DataSource") DataSource myTestDb2DataSource) throws Exception{ // SqlSessionFactoryBean fb = new SqlSessionFactoryBean(); // fb.setDataSource(this.dataSource(myTestDbDataSource, myTestDb2DataSource)); // fb.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage")); // fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapperLocations"))); // return fb.getObject(); // } @Bean public SqlSessionFactory sqlSessionFactory(DynamicDataSource dataSource) throws Exception{ SqlSessionFactoryBean fb = new SqlSessionFactoryBean(); fb.setDataSource(dataSource); fb.setTypeAliasesPackage(env.getProperty("mybatis.typeAliasesPackage")); fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapperLocations"))); return fb.getObject(); } /** * 配置事务管理器 */ @Bean public DataSourceTransactionManager transactionManager(DynamicDataSource dataSource) throws Exception { return new DataSourceTransactionManager(dataSource); } }