Spring Boot + Mybatis configure multiple data sources
- Mybatis blocker, turn the field name in uppercase lowercase
package com.sgcc.tysj.s.common.mybatis; import java.sql.Statement; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Properties; import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.plugin.Intercepts; import org.apache.ibatis.plugin.Invocation; import org.apache.ibatis.plugin.Plugin; import org.apache.ibatis.plugin.Signature; import org.springframework.stereotype.Component; @Component @Intercepts({ @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = { Statement.class }) }) public class MybatisResultSetSIntercept implements Interceptor { public Object intercept(Invocation invocation) throws Throwable { Object result = invocation.proceed(); //执行请求方法,并将所得结果保存到result中 if (result instanceof ArrayList) { ArrayList<?> resultList = (ArrayList<?>) result; if(resultList.size()>0&&resultList.get(0) instanceof Map ) { List<Map<String,Object>> resList = new ArrayList<Map<String,Object>>(); for (int i = 0; i < resultList.size(); i++) { if (resultList.get(i) instanceof Map) { Map<String, Object> nmap=new LinkedHashMap<String, Object>(); @SuppressWarnings("unchecked") Map <String, Object>map = (Map<String, Object>) ResultList.get (I); for (String Key: map.keySet ()) nmap.put (key.toLowerCase (), as map.get (Key)); resList.add (nmap); } } return resList; } } return Result; } public Object plugin (Object target) { // read @Signature configuration, determine the need to generate a proxy class iF (target the instanceof ResultSetHandler) { return Plugin.wrap (target, the this ); } the else { return target; } } public void setProperties(Properties properties) { } }
- A data source
package com.sgcc.tysj.p.pinggao.config; import com.sgcc.tysj.s.common.mybatis.MybatisResultSetSIntercept; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; importorg.springframework.boot.context.properties.ConfigurationProperties; Import org.springframework.context.annotation.Bean; Import org.springframework.context.annotation.Configuration; Import org.springframework.context.annotation.Primary; Import org.springframework. core.io.support.PathMatchingResourcePatternResolver; Import org.springframework.jdbc.datasource.DataSourceTransactionManager; Import the javax.sql.DataSource; / ** * @Description: default data source * @author : tangsw * @date: 2019/11/18 23:20 * / // indicates that the class is a class configuration @Configuration // 配置mybatis的接口类放的地方 @MapperScan(basePackages = "com.sgcc.tysj.p.pinggao.**.dao", sqlSessionTemplateRef = "db1SqlSessionTemplate") public class DatabaseConfigForSystem { @Value("${spring.datasource.system.driver-class-name}") private String driverClassName; @Value("${spring.datasource.system.url}") private String url; @Value("${spring.datasource.system.username}") private String username; @Value("${spring.datasource.system.password}") private String password; @Value("${spring.datasource.system.test-on-borrow}") private boolean testOnBorrow; @Value("${spring.datasource.system.test-while-idle}") private boolean testWhileIdle; @Value("${spring.datasource.system.validation-query}") private String validationQuery; @Value("${spring.datasource.system.maxIdle}") private int maxIdle; @Value("${spring.datasource.system.minIdle}") private int minIdle; @Value("${spring.datasource.system.initialSize}") private int initialSize; @Value("${spring.datasource.system.maxActive}") private int maxActive; @Value("${spring.datasource.system.timeBeteenEvictionRunsMillis}") private int timeBetweenEvictionRunsMillis; @Value("${spring.datasource.system.minEvictableIdelTimeMillis}") private int minEvictableIdelTimeMillis; @Value("${spring.datasource.system.maxWait}") private int maxWait; @Autowired privateMybatisResultSetSIntercept MybatisResultSetSIntercept; // this object into Spring container @Bean (name = "db1DataSource" ) // indicating that the data source is the default data source @Primary // read the configuration parameters in application.properties mapped to an object, prefix represents a prefix parameter @ConfigurationProperties (prefix = "spring.datasource.system" ) public the DataSource getDateSource1 () { org.apache.tomcat.jdbc.pool.DataSource the dataSource = new new org.apache.tomcat.jdbc.pool.DataSource ( ); dataSource.setDriverClassName (driverClassName); dataSource.setUrl (URL); dataSource.setUsername (username); dataSource.setPassword (password); dataSource.setMaxActive (for maxActive); dataSource.setMinIdle (minIdle); dataSource.setMaxIdle (maxIdle); dataSource.setTestOnBorrow (testOnBorrow); dataSource.setTestWhileIdle (testWhileIdle); dataSource.setValidationQuery (validationQuery); dataSource.setTimeBetweenEvictionRunsMillis (timeBetweenEvictionRunsMillis); the dataSource .setMinEvictableIdleTimeMillis (minEvictableIdelTimeMillis); dataSource.setInitialSize (initialSize); dataSource.setMaxWait (maxWait); return the dataSource; } @Bean (name = "db1SqlSessionFactory" ) // indicating that the data source is the default data source @Primary // @Qualifier A lookup Spring container object named db1DataSource public a SqlSessionFactory db1SqlSessionFactory (@Qualifier ( "db1DataSource" ) the DataSource DataSource) throws Exception { the SqlSessionFactoryBean the bean = new new the SqlSessionFactoryBean (); org.apache.ibatis.session.Configuration Configuration = new new org.apache.ibatis.session.Configuration (); // if the field is empty, return null configuration.setCallSettersOnNulls ( to true ); bean.setConfiguration (Configuration); // call interceptor Mybatis bean.setPlugins ( new new Interceptor [] {} mybatisResultSetSIntercept); bean.setDataSource (DataSource); bean.setMapperLocations ( // set mybatis xml position where new new PathMatchingResourcePatternResolver () getResources ( "CLASSPATH:. Mappings / tysj / P / pinggao / . * / * XML " )); return bean.getObject (); } / ** * configuration transaction manager * / @Bean (name =" db1TransactionManager " ) @Primary public DataSourceTransactionManager db1TransactionManager (@Qualifier (" db1DataSource " ) the DataSource the dataSource ) { return new new DataSourceTransactionManager(dataSource); } @Bean(name = "db1SqlSessionTemplate") @Primary public SqlSessionTemplate db1SqlSessionTemplate(@Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
- Data Source Based
package com.sgcc.tysj.p.pinggao.config; import com.sgcc.tysj.s.common.mybatis.MybatisResultSetSIntercept; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; importorg.springframework.boot.context.properties.ConfigurationProperties; Import org.springframework.context.annotation.Bean; Import org.springframework.context.annotation.Configuration; Import org.springframework.core.io.support.PathMatchingResourcePatternResolver; Import ORG. springframework.jdbc.datasource.DataSourceTransactionManager; Import the javax.sql.DataSource; / ** * @Description: the WebService interface this data source * @author : tangsw * @date: 2019/11/18 23:20 * / // represents this class is a class configuration @Configuration // configuration interface class put mybatis place @MapperScan(basePackages = "com.sgcc.tysj.p.pinggao_ws.erp.dao", sqlSessionTemplateRef = "db2SqlSessionTemplate") public class DatabaseConfigForWebService { @Value("${spring.datasource.webService.driver-class-name}") private String driverClassName; @Value("${spring.datasource.webService.url}") private String url; @Value("${spring.datasource.webService.username}") private String username; @Value("${spring.datasource.webService.password}") private String password; @Value("${spring.datasource.webService.test-on-borrow}") private boolean testOnBorrow; @Value("${spring.datasource.webService.test-while-idle}") private boolean testWhileIdle; @Value("${spring.datasource.webService.validation-query}") private String validationQuery; @Value("${spring.datasource.webService.maxIdle}") private int maxIdle; @Value("${spring.datasource.webService.minIdle}") private int minIdle; @Value("${spring.datasource.webService.initialSize}") private int initialSize; @Value("${spring.datasource.webService.maxActive}") private int maxActive; @Value("${spring.datasource.webService.timeBeteenEvictionRunsMillis}") private int timeBetweenEvictionRunsMillis; @Value("${spring.datasource.webService.minEvictableIdelTimeMillis}") private int minEvictableIdelTimeMillis; @Value("${spring.datasource.webService.maxWait}") private int maxWait; @Autowired Private MybatisResultSetSIntercept mybatisResultSetSIntercept; // this object into Spring container @Bean (name = "db2datasource" ) // indicating that the data source is the default data source // a configuration parameter object read mapping becomes application.properties prefix, prefix parameter indicating the @ConfigurationProperties (prefix = "spring.datasource.webService" ) public the DataSource getDateSource2 () { org.apache.tomcat.jdbc.pool.DataSource the dataSource = new new org.apache.tomcat.jdbc.pool.DataSource (); dataSource.setDriverClassName (driverClassName); dataSource.setUrl (URL); dataSource.setUsername (username); dataSource.setPassword (password); dataSource.setMaxActive (for maxActive); dataSource.setMinIdle (minIdle); dataSource.setMaxIdle (maxIdle); dataSource.setTestOnBorrow (testOnBorrow); dataSource.setTestWhileIdle (testWhileIdle); dataSource.setValidationQuery (validationQuery); dataSource.setTimeBetweenEvictionRunsMillis (timeBetweenEvictionRunsMillis); the dataSource .setMinEvictableIdleTimeMillis (minEvictableIdelTimeMillis); dataSource.setInitialSize (initialSize); dataSource.setMaxWait (maxWait); return the dataSource; } @Bean (name = "db2SqlSessionFactory" ) // indicating that the data source is the default data source // @Qualifier A lookup db2datasource Spring container object named public a SqlSessionFactory db2SqlSessionFactory (@Qualifier ( "db2datasource" ) the DataSource DataSource) throws Exception { the SqlSessionFactoryBean the bean = new new the SqlSessionFactoryBean (); org.apache.ibatis.session.Configuration Configuration = new new org.apache.ibatis.session.Configuration (); // if the field is empty, return null configuration.setCallSettersOnNulls ( to true ); bean.setConfiguration (Configuration); // Mybatis interceptor bean.setPlugins ( new new Interceptor [] {} mybatisResultSetSIntercept); bean.setDataSource (DataSource); bean.setMapperLocations ( // set mybatis xml position where new new PathMatchingResourcePatternResolver () getResources ( "CLASSPATH:. Mappings / tysj / P / pinggao_ws / . ERP / * XML " )); return bean.getObject (); } / ** * configuration transaction manager * / @Bean (name =" db2TransactionManager " ) public DataSourceTransactionManager db2TransactionManager (@Qualifier (" db2datasource " ) the DataSource the dataSource) { return new new DataSourceTransactionManager(dataSource); } @Bean(name = "db2SqlSessionTemplate") public SqlSessionTemplate db2SqlSessionTemplate(@Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
- Connection pool configuration parameters:
# ------------------------------------ WebService interface this data source configuration ------ --------------------------- spring.datasource.webService.url = jdbc: the Oracle: Thin: @ 192.168.10.10: 1521: orcl the Spring Oracle = .datasource.webService.username spring.datasource.webService.password = Oracle spring.datasource.webService.driver oracle.jdbc.OracleDriver-class-name = # The maximum number of connections the database, provided that there is no limitation 0 spring.datasource. = 20 is webService.maxActive # initialization connections spring.datasource.webService.initialSize. 1 = # the maximum number of milliseconds to wait, as the MS unit, over time, an error message will spring.datasource.webService.maxWait = 60000 # minimum idle connection spring.datasource =. 1 .webService.minIdle # maximum idle connection spring.datasource.webService.maxIdle = 20 ## If the current connection pool and then a connection is not used in the timeBetweenEvictionRunsMillis spare time he served, were physically closed off. = 60000 spring.datasource.webService.timeBeteenEvictionRunsMillis # Configure a minimum connection time survival pool milliseconds spring.datasource.webService.minEvictableIdelTimeMillis = 300000 # detect its availability at the time of acquiring the Connection object spring.datasource.webService.test- to true-BORROW = ON # guarantee connection object is obtained from the connection pool available spring.datasource.webService.test-while-idle = true validity verification database connections # spring.datasource.webService.validation-query = select 1 from dual
- Encounter problems:
1. Do not call interceptor Code;
2. Query the database data, if the value is empty, field names will not check out;
3. The system is idle for a period of time without access to prompt "close connection."
- Reference article:
Two kinds of integrated process springboot-mybatis multiple data sources
mybatis multiple data sources stepped pit, database connections are often disconnected problem
Springboot multi data source connection automatically disconnects connection problems
Configuring the springboot call-setters-on-nulls properties of mybatis