001/*
002 *  Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.mybatisflex.core.datasource;
017
018import java.lang.reflect.Method;
019import java.util.function.Supplier;
020
021/**
022 * @author michael
023 */
024public class DataSourceKey {
025
026    /**
027     * 通过注解设置的 key
028     */
029    private static ThreadLocal<String> annotationKeyThreadLocal = new ThreadLocal<>();
030
031    /**
032     * 通过手动编码指定的 key
033     */
034    private static ThreadLocal<String> manualKeyThreadLocal = new ThreadLocal<>();
035
036    private DataSourceKey() {
037    }
038
039    public static void use(String dataSourceKey) {
040        manualKeyThreadLocal.set(dataSourceKey.trim());
041    }
042
043    public static void useWithAnnotation(String dataSourceKey) {
044        annotationKeyThreadLocal.set(dataSourceKey.trim());
045    }
046
047    public static <T> T use(String dataSourceKey, Supplier<T> supplier) {
048        try {
049            use(dataSourceKey);
050            return supplier.get();
051        } finally {
052            clear();
053        }
054    }
055
056    public static void use(String dataSourceKey, Runnable runnable) {
057        try {
058            use(dataSourceKey);
059            runnable.run();
060        } finally {
061            clear();
062        }
063    }
064
065    public static void clear() {
066        annotationKeyThreadLocal.remove();
067        manualKeyThreadLocal.remove();
068    }
069
070    public static String getByAnnotation() {
071        return annotationKeyThreadLocal.get();
072    }
073
074    public static String getByManual() {
075        return manualKeyThreadLocal.get();
076    }
077
078    public static String get() {
079        String key = manualKeyThreadLocal.get();
080        return key != null ? key : annotationKeyThreadLocal.get();
081    }
082
083    public static void setAnnotationKeyThreadLocal(ThreadLocal<String> annotationKeyThreadLocal) {
084        DataSourceKey.annotationKeyThreadLocal = annotationKeyThreadLocal;
085    }
086
087    public static void setManualKeyThreadLocal(ThreadLocal<String> manualKeyThreadLocal) {
088        DataSourceKey.manualKeyThreadLocal = manualKeyThreadLocal;
089    }
090
091    public static String getByShardingStrategy(String dataSource, Object mapper, Method method, Object[] args) {
092        String shardingDsKey = DataSourceManager.getByShardingStrategy(dataSource, mapper, method, args);
093        return shardingDsKey != null ? shardingDsKey : dataSource;
094    }
095}