日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

SharDingJDBC-4.0.0-RC1按月水平分表

作者:Coder-CT 更新時(shí)間: 2022-02-19 編程語(yǔ)言

廢話(huà)不多說(shuō),上代碼!

         <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.0.0-RC1</version>
        </dependency>

關(guān)鍵配置yml

spring:
  #shardingjdbc主要配置
  main:
    allow-bean-definition-overriding: true #Bean覆蓋,srpingboot2.1以上默認(rèn)是false,一個(gè)實(shí)體類(lèi)對(duì)應(yīng)多張表,水平分表必須加
  shardingsphere:
    datasource:
      names: h1 #單數(shù)據(jù)源,多個(gè)以逗號(hào)隔開(kāi)
      h1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://rm-.mysql.cn-chengdu.rds.aliyuncs.com:3306/chen
        username: chen
        password: chen
    sharding:
     # binding-tables: hss_history #綁定表,需要關(guān)聯(lián)查詢(xún)的時(shí)候配置
      tables:
        hss_history: #邏輯表  下面是節(jié)點(diǎn)表,分表后還有數(shù)據(jù)在原來(lái)的表,所有查詢(xún)節(jié)點(diǎn)需要加上原來(lái)的表
          actual-data-nodes: h1.hss_history,h1.hss_history_202$->{201..204}
          key-generator: #主鍵生成策略 雪花算法,
            column: id
            type: SNOWFLAKE
          table-strategy:
            standard:  #分片策略 以創(chuàng)建時(shí)候分表,實(shí)現(xiàn)類(lèi)計(jì)算
              sharding-column: create_time
              #對(duì)應(yīng)下面的分表策略類(lèi)
              precise-algorithm-class-name: work.chen.history.config.TableShardingAlgorithm
              range-algorithm-class-name: work.chen.history.config.TableShardingAlgorithm
      #多數(shù)據(jù)源指定默認(rèn)數(shù)據(jù)源,兩個(gè)數(shù)據(jù)源其中一個(gè)數(shù)據(jù)源不參于分表可以設(shè)置
      #default-data-source-name: h1
    props:
      sql: #展示SQL 測(cè)試的時(shí)候可以改為true
        show: false

actual-data-nodes: h1.hss_history,h1.hss_history_202$->{201…204}
這代表可以查詢(xún)的表,有多少表就配多少,原始表hss_history,還有hss_history_202201-202204
如果這里配的節(jié)點(diǎn)表,數(shù)據(jù)庫(kù)中不存在,那么查詢(xún)的時(shí)候就會(huì)報(bào)錯(cuò) 找不到表,需要提前創(chuàng)建好表,
配了shardingjdbc 有些sql語(yǔ)句就不支持了,
SQL支持查詢(xún)
解決這個(gè)辦法,只有分多個(gè)數(shù)據(jù)源,不參于分表的數(shù)據(jù)源改為默認(rèn)的就不會(huì)使用sharding的數(shù)據(jù)源

分表具體策略

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;
import work.chenshuang.history.service.impl.HssHistoryService;
import work.chenshuang.history.utils.DateUtil;

import java.awt.image.ImageConsumer;
import java.util.Collection;
import java.util.Date;
import java.util.List;


// 分表規(guī)則
//按單月分表
public class TableShardingAlgorithm implements PreciseShardingAlgorithm<Date>,RangeShardingAlgorithm<Long> {
    //@Autowired不能注入
    private static HssHistoryService hssHistory = (HssHistoryService) SpringUtil.getBean(HssHistoryService.class);

    //精確插入表名  單表
    @Override
    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Date> preciseShardingValue) {
        StringBuffer tableName = new StringBuffer();
        //表名精確匹配,表名加上截取的年月
        tableName.append(preciseShardingValue.getLogicTableName())
                //時(shí)間戳轉(zhuǎn)成date類(lèi)型
                .append("_").append(DateUtil.date2Str(preciseShardingValue.getValue(), DateUtil.YEAR_MONTH_NUMBER));
        // System.out.println("表名為:"+tableName.toString());
        // System.out.println("邏輯表名"+preciseShardingValue.getLogicTableName());
        System.out.println("時(shí)間"+preciseShardingValue.getValue());
        //availableTargetNames存的是節(jié)點(diǎn)表名字,可以查詢(xún)的表
        //單數(shù)據(jù)源這里就會(huì)有問(wèn)題,sql有問(wèn)題 @Select("select table_name from information_schema.tables where TABLE_SCHEMA=(select database())")
        //List<String> tableNames = hssHistory.queryTableNames();
        //創(chuàng)建表
        //hssHistory.createTable(tableName.toString());
        return tableName.toString();
    }

    @Override
    public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Long> shardingValue) {
        return null;
    }
}

時(shí)間工具類(lèi)


import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
public class DateUtil {

    public static final String DATE_FORMAT_DEFAULT = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_FORMAT_NUMBER = "yyyyMMddHHmmss";
    public static final String YEAR_MONTH_DAY_NUMBER = "yyyyMMdd";
    public static final String YEAR_MONTH_NUMBER = "yyyyMM";
    public static final String DATE_FORMAT_DAY_PATTERN = "yyyy-MM-dd";
    public static final String YEAR_MONTH_DAY_EN_SECOND = "yyyy/MM/dd HH:mm:ss";
    public static final String YEAR_MONTH_DAY_CN_SECOND = "yyyy年MM月dd日 HH時(shí)mm分ss秒";
    public static final String YEAR_MONTH_DAY_CN = "yyyy年MM月dd日";

    /**
     * 采用 ThreadLocal 避免 SimpleDateFormat 非線(xiàn)程安全的問(wèn)題
     * <p>
     * Key —— 時(shí)間格式
     * Value —— 解析特定時(shí)間格式的 SimpleDateFormat
     */
    private static ThreadLocal<Map<String, SimpleDateFormat>> sThreadLocal = new ThreadLocal<>();


    /**
     * 獲取解析特定時(shí)間格式的 SimpleDateFormat
     *
     * @param pattern 時(shí)間格式
     */
    private static SimpleDateFormat getDateFormat(String pattern) {
        if (StringUtils.isBlank(pattern)) {
            pattern = DATE_FORMAT_DEFAULT;
        }
        Map<String, SimpleDateFormat> strDateFormatMap = sThreadLocal.get();
        if (strDateFormatMap == null) {
            strDateFormatMap = new HashMap<>();
        }

        SimpleDateFormat simpleDateFormat = strDateFormatMap.get(pattern);
        if (simpleDateFormat == null) {
            simpleDateFormat = new SimpleDateFormat(pattern, Locale.getDefault());
            strDateFormatMap.put(pattern, simpleDateFormat);
            sThreadLocal.set(strDateFormatMap);
        }
        return simpleDateFormat;
    }


    public static Date toDate(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static String format(LocalDateTime dateTime, String format) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.format(DateTimeFormatter.ofPattern(format));
    }

    public static LocalDateTime parse(String dateTimeStr, String format) {
        if (StringUtils.isBlank(format)) {
            format = DATE_FORMAT_DEFAULT;
        }
        if (dateTimeStr == null) {
            return null;
        }
        DateTimeFormatter sf = DateTimeFormatter.ofPattern(format);
        LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, sf);
        return dateTime;
    }

    public static String format(LocalDateTime dateTime) {
        return format(dateTime, DATE_FORMAT_DEFAULT);
    }

    public static LocalDateTime parse(String dateTimeStr) {
        return parse(dateTimeStr, DATE_FORMAT_DEFAULT);
    }

    // #############################################################################

    /**
     * 時(shí)間格式轉(zhuǎn)換為字符串格式
     *
     * @param date   時(shí)間
     * @param format 格式 如("yyyy-MM-dd hh:mm:ss")
     * @return String
     */
    public static String date2Str(Date date, String format) {
        if (StringUtils.isBlank(format)) {
            format = DATE_FORMAT_DEFAULT;
        }
        if (date == null) {
            return null;
        }
        return getDateFormat(format).format(date);
    }

    /**
     * 字符串格式轉(zhuǎn)換為時(shí)間格式
     *
     * @param dateStr 字符串
     * @param format  格式 如("yyyy-MM-dd HH:mm:ss")
     * @return Date
     */
    public static Date str2Date(String dateStr, String format) {
        if (StringUtils.isBlank(format)) {
            format = DATE_FORMAT_DEFAULT;
        }
        if (StringUtils.isBlank(dateStr)) {
            return null;
        }
        try {
            return getDateFormat(format).parse(dateStr);
        } catch (ParseException pe) {
            log.error("str2Date ParseException error", pe);
        }
        return null;
    }

    public static Date dateFormat(Date date, String format) {
        if (StringUtils.isBlank(format)) {
            format = DATE_FORMAT_DEFAULT;
        }
        if (date == null) {
            return null;
        }
        return str2Date(date2Str(date, format), format);
    }

    /**
     * @param timestamp:時(shí)間
     */
    public static Date parse(long timestamp) {
        return new Date(timestamp);
    }

    /**
     * 獲取當(dāng)前日期
     *
     * @param pattern 格式如:yyyy-MM-dd
     * @return
     */
    public static String getCurrentDate(String pattern) {
        return getDateFormat(pattern).format(new Date());
    }

    /**
     * get cuurent Date return java.util.Date type
     */
    public static Date getCurrentDate() {
        return new Date();
    }

    /**
     * get current Date return java.sql.Date type
     *
     * @return
     */
    public static java.sql.Date getNowSqlDate() {
        return new java.sql.Date(System.currentTimeMillis());
    }

    /**
     * get the current timestamp return java.sql.Timestamp
     *
     * @return
     */
    public static Timestamp getNowTimestamp() {
        return new Timestamp(System.currentTimeMillis());
    }

    public static String timestamp2Str(Timestamp time, String format) {
        return getDateFormat(format).format(time);
    }

    public static Date timestamp2Date(Timestamp time, String format) throws ParseException {
        return str2Date(timestamp2Str(time, format), format);
    }

    public static Timestamp str2Timestamp(Timestamp time, String format) throws ParseException {
        Date date = str2Date(timestamp2Str(time, format), format);
        return new Timestamp(date.getTime());
    }

    public static Timestamp date2Timestamp(Date date, String format) {
        Date result = str2Date(date2Str(date, format), format);
        return new Timestamp(result.getTime());
    }

    /**
     * time1>time2 返回正數(shù)
     *
     * @param time1
     * @param time2
     * @return
     */
    public static long getOffsetBetweenTimes(String time1, String time2) {
        return str2Date(time1, DATE_FORMAT_DEFAULT).getTime() - str2Date(time2, DATE_FORMAT_DEFAULT).getTime();
    }


    /**
     * 返回時(shí)間差
     *
     * @param start
     * @param end
     * @param timeUnit 天d, 時(shí)h, 分m, 秒s
     * @return 根據(jù)timeUnit返回
     */
    public static long getOffsetBetweenDate(Date start, Date end, char timeUnit) {
        long startT = start.getTime(); //定義上機(jī)時(shí)間
        long endT = end.getTime();  //定義下機(jī)時(shí)間

        long ss = (startT - endT) / (1000); //共計(jì)秒數(shù)
        int mm = (int) ss / 60;   //共計(jì)分鐘數(shù)
        int hh = (int) ss / 3600;  //共計(jì)小時(shí)數(shù)
        int dd = hh / 24;   //共計(jì)天數(shù)
        System.out.println("######################## 共" + dd + "天 準(zhǔn)確時(shí)間是:" + hh + " 小時(shí) " + mm + " 分鐘" + ss + " 秒 共計(jì):" + ss * 1000 + " 毫秒");

        long result = 0L;
        if ('d' == timeUnit) {
            result = dd;
        } else if ('h' == timeUnit) {
            result = hh;
        } else if ('m' == timeUnit) {
            result = mm;
        } else if ('s' == timeUnit) {
            result = ss;
        }
        return result;
    }

    /**
     * 對(duì)指定日期滾動(dòng)指定天數(shù),負(fù)數(shù)時(shí),則往前滾,正數(shù)時(shí),則往后滾
     *
     * @param date Date
     * @param days int
     * @return String
     */
    public static String rollDays(Date date, int days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, days);
        return date2Str(calendar.getTime(), DATE_FORMAT_DEFAULT);
    }

    /**
     * 對(duì)指定日期滾動(dòng)指定分鐘,負(fù)數(shù)時(shí),則往前滾,正數(shù)時(shí),則往后滾
     *
     * @param date    Date
     * @param minutes int
     * @return String
     */
    public static String rollMinutes(Date date, int minutes) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minutes);
        return date2Str(calendar.getTime(), DATE_FORMAT_DEFAULT);
    }

    /**
     * 對(duì)指定日期滾動(dòng)指定分鐘,負(fù)數(shù)時(shí),則往前滾,正數(shù)時(shí),則往后滾
     *
     * @param date    Date
     * @param seconds int
     * @return String
     */
    public static String rollSeconds(Date date, int seconds, String format) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, seconds);
        return date2Str(calendar.getTime(), format);
    }

    /**
     * 返回  2013-01-16T06:24:26.829Z 時(shí)間
     *
     * @param date
     * @return
     * @throws Exception
     */
    public static XMLGregorianCalendar getXmlDatetime(Date date) throws Exception {
        if (null == date) {
            date = new Date();
        }
        GregorianCalendar nowGregorianCalendar = new GregorianCalendar();
        XMLGregorianCalendar xmlDatetime = DatatypeFactory.newInstance().newXMLGregorianCalendar(nowGregorianCalendar);
        // XMLGregorianCalendar ->GregorianCalendar
        nowGregorianCalendar = xmlDatetime.toGregorianCalendar();
        nowGregorianCalendar.setTime(date);
        return xmlDatetime;
    }

    public static boolean checkDateBettwenBoth(Date checkDate, Date date1, Date date2) {
        boolean temp = false;
        if (checkDate == null || date1 == null || date2 == null) {
            temp = false;
            return temp;
        }

        if (checkDate.equals(date1) || checkDate.equals(date2)) {
            temp = true;
        }

        if (checkDate.after(date1) && checkDate.before(date2)) {
            temp = true;
        }

        return temp;
    }

    public static String getFormatDatetime() throws Exception {
        GregorianCalendar gCalendar = new GregorianCalendar();
        String strDateTime;
        try {
            strDateTime = getDateFormat(DATE_FORMAT_DEFAULT).format(gCalendar.getTime());
        } catch (Exception ex) {
            System.out.println("Error Message:".concat(String.valueOf(String.valueOf(ex.toString()))));
            String s = null;
            return s;
        }
        return strDateTime;
    }


    /**
     * 判斷給定的日期是一年中的第幾天
     *
     * @param dateTimeStr
     * @return
     */
    public static int dayOfYear(String dateTimeStr) {
        int day = 0;
        if (StringUtils.isBlank(dateTimeStr)) {
            return day;
        }
        Date dateTime = str2Date(dateTimeStr, DATE_FORMAT_DEFAULT);
        return dayOfYear(dateTime);
    }


    /**
     * 判斷給定的日期是一年中的第幾天
     *
     * @param dateTime
     * @return
     */
    public static int dayOfYear(Date dateTime) {
        int year = 0, month = 0, date = 0, day = 0;
        if (null == dateTime) {
            return day;
        }
        String dateTimeStr = date2Str(dateTime, null);
        LocalDateTime localDateTime = parse(dateTimeStr);
        year = localDateTime.getYear();
        month = localDateTime.getMonthValue();
        date = localDateTime.getDayOfMonth();
        return dayOfYear(year, month, date);
    }


    /**
     * 判斷給定的日期是一年中的第幾天
     *
     * @param year
     * @param month
     * @param date
     * @return
     */
    public static int dayOfYear(int year, int month, int date) {
        int[] days = {0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int day = 0;
        //判斷是不是閏年,然后設(shè)置二月的天數(shù)
        if ((year % 400 == 0) || ((year % 100 != 0) && (year % 4 == 0))) {
            days[2] = 29;
        } else {
            days[2] = 28;
        }
        for (int i = 1; i < month; i++) {
            day += days[i];
        }
        day += date;
        return day;
    }



    /*public static void main(String[] args){
        System.out.print(new Date());
    }*/
}

上面這個(gè)工具類(lèi)不導(dǎo)依賴(lài)會(huì)報(bào)錯(cuò)

  <!-- sfl4j -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.7</version>
        </dependency>

注入工具類(lèi)

package work.chenshuang.history.config;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class SpringUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext = null;

    public SpringUtil() {
    }

    public void setApplicationContext(ApplicationContext arg0) throws BeansException {
        if (applicationContext == null) {
            applicationContext = arg0;
        }

    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static void setAppCtx(ApplicationContext webAppCtx) {
        if (webAppCtx != null) {
            applicationContext = webAppCtx;
        }
    }

    /**
     * 拿到ApplicationContext對(duì)象實(shí)例后就可以手動(dòng)獲取Bean的注入實(shí)例對(duì)象
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    public static <T> T getBean(String name, Class<T> clazz) throws ClassNotFoundException {
        return getApplicationContext().getBean(name, clazz);
    }

    public static final Object getBean(String beanName) {
        return getApplicationContext().getBean(beanName);
    }

    public static final Object getBean(String beanName, String className) throws ClassNotFoundException {
        Class clz = Class.forName(className);
        return getApplicationContext().getBean(beanName, clz.getClass());
    }

    public static boolean containsBean(String name) {
        return getApplicationContext().containsBean(name);
    }

    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
        return getApplicationContext().isSingleton(name);
    }

    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
        return getApplicationContext().getType(name);
    }

    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
        return getApplicationContext().getAliases(name);
    }
}

配置完就可以使用了 提前創(chuàng)建好表就行了 ,動(dòng)態(tài)創(chuàng)建表可以,但節(jié)點(diǎn)表沒(méi)法動(dòng)態(tài)改變,節(jié)點(diǎn)表不改變,查詢(xún)就只會(huì)查那配置好的表,有懂的大佬還望告知!

原文鏈接:https://blog.csdn.net/weixin_51216079/article/details/122670250

欄目分類(lèi)
最近更新