手记

spring boot(四) 多数据源

前言

       前一篇中我们使用spring boot+mybatis创建了单一数据源,其中单一数据源不需要我们自己手动创建,spring boot自动配置在程序启动时会替我们创建好数据源。

准备工作

application.yml中配置connection的4个属性

spring:  
  datasource:    
    read:   
      driver-class-name: com.mysql.jdbc.Driver      
      url: jdbc:mysql://192.168.80.129:3306/test      
      username: root      
      password: 123456    
    write:      
      driver-class-name: com.mysql.jdbc.Driver      
      url: jdbc:mysql://192.168.80.129:3306/test      
      username: root      
      password: 123456


举个栗子

      1、多数据源主要是需要我们手动来创建DataSource、SqlSessionFactory、SqlSessionTemplate。这里我们基于同一个库来创建读写分离的数据源。这里两个方法的返回值都是javax.sql.DataSource。

@Configuration
public class DataSourceConfig {      
@Primary    
@Bean(name="readDataSource")    
@ConfigurationProperties(prefix = "spring.datasource.read")    
public DataSource readDataSource(){        
   return DataSourceBuilder.create().build();    
}       

@Bean(name="writeDataSource")    
@ConfigurationProperties(prefix = "spring.datasource.write")    
public DataSource writeDataSource(){        
   return DataSourceBuilder.create().build();    
}  
}

     2、读写分离的配置类。也就是分别创建读写的SqlSessionFactory和SqlSessionTemplate

@Configuration
@MapperScan(basePackages = {"com.zhangfei.dao.read"},sqlSessionFactoryRef = "readSqlSessionFactory")
public class MyBatisDbAConfig {     
   @Autowired    
   @Qualifier("readDataSource")    
   private DataSource dataSource;      
   
   @Bean    
   public SqlSessionFactory readSqlSessionFactory() throws Exception{        
        SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();        
        sqlSessionFactoryBean.setDataSource(dataSource);         
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();        
        Resource[] resource=resolver.getResources("classpath:mybatis/read/*.xml");        
        sqlSessionFactoryBean.setMapperLocations(resource);         
        return sqlSessionFactoryBean.getObject();   
   }     
   @Bean    
   public SqlSessionTemplate readSqlSession() throws Exception{        
       SqlSessionTemplate sqlSessionTemplate=new SqlSessionTemplate(readSqlSessionFactory());        
       return sqlSessionTemplate;   
      }
   }
@Configuration
@MapperScan(basePackages = {"com.zhangfei.dao.write"},sqlSessionFactoryRef = "writeSqlSessionFactory")
public class MyBatisDbBConfig {     
   @Autowired    
   @Qualifier("writeDataSource")    
   private DataSource dataSource;      
   @Bean    
   public SqlSessionFactory writeSqlSessionFactory() throws Exception{        
      SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();        
      sqlSessionFactoryBean.setDataSource(dataSource);         
      PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();        
      Resource[] resource=resolver.getResources("classpath:mybatis/write/*.xml");        
      sqlSessionFactoryBean.setMapperLocations(resource);         
      return sqlSessionFactoryBean.getObject();    
      }     
      @Bean    
      public SqlSessionTemplate writeSqlSession() throws Exception{        
      SqlSessionTemplate sqlSessionTemplate=new SqlSessionTemplate(writeSqlSessionFactory());         
      return sqlSessionTemplate;    
      } 
 }

      3、read包下的dao接口

public interface StudentReadDao {     
   List<Student> getStudentList();     
   Student getById(long id); 
 }

     4、wite包下的dao接口

public interface StudentWriteDao {     
    int delete(long id);     
    int insert(Student student);     
    int update(Student student);  
}

    5、分别创建读写的mapper文件。我本地分别创建了:

resources/mybatis/read/studentdao.xml、

/resources/mybatis/write/studentdao.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        " 
<mapper namespace="com.zhangfei.dao.read.StudentReadDao">    
<select id="getStudentList" resultType="com.zhangfei.entity.Student">        
select * from student;    
</select>     
<select id="getById" resultType="com.zhangfei.entity.Student">        
select * from student where id=#{id};    
</select>  
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        " 
<mapper namespace="com.zhangfei.dao.write.StudentWriteDao">     
 <insert id="insert" parameterType="com.zhangfei.entity.Student">       
 insert into student (name,age) values (#{name},#{age})    
 </insert>     
 <update id="update" parameterType="com.zhangfei.entity.Student">        
 update student set name=#{name},age=#{age} where id=#{id}    
 </update>     
 <delete id="delete" parameterType="long">        
 delete from student where id=#{id}    
 </delete>
 </mapper>

OK。以上几部就搞定了读写分离的准备工作,接着就可以在controller里调用了。 准备工作完成后,还有重要的一点就是需要在程序入口处排除springboot自动属性提供的数据源  @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

@RestController@RequestMapping("/student")
public class StudentController {      
@Autowired    
StudentReadDao studentDao;     
@GetMapping("/getbyid/{id}/")    
public Student getById(@PathVariable("id")long id){         
Student student=studentDao.getById(id);        
return student;    
}      
@GetMapping("/all/")    
public List<Student> getAll(){        
return studentDao.getStudentList();   
 }  
 }

总结

       好了,基本上又是3分钟就搞定了SpringBoot+MyBatis多数据源或者叫做读写分离的工作。那么不知道你又没有反问我们手动创建的DataSource具体类型是什么呢? 这里我们在这里只写了javax.sql.DataSource接口。 我本地用的是springboot 2.0.2 ,当前 DataSourceBuilder 只支持3种类型的数据源: com.zaxxer.hikari.HikariDataSource、org.apache.tomcat.jdbc.pool.DataSource、org.apache.commons.dbcp2.BasicDataSource。可以在DataSourceBuilder类中看到相关代码。那么现在这种情况因为我们引用的内嵌tomcat,所以我们这里返回的数据源类型是org.apache.tomcat.jdbc.pool.DataSource。 可以用instanceof验证一下具体的数据源类型。

1人推荐
随时随地看视频
慕课网APP

热门评论

这个没有事务管理器吗?不需要在service层通过@Transactional(value = "bbb")来切换对应的事物管理来实现数据源切换?

直接通过mapperscan对应的包下面就使用对应的数据源吗

查看全部评论