如何在springboot中利用mybatis实现多数据源切换

今天就跟大家聊聊有关如何在spring boot中利用mybatis实现多数据源切换,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。

“真诚服务,让网络创造价值”是我们的服务理念,创新互联公司团队10年如一日始终坚持在网站建设领域,为客户提供优质服。不管你处于什么行业,助你轻松跨入“互联网+”时代,PC网站+手机网站+公众号+重庆小程序开发

1.首先定义一个注解类

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TargetDataSource {
 String value();//此处接收的是数据源的名称
}

2.然后建一个配置类,这个在项目启动时会加载数据源,一开始采用了HikariCP,查资料说是最快性能最好的,然后又发现了阿里的druid,这个功能比较全面,而且性能也还可以,最主要他还有监控功能,具体实现看如下代码

package com.example.demo.datasource;
 
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.example.demo.datasource.DynamicDataSource;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
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;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.PlatformTransactionManager;
import org.w3c.dom.NodeList;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
 
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import javax.sql.DataSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.io.File;
import com.alibaba.druid.support.http.StatViewServlet;
/**
 * Author: wangchao
 * Version:
 * Date:  2017/9/11
 * Description:数据源配置
 * Modification History:
 * Date    Author    Version   Description
 * --------------------------------------------------------------
 * Why & What is modified:
 */
 
@Configuration
@EnableScheduling
public class DataSourceConfig {
 
 /*@Autowired
 private DBProperties properties;*/
 @Value("${datasource.filePath}")
 private String filePath;//数据源配置
 
 @Bean(name = "dataSource")
 public DataSource dataSource() {
  //按照目标数据源名称和目标数据源对象的映射存放在Map中
  Map targetDataSources = new HashMap<>();
  //查找xml数据连接字符串
  targetDataSources=getdataMap(filePath);
  //动态获取DBProperties类申明的属性
  /*Field[] fields=properties.getClass().getDeclaredFields();
  for(int i=0;i getdataMap(String fiePath)
 {
 
  try {
   Map targetDataSources = new HashMap<>();
   File xmlFile = new File(fiePath);
 
   DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
 
   DocumentBuilder builder = builderFactory.newDocumentBuilder();
 
   Document doc = builder.parse(xmlFile);
 
   doc.getDocumentElement().normalize();
 
   System.out.println("Root element: " + doc.getDocumentElement().getNodeName());
 
   NodeList nList = doc.getElementsByTagName("db");
   for(int i = 0 ; i

3.动态数据源,从之前已加载的数据源中选取,DynamicDataSource和DynamicDataSourceHolder配合使用

public class DynamicDataSource extends AbstractRoutingDataSource{
 //数据源路由,此方用于产生要选取的数据源逻辑名称
 @Override
 protected Object determineCurrentLookupKey() {
  //从共享线程中获取数据源名称
  return DynamicDataSourceHolder.getDataSource();
 }
}

public class DynamicDataSourceHolder {
 /**
  * 本地线程共享对象
  */
 private static final ThreadLocal THREAD_LOCAL = new ThreadLocal<>();
 
 public static void putDataSource(String name) {
  THREAD_LOCAL.set(name);
 }
 
 public static String getDataSource() {
  return THREAD_LOCAL.get();
 }
 
 public static void removeDataSource() {
  THREAD_LOCAL.remove();
 }
}

4.就是使用aop,在dao层切换数据源

@Component
@Aspect
public class DataSourceAspect {
 //切换放在mapper接口的方法上,所以这里要配置AOP切面的切入点
 @Pointcut("execution( * com.example.demo.dao.*.*(..))")
 public void dataSourcePointCut() {
 }
 
 @Before("dataSourcePointCut()")
 public void before(JoinPoint joinPoint) {
  Object target = joinPoint.getTarget();
  String method = joinPoint.getSignature().getName();
  Class<?>[] clazz = target.getClass().getInterfaces();
  Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getMethod().getParameterTypes();
  try {
   Method m = clazz[0].getMethod(method, parameterTypes);
   //如果方法上存在切换数据源的注解,则根据注解内容进行数据源切换
   if (m != null && m.isAnnotationPresent(TargetDataSource.class)) {
    TargetDataSource data = m.getAnnotation(TargetDataSource.class);
    String dataSourceName = data.value();
    DynamicDataSourceHolder.putDataSource(dataSourceName);
 
   } else {
 
   }
  } catch (Exception e) {
 
  }
 }
 
 //执行完切面后,将线程共享中的数据源名称清空
 @After("dataSourcePointCut()")
 public void after(JoinPoint joinPoint){
  DynamicDataSourceHolder.removeDataSource();
 }
}

数据连接都配置在xml里面如何在spring boot中利用mybatis实现多数据源切换

xml路径在配置文件里面配置,这样适用读写分离和多个不同的数据源,而且多个项目可以共用这一个配置

如何在spring boot中利用mybatis实现多数据源切换

最后引用注解,需要注意的是注解的数据库名称和xml里面databasename节点是一一对应的,可以随便自定义,比如读写是一个数据库名字,这时候就可以定义成pringtest_r表示读库

如何在spring boot中利用mybatis实现多数据源切换

看完上述内容,你们对如何在spring boot中利用mybatis实现多数据源切换有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注创新互联行业资讯频道,感谢大家的支持。


新闻名称:如何在springboot中利用mybatis实现多数据源切换
文章网址:http://scyanting.com/article/ggggdo.html