All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.taotao.boot.data.shardingsphere.algorithm.ModuloShardingDatabaseDateYearAlgorithm Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2020-2030, Shuigedeng ([email protected] & https://blog.taotaocloud.top/).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.taotao.boot.data.shardingsphere.algorithm;

import com.google.common.collect.Range;
import com.taotao.boot.common.utils.log.LogUtils;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
import org.springframework.context.annotation.Configuration;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

@Configuration
public class ModuloShardingDatabaseDateYearAlgorithm implements StandardShardingAlgorithm {
    private int ModedID = 5;
    private static final String DataBase_NAME = "ds_";

    // 获得日期字段中年份数字,如果年份<1995,返回1995
    private int getYearFromString(String value) throws ParseException {
        int nYear = -1;
        try {
            if (null == value || "".equals(value) || value.length() < 4) {
                Date date = new Date();
                return date.getYear();
            } else {
                try {
                    nYear = Integer.parseInt(value.substring(0, 4));
                } catch (Exception e) {
                    Date date = new Date();
                    return date.getYear();
                }
            }
            if (nYear < 1995) {
                nYear = 1995;
            }
        } catch (Exception e) {
            Date date = new Date();
            return date.getYear();
        }
        return nYear;
    }

    /*
     *databaseNamescollection:配置文件中定义的数据库名称集合
     *shardingValue:insert,select,update,delate时,Create_Date字段值
     *函数返回值:返回函数值shardingValue经过取余计算后对于的数据库名称。比如 1995%4 =3,返回数据库名称是ds_3
     */
    @Override
    public String doSharding(Collection availableTargetNames, PreciseShardingValue shardingValue) {
        if (shardingValue != null) {
            String value = shardingValue.getValue(); // 获取传递的字段值

            int nYear = -1;
            try {
                nYear = getYearFromString(value); // 获取年份

            } catch (ParseException e) {

				LogUtils.error(e);
            }
            // 对年份取余,将余数跟数据库前缀组合成数据库名称,
            // 检查这个名称是否在配置文件数据库集合中,如果存在返回数据库名称
            for (String each : availableTargetNames) {
                if (each.equals(DataBase_NAME + String.valueOf(nYear % 4))) {
                    return each;
                }
            }
            throw new UnsupportedOperationException("content_channel没有匹配到可用数据库节点");
        } else {
            throw new UnsupportedOperationException("分片列为空");
        }
    }

    /*
     *databaseNamescollection:配置文件中定义的数据库名称集合
     *rangeShardingValue:insert,select,update,delate时,Create_Date 范围查询字段值。比如 between 2015-01-01 and 2021-01-01,存储的就是 2015-01-01和2021-01-01
     *函数返回值:返回函数值rangeShardingValue经过取余计算后对于的数据库名称。比如 between 2015-01-01 and 2021-01-01 ,根据这时间段年份,得到返回的集合是ds_0,ds_1,ds_2,ds_3
     */

    @Override
    public Collection doSharding(
            Collection databaseNamescollection, RangeShardingValue rangeShardingValue) {

        Collection collect = new ArrayList<>();
        if (rangeShardingValue != null) {
            Range valueRange = rangeShardingValue.getValueRange(); // 获得范围区间值
            String slowerEndpointDate =
                    String.valueOf(valueRange.hasLowerBound() ? valueRange.lowerEndpoint() : ""); // 获得返回区间值下限
            String supperEndpointDate =
                    String.valueOf(valueRange.hasUpperBound() ? valueRange.upperEndpoint() : ""); // 获得范围区间值上限

            int nStartYear = -1;
            int nEndYear = -1;
            try {

                nStartYear = getYearFromString(slowerEndpointDate); // 获得下限年份
                nEndYear = getYearFromString(supperEndpointDate); // 获得上限年份

                if (nStartYear == -1 && nEndYear != -1) { // 下限年份为空时,上限不为空时,下限=上限-5
                    nStartYear = nEndYear - ModedID;
                } else if (nStartYear != -1 && nEndYear == -1) { // 下限不为空,上限为空,上限=下限+5
                    nEndYear = nStartYear + ModedID;
                }
            } catch (ParseException e) {

				LogUtils.error(e);
            }

            // 根据上下限范围,循环取值判断对应的数据库名称,返回数据库名称集合
            for (String each : databaseNamescollection) {
                for (int i = nStartYear; i <= nEndYear; i++) {
                    if (each.equals(DataBase_NAME + String.valueOf(i % 4))) {
                        if (!collect.contains(each)) {
                            collect.add(each);
                        }
                    }
                }
            }
            return collect;

        } else {
            throw new UnsupportedOperationException("分片列为空");
        }
    }

    @Override
    public String getType() {
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy