国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

樂清網(wǎng)站建設(shè)網(wǎng)站建設(shè)網(wǎng)站的宣傳與推廣

樂清網(wǎng)站建設(shè)網(wǎng)站建設(shè),網(wǎng)站的宣傳與推廣,蚌埠網(wǎng)站制作公司排名,人員調(diào)動(dòng)在網(wǎng)站上怎么做前言 別誤會(huì),本篇【并不是】 要用mybatis-plus自身的多租戶方案:在表中加一個(gè)tenant_id字段來區(qū)分不同的租戶數(shù)據(jù)。并不是的! 而是在假設(shè)業(yè)務(wù)系統(tǒng)已經(jīng)使用mybatis-plus多數(shù)據(jù)源的前提下,如何實(shí)現(xiàn)業(yè)務(wù)數(shù)據(jù)庫隔開的多租戶系統(tǒng)。 這…

前言

別誤會(huì),本篇【并不是】 要用mybatis-plus自身的多租戶方案:在表中加一個(gè)tenant_id字段來區(qū)分不同的租戶數(shù)據(jù)。并不是的!
而是在假設(shè)業(yè)務(wù)系統(tǒng)已經(jīng)使用mybatis-plus多數(shù)據(jù)源的前提下,如何實(shí)現(xiàn)業(yè)務(wù)數(shù)據(jù)庫隔開的多租戶系統(tǒng)。
這里面有點(diǎn)繞:多數(shù)據(jù)源可以是一個(gè)系統(tǒng)本身的功能需求,假設(shè)當(dāng)前系統(tǒng)算做是個(gè)單租戶,它使用了兩個(gè)數(shù)據(jù)庫: master1和sys1,那么做多租戶改造后,假設(shè)現(xiàn)在有了2個(gè)租戶,那么就要添加2個(gè)數(shù)據(jù)庫:master2和sys2 , 總共就是四個(gè)數(shù)據(jù)庫(數(shù)據(jù)源)了…
咱們這里簡(jiǎn)單化處理,假設(shè)一個(gè)業(yè)務(wù)系統(tǒng)只使用一個(gè)數(shù)據(jù)庫。

大綱

在本篇我們可以

  • 看到mybatis-plus底層多數(shù)據(jù)源的實(shí)現(xiàn)原理
  • 在不破壞多數(shù)據(jù)源的前提下,實(shí)現(xiàn)多租戶功能
  • spring security結(jié)合jwt記錄租戶信息

代碼版本:

springboot: 2.7.0
dynamic-datasource-spring-boot-starter: 4.3.0
io.jsonwebtoken: 0.12.3

回顧mybatis-plus多數(shù)據(jù)源使用

1.yaml配置:
在這里插入圖片描述
2.serviceImpl:
在這里插入圖片描述
或者使用切面動(dòng)態(tài)設(shè)置crud對(duì)應(yīng)的數(shù)據(jù)源。

改造需求

  • 不要把所有租戶信息都直接放在yaml等配置文件中
  • 可動(dòng)態(tài)的添加刪除數(shù)據(jù)源
  • 用戶登錄成功后,把租戶信息封裝到j(luò)wt token中,后續(xù)業(yè)務(wù)訪問提取中租戶信息,動(dòng)態(tài)切換數(shù)據(jù)源訪問

方案

租戶本身的信息可放在resources/tenants目錄下,一個(gè)租戶使用一個(gè)單獨(dú)的配置文件,或者通過讀取另外的數(shù)據(jù)庫獲取。本篇先使用前者。
修改某個(gè)租戶的配置文件內(nèi)容/數(shù)據(jù)庫,重啟服務(wù)/通過controller接口觸發(fā)數(shù)據(jù)源的變更。

正篇開始
yaml配置文件中只保留一個(gè)主數(shù)據(jù)庫,如上yaml截圖所示。
另外的2個(gè)租戶配置放classpath下tenant目錄,如下所示:
在這里插入圖片描述
新建多數(shù)據(jù)源配置類,內(nèi)容如下:

@Configuration(proxyBeanMethods = false)
@Slf4j
public class MultiDataSourceConfig {@Resourceprivate DruidDataSourceCreator druidDataSourceCreator;@Resourceprivate DynamicRoutingDataSource dataSource;@PostConstructpublic void init() {ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();try {org.springframework.core.io.Resource[] resources = resolver.getResources("classpath:tenants/*.properties");for (org.springframework.core.io.Resource resource : resources) {Properties tenantProperties = new Properties();tenantProperties.load(resource.getInputStream());String tenantId = tenantProperties.getProperty("name");DataSourceProperty dataSourceProperty = new DataSourceProperty();dataSourceProperty.setPoolName(tenantId);dataSourceProperty.setUrl(tenantProperties.getProperty("datasource.url"));dataSourceProperty.setUsername(tenantProperties.getProperty("datasource.username"));dataSourceProperty.setPassword(tenantProperties.getProperty("datasource.password"));dataSourceProperty.setDriverClassName(tenantProperties.getProperty("datasource.driver-class-name"));dataSource.addDataSource(tenantId, druidDataSourceCreator.createDataSource(dataSourceProperty));}} catch (IOException exp) {throw new RuntimeException("Problem in tenant datasource:" + exp);}}
}

上述代碼讀取classpath:tenants/目錄下的所有.properties配置文件內(nèi)容,組裝并添加數(shù)據(jù)源。

登錄

登錄操作時(shí),查詢此登錄用戶對(duì)應(yīng)的租戶信息,并在生成jwt token時(shí),把租戶信息也封裝進(jìn)去,通過http響應(yīng)頭返回給用戶。如下所示:

public static void addToken(HttpServletResponse res, String username, String tenant) {String JwtToken = Jwts.builder().subject(username).audience().add(tenant).and().issuedAt(new Date(System.currentTimeMillis())).expiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME)).signWith(SIGNINGKEY).compact();res.addHeader("Authorization", PREFIX + JwtToken);}

業(yè)務(wù)操作

在一個(gè)攔截器類中:token校驗(yàn),并從中提取出租戶信息,如下所示:

public static String getTenant(HttpServletRequest req) {String token = req.getHeader("Authorization");if (token == null) {return null;}String tenant = Jwts.parser().setSigningKey(SIGNINGKEY).build().parseClaimsJws(token.replace(PREFIX, "").trim()).getBody().getAudience().iterator().next();return tenant;}
動(dòng)態(tài)切換數(shù)據(jù)源

得到一個(gè)請(qǐng)求所屬租戶信息后,要訪問數(shù)據(jù)庫時(shí)切換源:記住這里
記住它:DynamicDataSourceContextHolder

    DynamicDataSourceContextHolder.push(tenant);try {chain.doFilter(request, response);} finally {DynamicDataSourceContextHolder.clear();}

完工!是的,使用層面上就結(jié)束了。接下來是原理分析。

剖析

1.有個(gè)類名叫:AbstractRoutingDataSource,mybatis-plus和spring-jdbc都有叫這個(gè)名的類,
并且它們都繼承了AbstractDataSource類,但是這個(gè)父類也只是同名而已。但是它們的功能都說得很清楚:抽象動(dòng)態(tài)獲取數(shù)據(jù)源,它們都有個(gè)抽象方法:抽象獲取連接池,如下所示:
在這里插入圖片描述
spring-jdbc下的源碼
在這里插入圖片描述
然后看看mybatis-plus的抽象方法實(shí)現(xiàn)
在這里插入圖片描述
在這里插入圖片描述
所以回顧我們業(yè)務(wù)代碼的寫法:DynamicDataSourceContextHolder.push(tenant);
正是我們把當(dāng)前請(qǐng)求對(duì)應(yīng)的tenant作為數(shù)據(jù)源key 壓棧了,后面切換數(shù)據(jù)源時(shí)依據(jù)它去得到數(shù)據(jù)源。那么還記得這個(gè)租戶key 是在哪里和數(shù)據(jù)源對(duì)應(yīng)上的嗎
正是在正篇開頭的新建多數(shù)據(jù)源配置類中:

dataSource.addDataSource(tenantId, druidDataSourceCreator.createDataSource(dataSourceProperty));
    /*** 添加數(shù)據(jù)源** @param ds         數(shù)據(jù)源名稱* @param dataSource 數(shù)據(jù)源*/public synchronized void addDataSource(String ds, DataSource dataSource) {DataSource oldDataSource = dataSourceMap.put(ds, dataSource);// 新數(shù)據(jù)源添加到分組this.addGroupDataSource(ds, dataSource);// 關(guān)閉老的數(shù)據(jù)源if (oldDataSource != null) {closeDataSource(ds, oldDataSource, graceDestroy);}log.info("dynamic-datasource - add a datasource named [{}] success", ds);}

如此就打通了流程。如果大家感興趣,可以看到com.baomidou.dynamic.datasource.DynamicRoutingDataSource類中有一些方法刪除數(shù)據(jù)源,還有數(shù)據(jù)源分組功能,這可以用于主主(從,如果業(yè)務(wù)場(chǎng)景都是只讀的話),策略是輪詢和隨機(jī):
在這里插入圖片描述

http://aloenet.com.cn/news/40837.html

相關(guān)文章:

  • 旅游景區(qū)網(wǎng)站源碼個(gè)人網(wǎng)站設(shè)計(jì)成品
  • 建c2c網(wǎng)站費(fèi)用拉新推廣賺錢的app
  • 浙江網(wǎng)站建設(shè)企業(yè)軟文類型
  • 免費(fèi)做的網(wǎng)站怎么設(shè)置域名京津冀協(xié)同發(fā)展
  • 營(yíng)銷加盟網(wǎng)站建設(shè)網(wǎng)站維護(hù)是什么意思
  • erp定制開發(fā)價(jià)格澳門seo關(guān)鍵詞排名
  • 做網(wǎng)站阿里云買哪個(gè)服務(wù)器好點(diǎn)汽車推廣軟文
  • 長(zhǎng)沙制作網(wǎng)頁網(wǎng)站杭州網(wǎng)絡(luò)
  • 一品威客網(wǎng)怎么樣seo免費(fèi)優(yōu)化網(wǎng)站
  • win7iis配置網(wǎng)站百度搜索引擎網(wǎng)址
  • 整站優(yōu)化網(wǎng)站報(bào)價(jià)公司網(wǎng)站建設(shè)全包
  • 網(wǎng)站開發(fā)團(tuán)隊(duì)取什么名字好怎么引流怎么推廣自己的產(chǎn)品
  • 長(zhǎng)春怎么做網(wǎng)站建站流程新手搭建網(wǎng)站第一步
  • 商城網(wǎng)站開發(fā)教程視頻北京網(wǎng)絡(luò)營(yíng)銷推廣
  • 歐美設(shè)計(jì)網(wǎng)站推薦app拉新平臺(tái)哪個(gè)好傭金高
  • 密云做網(wǎng)站的產(chǎn)品關(guān)鍵詞大全
  • 建站行業(yè)的利潤(rùn)百度指數(shù)里的資訊指數(shù)是什么
  • 不銹鋼公司網(wǎng)站源碼 網(wǎng)站建設(shè) 產(chǎn)品3級(jí)分類asp源碼域名查詢注冊(cè)商
  • 360度全景街景地圖陽江seo
  • 北京營(yíng)銷型網(wǎng)站建設(shè)培訓(xùn)百度怎么優(yōu)化網(wǎng)站關(guān)鍵詞
  • 科學(xué)城做網(wǎng)站公司網(wǎng)絡(luò)營(yíng)銷的四種模式
  • 桂平網(wǎng)站制作seo查詢seo優(yōu)化
  • 網(wǎng)站不備案可以做微信小程序么幫人推廣的平臺(tái)
  • 獨(dú)立商城網(wǎng)站建設(shè)網(wǎng)絡(luò)營(yíng)銷八大目標(biāo)是什么
  • 手機(jī)屏幕網(wǎng)站佛山外貿(mào)seo
  • 新校區(qū)建設(shè)專題網(wǎng)站免費(fèi)瀏覽網(wǎng)站推廣
  • 做網(wǎng)站最重要的是什么seo方法圖片
  • 網(wǎng)站建設(shè)制作設(shè)計(jì)seo優(yōu)化珠海百度人工電話
  • 網(wǎng)站建設(shè) 上海網(wǎng)站百度seo排名規(guī)則
  • 鮮花網(wǎng)站建設(shè)圖片百度知道客服電話人工服務(wù)