最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Springboot實(shí)現(xiàn)根據(jù)用戶ID切換動(dòng)態(tài)數(shù)據(jù)源

 更新時(shí)間:2021年12月15日 10:13:55   作者:洛陽(yáng)泰山  
在很多具體應(yīng)用場(chǎng)景中,我們需要用到動(dòng)態(tài)數(shù)據(jù)源的情況,比如多租戶的場(chǎng)景,系統(tǒng)登錄時(shí)需要根據(jù)用戶信息切換到用戶對(duì)應(yīng)的數(shù)據(jù)庫(kù)。這篇文章主要介紹了SpringBoot根據(jù)用戶ID實(shí)現(xiàn)切換動(dòng)態(tài)數(shù)據(jù)源的示例代碼,感興趣的可以了解一下

首先在application.yml 文件添加一下配置?

#每個(gè)庫(kù)可連接最大用戶數(shù)
dynamic-server:
  #每個(gè)服務(wù)最大建庫(kù)數(shù)
  database-max-number: 30
  #每個(gè)庫(kù)最大用戶連接數(shù)
  user-max-number: 200
  template: gis_template

然后項(xiàng)目中添加 dynamicds 模塊的代碼,僅展示模塊文件目錄,代碼太多不展示了

然后添加攔截器

 
    @Override
    public void addInterceptors(InterceptorRegistry registry){
        //排除登錄注冊(cè)攔截
        List<String> patterns = new ArrayList<>();
 
        patterns.add("/doc.html");
        patterns.add("/js/**");
        patterns.add("/webjars/**");
        patterns.add("/swagger-resources/**");
        patterns.add("/unify-resource/**");
        patterns.add("/unify-auth/oauth/token");
        patterns.add("/unify-auth/register");
        patterns.add("/unify-resource/**");
        patterns.add("/rabbit/**");
        //默認(rèn)數(shù)據(jù)源 不需要切換的 排除
        registry.addInterceptor(dynamicDataSourceInterceptor()).addPathPatterns("/**")
                .excludePathPatterns(patterns).order(1);
      //  registry.addInterceptor(dynamicDefaultDataSourceInterceptor()).addPathPatterns("/**").order(-1);
    }
 
    @Bean
    public DynamicDataSourceInterceptor dynamicDataSourceInterceptor(){
        return new DynamicDataSourceInterceptor();
    }

動(dòng)態(tài)數(shù)據(jù)源攔截器

跟據(jù)token 獲取用戶id 再根據(jù)用戶id切換對(duì)應(yīng)數(shù)據(jù)源?

 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.gis.dynamicds.cache.DynamicDataSourceCache;
import org.springblade.gis.dynamicds.datasource.MyDynamicDataSource;
import org.springblade.gis.dynamicds.service.DynamicDataSourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
/**
 * file:DynamicDataSourceInterceptor
 * <p>
 * 文件簡(jiǎn)要說(shuō)明
 *
 * @author 2021-10-28 tarzan 創(chuàng)建初始版本
 * @version V1.0  簡(jiǎn)要版本說(shuō)明
 */
public class DynamicDataSourceInterceptor implements HandlerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(DynamicDataSourceInterceptor.class);
    @Autowired
    private MyDynamicDataSource dynamicDataSource;
    @Autowired
    private DynamicDataSourceCache dynamicDataSourceCache;
    @Autowired
    private DynamicDataSourceService dynamicDataSourceService;
 
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)  {
        //獲取當(dāng)前登錄用戶信息
        BladeUser user = AuthUtil.getUser();
     /*   if(user == null || user.getUserId() == null){
            throw new UnauthorizedException(ErrorEnum.E_401);
        }*/
        log.info("據(jù)源切換--------------用戶名-----"+user.getUserName()+"------------>【{}】", user.getUserId());
        //如果未獲取到 dsName 重新加載數(shù)據(jù)庫(kù)
        if(!dynamicDataSourceCache.hasDataSourceName(user.getUserId())){
            dynamicDataSourceService.addUserDataSource(user.getUserId());
        }
        String dsName = dynamicDataSourceCache.getUserIdDataSourceName(user.getUserId());
        if(!dynamicDataSource.switchDataSource(dsName)){
            //如果切換數(shù)據(jù)源失敗 返回錯(cuò)誤
            throw new RuntimeException("未找到用戶數(shù)據(jù)庫(kù)");
        }
        return true;
    }
 
}

數(shù)據(jù)庫(kù)設(shè)計(jì)

dynamicDataSource:
  default:
    url: jdbc:postgresql://${POSTGRES_HOST:172.16.10.201}:${POSTGRES_PORT:5432}/${POSTGRES_DATABASE:gis_db}
    username: ${POSTGRES_USERNAME:postgres}
    password: ${POSTGRES_PASSWORD:postgres}
    driverClassName: org.postgresql.Driver
    pool:
      #最小空閑連接
      minimum-idle: 2
      #最大連接
      maximum-pool-size: 3
      # 空閑連接存活最大時(shí)間,默認(rèn)600000(10分鐘)
      idle-timeout: 1200000
      # 據(jù)庫(kù)連接超時(shí)時(shí)間,默認(rèn)30秒
      connection-timeout: 300000

初始鏈接一個(gè)基礎(chǔ)數(shù)據(jù)庫(kù),放置用戶表,數(shù)據(jù)源表,數(shù)據(jù)庫(kù)表

數(shù)據(jù)庫(kù)表建表語(yǔ)句

CREATE TABLE "public"."data_server_database" (
  "id" int8 NOT NULL,
  "data_source_key" varchar(128) COLLATE "pg_catalog"."default" NOT NULL,
  "database_name" varchar(128) COLLATE "pg_catalog"."default" NOT NULL,
  "source_id" int8 NOT NULL,
  "create_time" timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  "update_time" timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  "priority" int4 NOT NULL,
  "amount" int4 NOT NULL DEFAULT 0,
  "status" int2 NOT NULL DEFAULT 2
)
;
COMMENT ON COLUMN "public"."data_server_database"."id" IS '主鍵';
COMMENT ON COLUMN "public"."data_server_database"."data_source_key" IS '數(shù)據(jù)源連接唯一key';
COMMENT ON COLUMN "public"."data_server_database"."database_name" IS '數(shù)據(jù)庫(kù)名';
COMMENT ON COLUMN "public"."data_server_database"."source_id" IS '數(shù)據(jù)源id(data_server_source表主鍵id)';
COMMENT ON COLUMN "public"."data_server_database"."create_time" IS '創(chuàng)建時(shí)間';
COMMENT ON COLUMN "public"."data_server_database"."update_time" IS '更新時(shí)間';
COMMENT ON COLUMN "public"."data_server_database"."priority" IS '數(shù)據(jù)庫(kù)使用順序(升序)';
COMMENT ON COLUMN "public"."data_server_database"."amount" IS '數(shù)據(jù)使用用戶數(shù)量';
COMMENT ON COLUMN "public"."data_server_database"."status" IS '使用狀態(tài)(1:正在使用;2:本庫(kù)使用用戶數(shù)已滿)';
COMMENT ON TABLE "public"."data_server_database" IS '用戶連接的數(shù)據(jù)庫(kù)配置';
 
-- ----------------------------
-- Uniques structure for table data_server_database
-- ----------------------------
ALTER TABLE "public"."data_server_database" ADD CONSTRAINT "source_key_unique" UNIQUE ("data_source_key");
COMMENT ON CONSTRAINT "source_key_unique" ON "public"."data_server_database" IS '數(shù)據(jù)源名 唯一';
 
-- ----------------------------
-- Primary Key structure for table data_server_database
-- ----------------------------
ALTER TABLE "public"."data_server_database" ADD CONSTRAINT "data_server_source_pkey" PRIMARY KEY ("id");

數(shù)據(jù)源表建表語(yǔ)句?

CREATE TABLE "public"."data_server_source" (
  "id" int8 NOT NULL,
  "driver_class_name" varchar(128) COLLATE "pg_catalog"."default" NOT NULL,
  "url" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
  "user_name" varchar(64) COLLATE "pg_catalog"."default" NOT NULL,
  "password" varchar(128) COLLATE "pg_catalog"."default" NOT NULL,
  "create_time" timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  "update_time" timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  "priority" int4,
  "amount" int4 DEFAULT 0,
  "status" int2 DEFAULT 2
)
;
COMMENT ON COLUMN "public"."data_server_source"."id" IS '主鍵';
COMMENT ON COLUMN "public"."data_server_source"."driver_class_name" IS '數(shù)據(jù)庫(kù)驅(qū)動(dòng)';
COMMENT ON COLUMN "public"."data_server_source"."url" IS '數(shù)據(jù)庫(kù)連接url';
COMMENT ON COLUMN "public"."data_server_source"."user_name" IS '數(shù)據(jù)庫(kù)用戶名';
COMMENT ON COLUMN "public"."data_server_source"."password" IS '數(shù)據(jù)庫(kù)用戶密碼';
COMMENT ON COLUMN "public"."data_server_source"."create_time" IS '創(chuàng)建時(shí)間';
COMMENT ON COLUMN "public"."data_server_source"."update_time" IS '更新時(shí)間';
COMMENT ON COLUMN "public"."data_server_source"."priority" IS '數(shù)據(jù)庫(kù)服務(wù)使用順序(升序)';
COMMENT ON COLUMN "public"."data_server_source"."amount" IS '數(shù)據(jù)服務(wù)建庫(kù)數(shù)量';
COMMENT ON COLUMN "public"."data_server_source"."status" IS '使用狀態(tài)(1:正在使用;2:本服務(wù)建庫(kù)數(shù)已滿)';
COMMENT ON TABLE "public"."data_server_source" IS '數(shù)據(jù)庫(kù)服務(wù)的數(shù)據(jù)源連接表';
 
-- ----------------------------
-- Records of data_server_source
-- ----------------------------
INSERT INTO "public"."data_server_source" VALUES (2, 'org.postgresql.Driver', 'jdbc:postgresql://localhost:5432/', 'hgl', 'hgl', '2021-11-01 14:53:45', '2021-11-01 14:53:47', 2, 0, 2);
INSERT INTO "public"."data_server_source" VALUES (1, 'org.postgresql.Driver', 'jdbc:postgresql://172.16.10.201:5432/', 'postgres', 'postgres', '2021-11-01 14:53:45', '2021-11-01 14:53:47', 1, 3, 1);
INSERT INTO "public"."data_server_source" VALUES (5, 'org.postgresql.Driver', 'jdbc:postgresql://172.16.10.6:5432/', 'hgl', 'hgl', '2021-11-01 14:54:12', '2021-11-01 14:54:14', 10, 0, 2);
INSERT INTO "public"."data_server_source" VALUES (10, 'org.postgresql.Driver', 'jdbc:postgresql://172.16.10.72:5432,172.16.10.73:5432/', 'postgres', 'pgpg', '2021-11-01 14:54:12', '2021-11-01 14:54:14', 10, 0, 2);
 
-- ----------------------------
-- Primary Key structure for table data_server_source
-- ----------------------------
ALTER TABLE "public"."data_server_source" ADD CONSTRAINT "data_server_source_pkey1" PRIMARY KEY ("id");

用戶表 省略,就是常規(guī)用戶表,加上 數(shù)據(jù)庫(kù)id外鍵即可

注冊(cè)用戶時(shí),

調(diào)用DynamicDataSourceService類的getDatabaseId() 方法,將用戶和數(shù)據(jù)庫(kù)綁定。

      entity.setDatabaseId(dataSourceService.getDatabaseId());

getDatabaseId() 講解 根據(jù)配置的數(shù)據(jù)庫(kù)最大用戶數(shù)配置,方法內(nèi)部判斷當(dāng)前數(shù)據(jù)庫(kù)用戶數(shù)是否大于配置用戶,沒(méi)有則返回當(dāng)前數(shù)據(jù)庫(kù)id,有則返回下一個(gè)數(shù)據(jù)庫(kù)id

使用方法,調(diào)用接口時(shí)候,傳入token ,動(dòng)態(tài)數(shù)據(jù)庫(kù)攔截器,自動(dòng)獲取用戶id,切換對(duì)應(yīng)數(shù)據(jù)源。?

到此這篇關(guān)于Springboot實(shí)現(xiàn)根據(jù)用戶ID切換動(dòng)態(tài)數(shù)據(jù)源的文章就介紹到這了,更多相關(guān)Springboot切換動(dòng)態(tài)數(shù)據(jù)源內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Springboot對(duì)多線程的支持

    詳解Springboot對(duì)多線程的支持

    Spring是通過(guò)任務(wù)執(zhí)行器(TaskExecutor)來(lái)實(shí)現(xiàn)多線程和并發(fā)編程,使用ThreadPoolTaskExecutor來(lái)創(chuàng)建一個(gè)基于線城池的TaskExecutor。這篇文章給大家介紹Springboot對(duì)多線程的支持,感興趣的朋友一起看看吧
    2018-07-07
  • SpringBoot配置文件啟動(dòng)加載順序的方法步驟

    SpringBoot配置文件啟動(dòng)加載順序的方法步驟

    SpringBoot的啟動(dòng)加載順序涉及多個(gè)步驟和組件,通過(guò)分層和優(yōu)先級(jí)機(jī)制加載配置文件,確保在啟動(dòng)時(shí)正確配置應(yīng)用程序,本文就來(lái)介紹一下SpringBoot配置文件啟動(dòng)加載順序的方法步驟,感興趣的可以了解一下
    2024-11-11
  • java中將一個(gè)List等分成n個(gè)list的工具方法(推薦)

    java中將一個(gè)List等分成n個(gè)list的工具方法(推薦)

    下面小編就為大家?guī)?lái)一篇java中將一個(gè)List等分成n個(gè)list的工具方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • Java Annotation詳解及實(shí)例代碼

    Java Annotation詳解及實(shí)例代碼

    這篇文章主要介紹了Java Annotation詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • IDEA教程創(chuàng)建SpringBoot前后端分離項(xiàng)目示例圖解

    IDEA教程創(chuàng)建SpringBoot前后端分離項(xiàng)目示例圖解

    在使用spring、mybatis等框架時(shí),配置文件很復(fù)雜,有時(shí)復(fù)雜的讓人想放棄Java,使用C#。springboot出現(xiàn)這一切問(wèn)題就都不是問(wèn)題
    2021-10-10
  • 淺談圖片上傳利用request.getInputStream()獲取文件流時(shí)遇到的問(wèn)題

    淺談圖片上傳利用request.getInputStream()獲取文件流時(shí)遇到的問(wèn)題

    下面小編就為大家?guī)?lái)一篇淺談圖片上傳利用request.getInputStream()獲取文件流時(shí)遇到的問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • Mybatis 創(chuàng)建方法、全局配置教程詳解

    Mybatis 創(chuàng)建方法、全局配置教程詳解

    MyBatis是一個(gè)半自動(dòng)化的輕量級(jí)的持久化層框架。 MyBatis實(shí)際上是Ibatis3.0版本以后的持久化層框架,下面通過(guò)本文給大家分享Mybatis 創(chuàng)建方法、全局配置教程詳解,需要的朋友參考下吧
    2017-09-09
  • 詳解Jvm中時(shí)區(qū)設(shè)置方式

    詳解Jvm中時(shí)區(qū)設(shè)置方式

    這篇文章主要介紹了詳解Jvm中時(shí)區(qū)設(shè)置方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Tomcat啟動(dòng)分析(我們?yōu)槭裁匆渲肅ATALINA_HOME環(huán)境變量)

    Tomcat啟動(dòng)分析(我們?yōu)槭裁匆渲肅ATALINA_HOME環(huán)境變量)

    本文主要介紹Tomcat啟動(dòng)分析的知識(shí),這里整理了相關(guān)資料及分析原因和如何實(shí)現(xiàn)的方法,有興趣的小伙伴可以參考下
    2016-09-09
  • Spring—@Value在static中引用方式

    Spring—@Value在static中引用方式

    這篇文章主要介紹了Spring—@Value在static中引用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09

最新評(píng)論

怀安县| 康保县| 澄城县| 五峰| 景东| 西畴县| 绥芬河市| 宁海县| 景东| 逊克县| 秦安县| 韶关市| 镇江市| 丽江市| 怀仁县| 延吉市| 顺义区| 临夏县| 绍兴县| 镇平县| 甘孜| 五台县| 浑源县| 万荣县| 五家渠市| 搜索| 老河口市| 防城港市| 米林县| 白水县| 花垣县| 喜德县| 宿迁市| 凤阳县| 平潭县| 疏附县| 新丰县| 双峰县| 南部县| 揭阳市| 白银市|