本文將講述 spring boot + mybatis + druid 多數據源配置方案。css
CentOs7.3 安裝 MySQL 5.7.19 二進制版本java
代碼我已放到 Github ,導入spring-boot-mybatis
項目mysql
github github.com/souyunku/sp…git
在項目中添加 mybatis,druid
依賴github
點擊預覽 pom.xmlspring
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
省略 更多
複製代碼
@Configuration
@EnableConfigurationProperties(DruidDbProperties.class)
@Import({DruidMonitConfig.class})
public abstract class AbstractDruidDBConfig {
private Logger logger = LoggerFactory.getLogger(AbstractDruidDBConfig.class);
@Resource
private DruidDbProperties druidDbProperties;
public DruidDataSource createDataSource(String url, String username, String password) {
if (StringUtils.isEmpty(url)) {
System.out.println(
"Your database connection pool configuration is incorrect!" + " Please check your Spring profile");
throw new ApplicationContextException("Database connection pool is not configured correctly");
}
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(url);
datasource.setUsername(username);
datasource.setPassword(password);
// datasource.setDriverClassName(
// StringUtils.isEmpty(driverClassName) ?
// druidDbProperties.getDriverClassName() : driverClassName);
datasource.setInitialSize(druidDbProperties.getInitialSize());
datasource.setMinIdle(druidDbProperties.getMinIdle());
datasource.setMaxActive(druidDbProperties.getMaxActive());
datasource.setMaxWait(druidDbProperties.getMaxWait());
datasource.setTimeBetweenEvictionRunsMillis(druidDbProperties.getTimeBetweenEvictionRunsMillis());
datasource.setMinEvictableIdleTimeMillis(druidDbProperties.getMinEvictableIdleTimeMillis());
datasource.setValidationQuery(druidDbProperties.getValidationQuery());
datasource.setTestWhileIdle(druidDbProperties.isTestWhileIdle());
datasource.setTestOnBorrow(druidDbProperties.isTestOnBorrow());
datasource.setTestOnReturn(druidDbProperties.isTestOnReturn());
try {
datasource.setFilters(druidDbProperties.getFilters());
} catch (SQLException e) {
logger.error("druid configuration initialization filter", e);
}
datasource.setConnectionProperties(druidDbProperties.getConnectionProperties());
return datasource;
}
/** * 加載默認mybatis xml配置文件,並初始化分頁插件 * * @param dataSource * @return * @throws Exception */
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
return createSqlSessionFactory(dataSource, "classpath:mybatis/**/*.xml");
}
/** * 加載mybatis xml配置文件,並初始化分頁插件 * * @param dataSource 數據源 * @param mapperLocations 自定義xml配置路徑 * @return * @throws Exception */
public SqlSessionFactory sqlSessionFactory(DataSource dataSource, String mapperLocations) throws Exception {
return createSqlSessionFactory(dataSource, mapperLocations);
}
private SqlSessionFactory createSqlSessionFactory(DataSource dataSource, String mapperLocations) throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
// mybatis分頁
PageHelper pageHelper = new PageHelper();
Properties props = new Properties();
props.setProperty("dialect", "mysql");
props.setProperty("reasonable", "true");
props.setProperty("supportMethodsArguments", "true");
props.setProperty("returnPageInfo", "check");
props.setProperty("params", "count=countSql");
pageHelper.setProperties(props); // 添加插件
sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper});
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mapperLocations));
return sqlSessionFactoryBean.getObject();
}
}
複製代碼
@EnableConfigurationProperties(DruidDbProperties.class)
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DruidMonitConfig {
@Resource
private DruidDbProperties druidDbProperties;
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean reg = new ServletRegistrationBean();
reg.setServlet(new StatViewServlet());
reg.addUrlMappings("/druid/*");
if (!StringUtils.isEmpty(druidDbProperties.getAllow())) {
reg.addInitParameter("allow", druidDbProperties.getAllow()); // 白名單
}
if (!StringUtils.isEmpty(druidDbProperties.getDeny())) {
reg.addInitParameter("deny", druidDbProperties.getDeny()); // 黑名單
}
reg.addInitParameter("loginUsername", druidDbProperties.getUsername());
reg.addInitParameter("loginPassword", druidDbProperties.getPassword());
return reg;
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
/** * 監聽Spring 1.定義攔截器 2.定義切入點 3.定義通知類 * * @return */
@Bean
public DruidStatInterceptor druidStatInterceptor() {
return new DruidStatInterceptor();
}
@Bean
public JdkRegexpMethodPointcut druidStatPointcut() {
JdkRegexpMethodPointcut druidStatPointcut = new JdkRegexpMethodPointcut();
String patterns = "io.ymq.mybatis*";
druidStatPointcut.setPatterns(patterns);
return druidStatPointcut;
}
@Bean
public Advisor druidStatAdvisor() {
return new DefaultPointcutAdvisor(druidStatPointcut(), druidStatInterceptor());
}
}
複製代碼
@ConfigurationProperties(prefix = "druid")
public class DruidDbProperties {
private String driverClassName = "com.mysql.jdbc.Driver";
/** * 初始化時創建物理鏈接的個數。初始化發生在顯示調用init方法,或者第一次getConnection時 */
private int initialSize = 10;
/** * 最小鏈接池數量 */
private int minIdle = 50;
/** * 最大鏈接池數量 */
private int maxActive = 300;
/** * 獲取鏈接時最大等待時間,單位毫秒。配置了maxWait以後,缺省啓用公平鎖,併發效率會有所降低,若是須要能夠經過配置useUnfairLock屬性爲true使用非公平鎖。 */
private int maxWait = 60000;
/** * 有兩個含義: 1) * Destroy線程會檢測鏈接的間隔時間,若是鏈接空閒時間大於等於minEvictableIdleTimeMillis則關閉物理鏈接。 2) * testWhileIdle的判斷依據,詳細看testWhileIdle屬性的說明 */
private int timeBetweenEvictionRunsMillis = 60000;
/** * 鏈接保持空閒而不被驅逐的最長時間 */
private int minEvictableIdleTimeMillis = 3600000;
/** * 用來檢測鏈接是否有效的sql,要求是一個查詢語句,經常使用select * 'x'。若是validationQuery爲null,testOnBorrow、testOnReturn、testWhileIdle都不會其做用。 */
private String validationQuery = "SELECT USER()";
/** * 建議配置爲true,不影響性能,而且保證安全性。申請鏈接的時候檢測,若是空閒時間大於timeBetweenEvictionRunsMillis,執行validationQuery檢測鏈接是否有效。 */
private boolean testWhileIdle = true;
/** * 申請鏈接時執行validationQuery檢測鏈接是否有效,作了這個配置會下降性能。 */
private boolean testOnBorrow = false;
/** * 歸還鏈接時執行validationQuery檢測鏈接是否有效,作了這個配置會下降性能。 */
private boolean testOnReturn = false;
/** * 屬性類型是字符串,經過別名的方式配置擴展插件,經常使用的插件有: 監控統計用的filter:stat 日誌用的filter:log4j * 防護sql注入的filter:wall */
private String filters = "mergeStat,config,wall";
private String connectionProperties;
/** * 白名單 */
private String allow;
/** * 黑名單 */
private String deny;
private String username = "admin";
private String password = "admin";
省略 get set
}
複製代碼
@Configuration
@EnableTransactionManagement
public class DBOneConfiguration extends AbstractDruidDBConfig {
@Value("${ymq.one.datasource.url}")
private String url;
@Value("${ymq.one.datasource.username}")
private String username;
@Value("${ymq.one.datasource.password}")
private String password;
// 註冊 datasourceOne
@Bean(name = "datasourceOne", initMethod = "init", destroyMethod = "close")
public DruidDataSource dataSource() {
return super.createDataSource(url, username, password);
}
@Bean(name = "sqlSessionFactorYmqOne")
public SqlSessionFactory sqlSessionFactory() throws Exception {
return super.sqlSessionFactory(dataSource());
}
@Bean
public PlatformTransactionManager transactionManager() throws SQLException {
return new DataSourceTransactionManager(dataSource());
}
}
複製代碼
@Configuration
@EnableTransactionManagement
public class DBOneConfiguration extends AbstractDruidDBConfig {
@Value("${ymq.one.datasource.url}")
private String url;
@Value("${ymq.one.datasource.username}")
private String username;
@Value("${ymq.one.datasource.password}")
private String password;
// 註冊 datasourceOne
@Bean(name = "datasourceOne", initMethod = "init", destroyMethod = "close")
public DruidDataSource dataSource() {
return super.createDataSource(url, username, password);
}
@Bean(name = "sqlSessionFactorYmqOne")
public SqlSessionFactory sqlSessionFactory() throws Exception {
return super.sqlSessionFactory(dataSource());
}
@Bean
public PlatformTransactionManager transactionManager() throws SQLException {
return new DataSourceTransactionManager(dataSource());
}
}
複製代碼
@Repository
public class YmqOneBaseDao extends BaseDao {
@Resource
public void setSqlSessionFactorYmqOne(SqlSessionFactory sqlSessionFactory) {
super.setSqlSessionFactory(sqlSessionFactory);
}
}
複製代碼
@Repository
public class YmqTwoBaseDao extends BaseDao {
@Resource
public void setSqlSessionFactorYmqTwo(SqlSessionFactory sqlSessionFactory) {
super.setSqlSessionFactory(sqlSessionFactory);
}
}
複製代碼
@RestController
public class IndexController {
private static final Logger LOG = LoggerFactory.getLogger(IndexController.class);
@Autowired
private YmqOneBaseDao ymqOneBaseDao;
@Autowired
private YmqTwoBaseDao ymqTwoBaseDao;
@RequestMapping("/")
public String index() throws Exception {
List<TestOnePo> testOnePoList = null;
testOnePoList = ymqOneBaseDao.selectList(new TestOnePo());
for (TestOnePo item : testOnePoList) {
LOG.info("數據源 ymqOneBaseDao :查詢結果:{}", JSONObject.toJSONString(item));
}
List<TestTwoPo> testTwoPoList = null;
testTwoPoList = ymqTwoBaseDao.selectList(new TestTwoPo());
for (TestTwoPo item : testTwoPoList) {
LOG.info("數據源 ymqTwoBaseDao:查詢結果:{}", JSONObject.toJSONString(item));
}
String onePoList = JSONObject.toJSONString(testOnePoList);
String twoPoList = JSONObject.toJSONString(testTwoPoList);
return "數據源 ymqOneBaseDao :查詢結果:" + onePoList + "<br/> 數據源 ymqTwoBaseDao :查詢結果:" + twoPoList;
}
}
複製代碼
application.properties
sql
#############SERVER CONFIG############
spring.application.name=ymq-mybatis-spring-boot
#數據源 one
ymq.one.datasource.url=jdbc:mysql://10.4.82.6:3306/ymq_one?useUnicode=true&characterEncoding=UTF-8
ymq.one.datasource.username=root
ymq.one.datasource.password=123456
#數據源 two
ymq.two.datasource.url=jdbc:mysql://10.4.82.6:3306/ymq_two?useUnicode=true&characterEncoding=UTF-8
ymq.two.datasource.username=root
ymq.two.datasource.password=123456
server.port=80
server.tomcat.max-threads=1000
server.tomcat.max-connections=2000
複製代碼
@SpringBootApplication
@ComponentScan(value = {"io.ymq.mybatis"})
public class Startup {
public static void main(String[] args) {
SpringApplication.run(Startup.class, args);
}
}
複製代碼
在頁面上輸入 http://localhost/ 能夠看到 Controller 執行狀況:數據庫
數據源 ymqOneBaseDao :查詢結果:[{"id":1,"name":"測試","remark":"這是測試 ymq_one 數據庫"}]
數據源 ymqTwoBaseDao :查詢結果:[{"id":1,"name":"測試","remark":"這是測試 ymq_two 數據庫"}]
複製代碼
在頁面上輸入 http://localhost/druid/ 能夠看到監控到的sql語句執行狀況:segmentfault
代碼我已放到 Github ,導入spring-boot-mybatis
項目tomcat
github github.com/souyunku/sp…