¶Ô±ÈÐÂÎļþ |
| | |
| | | /* |
| | | * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
| | | * |
| | | * Redistribution and use in source and binary forms, with or without |
| | | * modification, are permitted provided that the following conditions are met: |
| | | * |
| | | * Redistributions of source code must retain the above copyright notice, |
| | | * this list of conditions and the following disclaimer. |
| | | * Redistributions in binary form must reproduce the above copyright |
| | | * notice, this list of conditions and the following disclaimer in the |
| | | * documentation and/or other materials provided with the distribution. |
| | | * Neither the name of the dreamlu.net developer nor the names of its |
| | | * contributors may be used to endorse or promote products derived from |
| | | * this software without specific prior written permission. |
| | | * Author: Chill åºéª (smallchill@163.com) |
| | | */ |
| | | package org.springblade.core.tenant.dynamic; |
| | | |
| | | import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; |
| | | import com.baomidou.dynamic.datasource.creator.DataSourceCreator; |
| | | import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; |
| | | import lombok.AllArgsConstructor; |
| | | import org.springblade.core.cache.utils.CacheUtil; |
| | | import org.springblade.core.tool.utils.StringUtil; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.jdbc.core.BeanPropertyRowMapper; |
| | | import org.springframework.jdbc.core.JdbcTemplate; |
| | | |
| | | import javax.sql.DataSource; |
| | | import java.util.Set; |
| | | |
| | | import static org.springblade.core.tenant.constant.TenantBaseConstant.*; |
| | | |
| | | /** |
| | | * ç§æ·æ°æ®æºæ ¸å¿å¤çç±» |
| | | * |
| | | * @author Chill |
| | | */ |
| | | @AllArgsConstructor |
| | | public class TenantDataSourceHolder { |
| | | |
| | | private final DataSource dataSource; |
| | | private final DataSourceCreator dataSourceCreator; |
| | | private final JdbcTemplate jdbcTemplate; |
| | | |
| | | /** |
| | | * æ°æ®æºç¼åå¤ç |
| | | * |
| | | * @param tenantId ç§æ·ID |
| | | */ |
| | | public void handleDataSource(String tenantId) { |
| | | // è·åå¨åçæ°æ®æºéå |
| | | DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource; |
| | | Set<String> keys = ds.getCurrentDataSources().keySet(); |
| | | // é
ç½®ä¸åå¨åå¨ææ·»å æ°æ®æºï¼ä»¥æå è½½çæ¨¡å¼è§£å³åå¸å¼åºæ¯çé
ç½®åæ¥ |
| | | // 为äºä¿è¯æ°æ®å®æ´æ§ï¼é
ç½®åçææ°æ®æºç¼åï¼åå°ä¾¿æ æ³ä¿®æ¹æ´æ¢æ°æ®æºï¼è¥ä¸å®è¦ä¿®æ¹è¯·è¿ç§»æ°æ®åé坿塿èªè¡ä¿®æ¹åºå±é»è¾ |
| | | if (!keys.contains(tenantId)) { |
| | | TenantDataSource tenantDataSource = getDataSource(tenantId); |
| | | if (tenantDataSource != null) { |
| | | // åå»ºæ°æ®æºé
ç½® |
| | | DataSourceProperty dataSourceProperty = new DataSourceProperty(); |
| | | // æ·è´æ°æ®æºé
ç½® |
| | | BeanUtils.copyProperties(tenantDataSource, dataSourceProperty); |
| | | // å
³éæå è½½ |
| | | dataSourceProperty.setLazy(Boolean.FALSE); |
| | | // åå»ºå¨ææ°æ®æº |
| | | DataSource dataSource = dataSourceCreator.createDataSource(dataSourceProperty); |
| | | // æ·»å ææ°æ°æ®æº |
| | | ds.addDataSource(tenantId, dataSource); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¤æç§æ·æ¯å¦ææ°æ®æºé
ç½® |
| | | * |
| | | * @param tenantId ç§æ·ID |
| | | */ |
| | | private Boolean existDataSource(String tenantId) { |
| | | // å°ç§æ·æ¯å¦é
ç½®æ°æ®æºè¿è¡ç¼åï¼è¥éæ°é
ç½®ä¼å°æ¤ç¼åæ¸
空并å¨ä¸æ¬¡è¯·æ±çæ¶åæå è½½ |
| | | // è¥ç§æ·æ²¡æé
ç½®æ°æ®æºåä¼èªå¨ä½¿ç¨masteræ°æ®æºï¼æ¤ä¸¾æ¯ä¸ºäºé¿å
卿²¡ææ°æ®åºçæ¶åé¢ç¹æ¥è¯¢å¯¼è´ç¼åå»ç©¿ |
| | | Boolean exist = CacheUtil.get(TENANT_DATASOURCE_CACHE, TENANT_DATASOURCE_EXIST_KEY, tenantId, Boolean.class, Boolean.FALSE); |
| | | if (exist == null) { |
| | | TenantDataSource tenantDataSource = jdbcTemplate.queryForObject(TENANT_DATASOURCE_EXIST_STATEMENT, new String[]{tenantId}, new BeanPropertyRowMapper<>(TenantDataSource.class)); |
| | | if (tenantDataSource != null && StringUtil.isNotBlank(tenantDataSource.getDatasourceId())) { |
| | | exist = Boolean.TRUE; |
| | | } else { |
| | | exist = Boolean.FALSE; |
| | | } |
| | | CacheUtil.put(TENANT_DATASOURCE_CACHE, TENANT_DATASOURCE_EXIST_KEY, tenantId, exist, Boolean.FALSE); |
| | | } |
| | | return exist; |
| | | } |
| | | |
| | | /** |
| | | * è·å对åºçæ°æ®æºé
ç½® |
| | | * |
| | | * @param tenantId ç§æ·ID |
| | | */ |
| | | private TenantDataSource getDataSource(String tenantId) { |
| | | // ä¸åå¨ç§æ·æ°æ®æºåè¿å空ï¼é²æ¢ç¼åå»ç©¿ |
| | | if (!existDataSource(tenantId)) { |
| | | return null; |
| | | } |
| | | // è·åç§æ·æ°æ®æºä¿¡æ¯ |
| | | TenantDataSource tenantDataSource = CacheUtil.get(TENANT_DATASOURCE_CACHE, TENANT_DATASOURCE_KEY, tenantId, TenantDataSource.class, Boolean.FALSE); |
| | | if (tenantDataSource == null) { |
| | | tenantDataSource = jdbcTemplate.queryForObject(TENANT_DATASOURCE_SINGLE_STATEMENT, new String[]{tenantId}, new BeanPropertyRowMapper<>(TenantDataSource.class)); |
| | | if (tenantDataSource != null && StringUtil.isNoneBlank(tenantDataSource.getTenantId(), tenantDataSource.getDriverClass(), tenantDataSource.getUrl(), tenantDataSource.getUsername(), tenantDataSource.getPassword())) { |
| | | CacheUtil.put(TENANT_DATASOURCE_CACHE, TENANT_DATASOURCE_KEY, tenantId, tenantDataSource, Boolean.FALSE); |
| | | } else { |
| | | tenantDataSource = null; |
| | | } |
| | | } |
| | | return tenantDataSource; |
| | | } |
| | | |
| | | } |