国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - spring boot+mybatis 多數據源切換(實例講解)

spring boot+mybatis 多數據源切換(實例講解)

2021-01-03 15:25易興 Java教程

下面小編就為大家帶來一篇spring boot+mybatis 多數據源切換(實例講解)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

由于公司業務劃分了多個數據庫,開發一個項目會同事調用多個庫,經過學習我們采用了注解+aop的方式實現的

1.首先定義一個注解類

?
1
2
3
4
5
@retention(retentionpolicy.runtime)
@target(elementtype.method)
public @interface targetdatasource {
 string value();//此處接收的是數據源的名稱
}

2.然后建一個配置類,這個在項目啟動時會加載數據源,一開始采用了hikaricp,查資料說是最快性能最好的,然后又發現了阿里的druid,這個功能比較全面,而且性能也還可以,最主要他還有監控功能,具體實現看如下代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
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<object, object> targetdatasources = new hashmap<>();
  //查找xml數據連接字符串
  targetdatasources=getdatamap(filepath);
  //動態獲取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的對象包裝多數據源
  dynamicdatasource datasource = new dynamicdatasource();
  datasource.settargetdatasources(targetdatasources);
  //設置默認的數據源,當拿不到數據源時,使用此配置
  //datasource.setdefaulttargetdatasource(properties.getuzaitravel());
  return datasource;
 }
 
 @bean
 public platformtransactionmanager txmanager() {
  return new datasourcetransactionmanager(datasource());
 }
 
 /**
 *獲取數據源集合
 */
 
 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);// 啟用監控統計功能
    datasource.setfilters("stat");//設置是否顯示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提供類的進行注冊.
  servletregistrationbean servletregistrationbean = new servletregistrationbean(new statviewservlet(), "/druid/*");
  //添加初始化參數:initparams
 
  //白名單:
  servletregistrationbean.addinitparameter("allow",ip);
  //ip黑名單 (存在共同時,deny優先于allow) : 如果滿足deny的話提示:sorry, you are not permitted to view this page.
  // servletregistrationbean.addinitparameter("deny", "192.168.1.73");
  //登錄查看信息的賬號密碼.
  servletregistrationbean.addinitparameter("loginusername",druidlgoinname);
  servletregistrationbean.addinitparameter("loginpassword",druidlgoinpassword);
  //是否能夠重置數據.
  servletregistrationbean.addinitparameter("resetenable","false");
  return servletregistrationbean;
 }
 
 /**
 
  * 注冊一個:filterregistrationbean
 
  * @return
 
 */
 @bean
 public filterregistrationbean druidstatfilter2(){
  filterregistrationbean filterregistrationbean = new filterregistrationbean(new webstatfilter());
  //添加過濾規則.
  filterregistrationbean.addurlpatterns("/*");
  //添加不需要忽略的格式信息.
  filterregistrationbean.addinitparameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
  return filterregistrationbean;
 }
 
}

3.動態數據源,從之前已加載的數據源中選取,dynamicdatasource和dynamicdatasourceholder配合使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class dynamicdatasource extends abstractroutingdatasource{
 //數據源路由,此方用于產生要選取的數據源邏輯名稱
 @override
 protected object determinecurrentlookupkey() {
  //從共享線程中獲取數據源名稱
  return dynamicdatasourceholder.getdatasource();
 }
}
 
public class dynamicdatasourceholder {
 /**
  * 本地線程共享對象
  */
 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層切換數據源

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@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 多數據源切換(實例講解)

至此多數據源就配置完成,至于阿里的druid下次再分享,代碼都貼出來,如果大家感覺還有哪些不足的地方,歡迎指正。

以上這篇spring boot+mybatis 多數據源切換(實例講解)就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/ok123/archive/2017/09/14/7523106.html

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产精品久久久久久久美男 | 中文字幕123 | 国产不卡一区 | 久久精品成人 | 亚洲精品一区二区三区四区高清 | 国产黄色免费网站 | 理伦影院 | 欧美大片免费 | 欧美三区二区一区 | 亚洲成人黄色 | 国产一区二区在线免费观看 | 亚洲国产精品久久人人爱 | 国产精品1区2区在线观看 | 国产黄色av | 日韩第一区| 一区二区视频在线观看 | 久久国产精品99久久久久久老狼 | 亚洲日本国产 | 成人自拍视频 | 久久av网 | 亚洲午夜电影在线 | 欧美高清一区 | 欧美成人福利 | 亚洲精品乱码久久久久久麻豆不卡 | 9色av| 国产99久久 | 国产在线不卡 | 91大神免费观看 | 亚洲欧美视频在线播放 | 在线一区| 亚洲狠狠丁香婷婷综合久久久 | 免费啪啪网站 | 色综合天天综合网国产成人综合天 | 欧美一区二区三区在线看 | 中文字幕亚洲一区二区三区 | 久久久久久久久久久免费视频 | 国产h片在线观看 | 中文色视频 | 免费国产一区二区 | 老熟妇午夜毛片一区二区三区 | av一区二区在线观看 |