成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

如何在springboot中利用mybatis實(shí)現(xiàn)多數(shù)據(jù)源切換

今天就跟大家聊聊有關(guān)如何在spring boot中利用mybatis實(shí)現(xiàn)多數(shù)據(jù)源切換,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。

“真誠服務(wù),讓網(wǎng)絡(luò)創(chuàng)造價(jià)值”是我們的服務(wù)理念,創(chuàng)新互聯(lián)公司團(tuán)隊(duì)10年如一日始終堅(jiān)持在網(wǎng)站建設(shè)領(lǐng)域,為客戶提供優(yōu)質(zhì)服。不管你處于什么行業(yè),助你輕松跨入“互聯(lián)網(wǎng)+”時(shí)代,PC網(wǎng)站+手機(jī)網(wǎng)站+公眾號(hào)+重慶小程序開發(fā)

1.首先定義一個(gè)注解類

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TargetDataSource {
 String value();//此處接收的是數(shù)據(jù)源的名稱
}

2.然后建一個(gè)配置類,這個(gè)在項(xiàng)目啟動(dòng)時(shí)會(huì)加載數(shù)據(jù)源,一開始采用了HikariCP,查資料說是最快性能最好的,然后又發(fā)現(xiàn)了阿里的druid,這個(gè)功能比較全面,而且性能也還可以,最主要他還有監(jiān)控功能,具體實(shí)現(xiàn)看如下代碼

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:數(shù)據(jù)源配置
 * 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;//數(shù)據(jù)源配置
 
 @Bean(name = "dataSource")
 public DataSource dataSource() {
  //按照目標(biāo)數(shù)據(jù)源名稱和目標(biāo)數(shù)據(jù)源對(duì)象的映射存放在Map中
  Map<Object, Object> targetDataSources = new HashMap<>();
  //查找xml數(shù)據(jù)連接字符串
  targetDataSources=getdataMap(filePath);
  //動(dòng)態(tài)獲取DBProperties類申明的屬性
  /*Field[] fields=properties.getClass().getDeclaredFields();
  for(int i=0;i<fields.length;i++)
  {
   targetDataSources.put(fields[i].getName(), getFieldValueByName(fields[i].getName(),properties));
  }*/
  //采用是想AbstractRoutingDataSource的對(duì)象包裝多數(shù)據(jù)源
  DynamicDataSource dataSource = new DynamicDataSource();
  dataSource.setTargetDataSources(targetDataSources);
  //設(shè)置默認(rèn)的數(shù)據(jù)源,當(dāng)拿不到數(shù)據(jù)源時(shí),使用此配置
  //dataSource.setDefaultTargetDataSource(properties.getUzaiTravel());
  return dataSource;
 }
 
 @Bean
 public PlatformTransactionManager txManager() {
  return new DataSourceTransactionManager(dataSource());
 }
 
 /**
 *獲取數(shù)據(jù)源集合
 */
 
 private Map<Object, Object> getdataMap(String fiePath)
 {
 
  try {
   Map<Object, Object> 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<nList.getLength();i++) {
 
    Node node = nList.item(i);
    Element ele = (Element)node;
 
    /*HikariConfig config = new HikariConfig();
    config.setDriverClassName(ele.getElementsByTagName("driver-class").item(0).getTextContent());
    config.setJdbcUrl(ele.getElementsByTagName("jdbc-url").item(0).getTextContent());
    config.setUsername(ele.getElementsByTagName("username").item(0).getTextContent());
    config.setPassword(ele.getElementsByTagName("password").item(0).getTextContent());
    //config.addDataSourceProperty("password", ele.getElementsByTagName("password").item(0).getTextContent());
    HikariDataSource dataSource = new HikariDataSource(config);*/
 
 
    DruidDataSource dataSource = new DruidDataSource();
    dataSource.setDriverClassName(ele.getElementsByTagName("driver-class").item(0).getTextContent());
    dataSource.setUsername(ele.getElementsByTagName("username").item(0).getTextContent());
    dataSource.setPassword(ele.getElementsByTagName("password").item(0).getTextContent());
    dataSource.setUrl(ele.getElementsByTagName("jdbc-url").item(0).getTextContent());
    dataSource.setInitialSize(5);
    dataSource.setMinIdle(1);
    dataSource.setMaxActive(10);// 啟用監(jiān)控統(tǒng)計(jì)功能
    dataSource.setFilters("stat");//設(shè)置是否顯示sql語句
    targetDataSources.put(ele.getElementsByTagName("databasename").item(0).getTextContent(), dataSource);
   }
   return targetDataSources;
  }
  catch (Exception ex)
  {
   return null;
  }
 
 }
 //訪問的ip
 @Value("${druid.IP}")
 private String IP;
 //登錄名
 @Value("${druid.druidLgoinName}")
 private String druidLgoinName;
 //密碼
 @Value("${druid.druidLgoinPassword}")
 private String druidLgoinPassword;
 
 @Bean
 public ServletRegistrationBean DruidStatViewServle() {
  //org.springframework.boot.context.embedded.ServletRegistrationBean提供類的進(jìn)行注冊(cè).
  ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
  //添加初始化參數(shù):initParams
 
  //白名單:
  servletRegistrationBean.addInitParameter("allow",IP);
  //IP黑名單 (存在共同時(shí),deny優(yōu)先于allow) : 如果滿足deny的話提示:Sorry, you are not permitted to view this page.
  // servletRegistrationBean.addInitParameter("deny", "192.168.1.73");
  //登錄查看信息的賬號(hào)密碼.
  servletRegistrationBean.addInitParameter("loginUsername",druidLgoinName);
  servletRegistrationBean.addInitParameter("loginPassword",druidLgoinPassword);
  //是否能夠重置數(shù)據(jù).
  servletRegistrationBean.addInitParameter("resetEnable","false");
  return servletRegistrationBean;
 }
 
 /**
 
  * 注冊(cè)一個(gè):filterRegistrationBean
 
  * @return
 
 */
 @Bean
 public FilterRegistrationBean druidStatFilter2(){
  FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
  //添加過濾規(guī)則.
  filterRegistrationBean.addUrlPatterns("/*");
  //添加不需要忽略的格式信息.
  filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
  return filterRegistrationBean;
 }
 
}

3.動(dòng)態(tài)數(shù)據(jù)源,從之前已加載的數(shù)據(jù)源中選取,DynamicDataSource和DynamicDataSourceHolder配合使用

public class DynamicDataSource extends AbstractRoutingDataSource{
 //數(shù)據(jù)源路由,此方用于產(chǎn)生要選取的數(shù)據(jù)源邏輯名稱
 @Override
 protected Object determineCurrentLookupKey() {
  //從共享線程中獲取數(shù)據(jù)源名稱
  return DynamicDataSourceHolder.getDataSource();
 }
}

public class DynamicDataSourceHolder {
 /**
  * 本地線程共享對(duì)象
  */
 private static final ThreadLocal<String> 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層切換數(shù)據(jù)源

@Component
@Aspect
public class DataSourceAspect {
 //切換放在mapper接口的方法上,所以這里要配置AOP切面的切入點(diǎn)
 @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<&#63;>[] clazz = target.getClass().getInterfaces();
  Class<&#63;>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getMethod().getParameterTypes();
  try {
   Method m = clazz[0].getMethod(method, parameterTypes);
   //如果方法上存在切換數(shù)據(jù)源的注解,則根據(jù)注解內(nèi)容進(jìn)行數(shù)據(jù)源切換
   if (m != null && m.isAnnotationPresent(TargetDataSource.class)) {
    TargetDataSource data = m.getAnnotation(TargetDataSource.class);
    String dataSourceName = data.value();
    DynamicDataSourceHolder.putDataSource(dataSourceName);
 
   } else {
 
   }
  } catch (Exception e) {
 
  }
 }
 
 //執(zhí)行完切面后,將線程共享中的數(shù)據(jù)源名稱清空
 @After("dataSourcePointCut()")
 public void after(JoinPoint joinPoint){
  DynamicDataSourceHolder.removeDataSource();
 }
}

數(shù)據(jù)連接都配置在xml里面如何在spring boot中利用mybatis實(shí)現(xiàn)多數(shù)據(jù)源切換

xml路徑在配置文件里面配置,這樣適用讀寫分離和多個(gè)不同的數(shù)據(jù)源,而且多個(gè)項(xiàng)目可以共用這一個(gè)配置

如何在spring boot中利用mybatis實(shí)現(xiàn)多數(shù)據(jù)源切換

最后引用注解,需要注意的是注解的數(shù)據(jù)庫名稱和xml里面databasename節(jié)點(diǎn)是一一對(duì)應(yīng)的,可以隨便自定義,比如讀寫是一個(gè)數(shù)據(jù)庫名字,這時(shí)候就可以定義成pringtest_r表示讀庫

如何在spring boot中利用mybatis實(shí)現(xiàn)多數(shù)據(jù)源切換

看完上述內(nèi)容,你們對(duì)如何在spring boot中利用mybatis實(shí)現(xiàn)多數(shù)據(jù)源切換有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。

本文名稱:如何在springboot中利用mybatis實(shí)現(xiàn)多數(shù)據(jù)源切換
分享URL:http://jinyejixie.com/article10/ggggdo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、網(wǎng)站內(nèi)鏈、全網(wǎng)營銷推廣、用戶體驗(yàn)網(wǎng)站設(shè)計(jì)、服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)
左权县| 芷江| 芦溪县| 大埔区| 称多县| 伊宁县| 峨眉山市| 弥勒县| 凤阳县| 丹凤县| 封丘县| 西宁市| 喀喇沁旗| 靖安县| 泰安市| 安陆市| 邛崃市| 柳州市| 莱西市| 博兴县| 平潭县| 文安县| 孝义市| 奈曼旗| 报价| 灌阳县| 响水县| 军事| 通山县| 宣武区| 乐安县| 怀柔区| 当涂县| 拉孜县| 盱眙县| 定安县| 玉田县| 图们市| 聂拉木县| 宁安市| 江西省|