spring boot 配置MyBatis,支持多个数据源和分页插件

spring boot中的MyBatis配置是比较复杂的。

下面总结针对mySql数据库的配置和使用的详细过程(有两个数据库:名字为test和my_db):


1、引入依赖:

pom.xml文件中,添加:

[html] view plain copy
  1. <!-- Begin of DB related -->  
  2.     <dependency> <!-- for ChainedTransactionManager configuration -->  
  3.         <groupId>org.springframework.data</groupId>  
  4.         <artifactId>spring-data-commons</artifactId>  
  5.     </dependency>  
  6.     <dependency> <!-- exclude掉缺省的jdbc配置 -->  
  7.         <groupId>org.springframework.boot</groupId>  
  8.         <artifactId>spring-boot-starter-jdbc</artifactId>  
  9.         <exclusions>  
  10.             <exclusion>  
  11.                 <groupId>org.apache.tomcat</groupId>  
  12.                 <artifactId>tomcat-jdbc</artifactId>  
  13.             </exclusion>  
  14.         </exclusions>  
  15.     </dependency>  
  16.     <dependency>  
  17.         <groupId>org.mybatis</groupId>  
  18.         <artifactId>mybatis</artifactId>  
  19.         <version>3.4.0</version>  
  20.     </dependency>  
  21.     <dependency>  
  22.         <groupId>org.mybatis</groupId>  
  23.         <artifactId>mybatis-spring</artifactId>  
  24.         <version>1.3.0</version>  
  25.     </dependency>  
  26.     <dependency> <!-- 连接池 -->  
  27.         <groupId>com.zaxxer</groupId>  
  28.         <artifactId>HikariCP</artifactId>  
  29.     </dependency>  
  30.     <dependency>  
  31.         <groupId>mysql</groupId>  
  32.         <artifactId>mysql-connector-java</artifactId>  
  33.     </dependency>  
  34.     <dependency> <!-- mybatis 分页插件 -->  
  35.         <groupId>com.github.pagehelper</groupId>  
  36.         <artifactId>pagehelper</artifactId>  
  37.         <version>4.1.6</version>  
  38.     </dependency>       
  39. <!-- End of DB related -->  

2、开始配置:

2.1、在application.yml中定义mySql的ip和port,以方便以后使用不同的profile来区分不同的环境(development, test, production):

[html] view plain copy
  1. server:  
  2.   port: 8081  
  3.   
  4. mysql:  
  5.   ipPort: localhost:3306  


2.2、为两个数据库定义annotation,用于注解dao类,以使dao类可以找到自己所对应的数据库:

[java] view plain copy
  1. /** 
  2.  * test库数据源 
  3.  * 使用方法:在DAO层interface中使用这个注解 
  4.  * 
  5.  */  
  6. public @interface TestRepository {  
  7.   
  8. }  

[java] view plain copy
  1. /** 
  2.  * my_db库数据源 
  3.  * 使用方法:在DAO层interface中使用这个注解 
  4.  * 
  5.  */  
  6. public @interface MyDbRepository {  
  7.   
  8. }  


2.3、配置DataSource、SqlSessionFactory和Transaction Manager:

[java] view plain copy
  1. /** 
  2.  * DataSource、SqlSessionFactory和Transaction Manager 配置 
  3.  * @author XuJijun 
  4.  * 
  5.  */  
  6. @Configuration  
  7. @EnableTransactionManagement  
  8. public class MyBatisConfig implements TransactionManagementConfigurer{  
  9.     private final static Logger logger = LoggerFactory.getLogger(MyBatisConfig.class);  
  10.   
  11.     //数据库连接相关的参数:  
  12.     private String driverClassName = "com.mysql.jdbc.Driver";  
  13.     @Value("${mysql.ipPort}"private String jdbcIpPort; //从配置文件中获取  
  14.     private String jdbcUrl = "jdbc:mysql://%s/%s?useUnicode=true&characterEncoding=UTF-8";  
  15.     private String userName = "root";  
  16.     private String password = "123456";  
  17.       
  18.     //连接池相关的参数:  
  19.     //等待从连接池中获得连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 缺省:30秒  
  20.     private long connectionTimeout = 30000;  
  21.     //一个连接idle状态的最大时长(毫秒),超时则被释放(retired),缺省:10分钟  
  22.     private long idleTimeout = 600000;  
  23.     //一个连接的生命时长(毫秒),超时而且没被使用则被释放(retired),缺省:30分钟,建议设置比数据库超时时长少30秒以上,  
  24.     //参考MySQL wait_timeout参数(show variables like '%timeout%';)  
  25.     private long maxLifetime = 1765000;  
  26.     //连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count)  
  27.     private int maximumPoolSize = 15;  
  28.       
  29.     /** 
  30.      * 配置dataSource,使用Hikari连接池  
  31.      */  
  32.     @Bean(destroyMethod = "close")  
  33.     @Primary  
  34.     public DataSource dataSource1(){  
  35.         HikariConfig config = new HikariConfig();  
  36.         config.setDriverClassName(driverClassName);  
  37.         config.setJdbcUrl(String.format(jdbcUrl, jdbcIpPort, "test"));  
  38.         config.setUsername(userName);  
  39.         config.setPassword(password);  
  40.         config.setConnectionTimeout(connectionTimeout);   
  41.         config.setIdleTimeout(idleTimeout);  
  42.         config.setMaxLifetime(maxLifetime);  
  43.         config.setMaximumPoolSize(maximumPoolSize);  
  44.           
  45.         HikariDataSource ds = new HikariDataSource(config);  
  46.         return ds;  
  47.     }  
  48.   
  49.     @Bean(destroyMethod = "close")    
  50.     public DataSource dataSource2(){  
  51.         HikariConfig config = new HikariConfig();  
  52.         config.setDriverClassName(driverClassName);  
  53.         config.setJdbcUrl(String.format(jdbcUrl, jdbcIpPort, "my_db"));  
  54.         config.setUsername(userName);  
  55.         config.setPassword(password);  
  56.         config.setConnectionTimeout(connectionTimeout);  
  57.         config.setIdleTimeout(idleTimeout);  
  58.         config.setMaxLifetime(maxLifetime);  
  59.         config.setMaximumPoolSize(maximumPoolSize);  
  60.           
  61.         HikariDataSource ds = new HikariDataSource(config);  
  62.         return ds;  
  63.     }  
  64.   
  65.     /** 
  66.      * 配置SqlSessionFactory: 
  67.      * - 创建SqlSessionFactoryBean,并指定一个dataSource; 
  68.      * - 设置这个分页插件:https://github.com/pagehelper/Mybatis-PageHelper; 
  69.      * - 指定mapper文件的路径; 
  70.      */  
  71.     @Bean  
  72.     public SqlSessionFactory sqlSessionFactory1() {  
  73.           
  74.         SqlSessionFactoryBean bean = new SqlSessionFactoryBean();  
  75.         bean.setDataSource(dataSource1());  
  76.           
  77.         //分页插件  
  78.         PageHelper pageHelper = new PageHelper();  
  79.         Properties properties = new Properties();  
  80.         properties.setProperty("dialect""mysql");  
  81.         properties.setProperty("reasonable""false");  
  82.         properties.setProperty("pageSizeZero""true");  
  83.         pageHelper.setProperties(properties);  
  84.         bean.setPlugins(new Interceptor[]{pageHelper});  
  85.           
  86.         try {  
  87.             //指定mapper xml目录  
  88.             ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();  
  89.             bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));  
  90.             return bean.getObject();  
  91.         } catch (Exception e) {  
  92.             logger.error(e.getMessage(), e);  
  93.             throw new RuntimeException(e);  
  94.         }  
  95.     }  
  96.       
  97.     @Bean  
  98.     public SqlSessionFactory sqlSessionFactory2() {  
  99.           
  100.         SqlSessionFactoryBean bean = new SqlSessionFactoryBean();  
  101.         bean.setDataSource(dataSource2());  
  102.           
  103.         //分页插件  
  104.         PageHelper pageHelper = new PageHelper();  
  105.         Properties properties = new Properties();  
  106.         properties.setProperty("dialect""mysql");  
  107.         properties.setProperty("reasonable""false");  
  108.         properties.setProperty("pageSizeZero""true");  
  109.         pageHelper.setProperties(properties);  
  110.         bean.setPlugins(new Interceptor[]{pageHelper});  
  111.           
  112.         try {  
  113.             //指定mapper xml目录  
  114.             ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();  
  115.             bean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));  
  116.             return bean.getObject();  
  117.         } catch (Exception e) {  
  118.             logger.error(e.getMessage(), e);  
  119.             throw new RuntimeException(e);  
  120.         }  
  121.     }  
  122.       
  123.       
  124.     /**  
  125.      * Transaction 相关配置  
  126.      * 因为有两个数据源,所有使用ChainedTransactionManager把两个DataSourceTransactionManager包括在一起。  
  127.      */  
  128.     @Override  
  129.     public PlatformTransactionManager annotationDrivenTransactionManager() {  
  130.         DataSourceTransactionManager dtm1 = new DataSourceTransactionManager(dataSource1());  
  131.         DataSourceTransactionManager dtm2 = new DataSourceTransactionManager(dataSource2());  
  132.   
  133.         ChainedTransactionManager ctm = new ChainedTransactionManager(dtm1, dtm2);  
  134.         return ctm;  
  135.     }  
  136.   
  137. }  

2.4、配置MyBatis Mapper Scanner:

[java] view plain copy
  1. /** 
  2.  * 配置MyBatis Mapper Scanner 
  3.  * @author XuJijun 
  4.  * 
  5.  */  
  6. @Configuration  
  7. @AutoConfigureAfter(MyBatisConfig.class)  
  8. public class MyBatisMapperScannerConfig {  
  9.   
  10.     /** 
  11.      * - 设置SqlSessionFactory; 
  12.      * - 设置dao所在的package路径; 
  13.      * - 关联注解在dao类上的Annotation名字; 
  14.      */  
  15.     @Bean  
  16.     public MapperScannerConfigurer mapperScannerConfigurer1() {  
  17.         MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();  
  18.         mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory1");  
  19.         mapperScannerConfigurer.setBasePackage("com.xjj.dao");  
  20.         mapperScannerConfigurer.setAnnotationClass(TestRepository.class);  
  21.         return mapperScannerConfigurer;  
  22.     }  
  23.   
  24.     @Bean  
  25.     public MapperScannerConfigurer mapperScannerConfigurer2() {  
  26.         MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();  
  27.         mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory2");  
  28.         mapperScannerConfigurer.setBasePackage("com.xjj.dao");  
  29.         mapperScannerConfigurer.setAnnotationClass(MyDbRepository.class);  
  30.         return mapperScannerConfigurer;  
  31.     }  
  32.       
  33. }  


3、使用

3.1、定义一个实体类Person(略):

3.2、定义Dao:

spring boot 配置MyBatis,支持多个数据源和分页插件

3.3、定义mapper(如有需要):

spring boot 配置MyBatis,支持多个数据源和分页插件


4、测试:

4.1、单元测试代码:

spring boot 配置MyBatis,支持多个数据源和分页插件

4.1、测试结果:

spring boot 配置MyBatis,支持多个数据源和分页插件

结果表明:已经配置成功,并可以正常使用。spring boot 配置MyBatis,支持多个数据源和分页插件

源代码:https://github.com/xujijun/my-spring-boot