Springboot實(shí)現(xiàn)根據(jù)用戶ID切換動態(tài)數(shù)據(jù)源
首先在application.yml 文件添加一下配置?
#每個庫可連接最大用戶數(shù) dynamic-server: #每個服務(wù)最大建庫數(shù) database-max-number: 30 #每個庫最大用戶連接數(shù) user-max-number: 200 template: gis_template
然后項(xiàng)目中添加 dynamicds 模塊的代碼,僅展示模塊文件目錄,代碼太多不展示了

然后添加攔截器
@Override
public void addInterceptors(InterceptorRegistry registry){
//排除登錄注冊攔截
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();
}
動態(tài)數(shù)據(jù)源攔截器
跟據(jù)token 獲取用戶id 再根據(jù)用戶id切換對應(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>
* 文件簡要說明
*
* @author 2021-10-28 tarzan 創(chuàng)建初始版本
* @version V1.0 簡要版本說明
*/
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ù)庫
if(!dynamicDataSourceCache.hasDataSourceName(user.getUserId())){
dynamicDataSourceService.addUserDataSource(user.getUserId());
}
String dsName = dynamicDataSourceCache.getUserIdDataSourceName(user.getUserId());
if(!dynamicDataSource.switchDataSource(dsName)){
//如果切換數(shù)據(jù)源失敗 返回錯誤
throw new RuntimeException("未找到用戶數(shù)據(jù)庫");
}
return true;
}
}
數(shù)據(jù)庫設(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
# 空閑連接存活最大時間,默認(rèn)600000(10分鐘)
idle-timeout: 1200000
# 據(jù)庫連接超時時間,默認(rèn)30秒
connection-timeout: 300000
初始鏈接一個基礎(chǔ)數(shù)據(jù)庫,放置用戶表,數(shù)據(jù)源表,數(shù)據(jù)庫表
數(shù)據(jù)庫表建表語句
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ù)庫名';
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)建時間';
COMMENT ON COLUMN "public"."data_server_database"."update_time" IS '更新時間';
COMMENT ON COLUMN "public"."data_server_database"."priority" IS '數(shù)據(jù)庫使用順序(升序)';
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:本庫使用用戶數(shù)已滿)';
COMMENT ON TABLE "public"."data_server_database" IS '用戶連接的數(shù)據(jù)庫配置';
-- ----------------------------
-- 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ù)源表建表語句?
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ù)庫驅(qū)動';
COMMENT ON COLUMN "public"."data_server_source"."url" IS '數(shù)據(jù)庫連接url';
COMMENT ON COLUMN "public"."data_server_source"."user_name" IS '數(shù)據(jù)庫用戶名';
COMMENT ON COLUMN "public"."data_server_source"."password" IS '數(shù)據(jù)庫用戶密碼';
COMMENT ON COLUMN "public"."data_server_source"."create_time" IS '創(chuàng)建時間';
COMMENT ON COLUMN "public"."data_server_source"."update_time" IS '更新時間';
COMMENT ON COLUMN "public"."data_server_source"."priority" IS '數(shù)據(jù)庫服務(wù)使用順序(升序)';
COMMENT ON COLUMN "public"."data_server_source"."amount" IS '數(shù)據(jù)服務(wù)建庫數(shù)量';
COMMENT ON COLUMN "public"."data_server_source"."status" IS '使用狀態(tài)(1:正在使用;2:本服務(wù)建庫數(shù)已滿)';
COMMENT ON TABLE "public"."data_server_source" IS '數(shù)據(jù)庫服務(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ù)庫id外鍵即可
注冊用戶時,
調(diào)用DynamicDataSourceService類的getDatabaseId() 方法,將用戶和數(shù)據(jù)庫綁定。
entity.setDatabaseId(dataSourceService.getDatabaseId());
getDatabaseId() 講解 根據(jù)配置的數(shù)據(jù)庫最大用戶數(shù)配置,方法內(nèi)部判斷當(dāng)前數(shù)據(jù)庫用戶數(shù)是否大于配置用戶,沒有則返回當(dāng)前數(shù)據(jù)庫id,有則返回下一個數(shù)據(jù)庫id
使用方法,調(diào)用接口時候,傳入token ,動態(tài)數(shù)據(jù)庫攔截器,自動獲取用戶id,切換對應(yīng)數(shù)據(jù)源。?
到此這篇關(guān)于Springboot實(shí)現(xiàn)根據(jù)用戶ID切換動態(tài)數(shù)據(jù)源的文章就介紹到這了,更多相關(guān)Springboot切換動態(tài)數(shù)據(jù)源內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 如何使用SpringBoot集成Kafka實(shí)現(xiàn)用戶數(shù)據(jù)變更后發(fā)送消息
- SpringBoot3使用Jasypt加密數(shù)據(jù)庫用戶名、密碼等敏感信息
- Spring?Boot應(yīng)用中如何動態(tài)指定數(shù)據(jù)庫實(shí)現(xiàn)不同用戶不同數(shù)據(jù)庫的問題
- SpringBoot+MyBatis實(shí)現(xiàn)MD5加密數(shù)據(jù)庫用戶密碼的方法
- springboot用戶數(shù)據(jù)修改的詳細(xì)實(shí)現(xiàn)
- Springboot項(xiàng)目對數(shù)據(jù)庫用戶名密碼實(shí)現(xiàn)加密過程解析
- Spring Boot管理用戶數(shù)據(jù)的操作步驟
相關(guān)文章
spring定時任務(wù)(scheduler)的串行、并行執(zhí)行實(shí)現(xiàn)解析
這篇文章主要介紹了spring定時任務(wù)(scheduler)的串行、并行執(zhí)行實(shí)現(xiàn)解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-09-09
MyBatis處理mysql主鍵自動增長出現(xiàn)的不連續(xù)問題解決
本文主要介紹了MyBatis處理mysql主鍵自動增長出現(xiàn)的不連續(xù)問題解決,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09
java?集合工具類Collections及Comparable和Comparator排序詳解
這篇文章主要介紹了java集合工具類Collections及Comparable和Comparator排序詳解,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-06-06
詳解Spring Boot實(shí)戰(zhàn)之單元測試
本篇文章主要介紹了詳解Spring Boot實(shí)戰(zhàn)之單元測試,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07

