最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

springboot 按月分表的實(shí)現(xiàn)方式

 更新時(shí)間:2023年04月16日 11:18:24   作者:終成一個(gè)大象  
本文主要介紹了springboot 按月分表的實(shí)現(xiàn)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

一、項(xiàng)目背景

在實(shí)際工作中,會(huì)遇到業(yè)務(wù)比較集中的情況,隨著時(shí)間推延,這部分業(yè)務(wù)關(guān)聯(lián)的mysql表就會(huì)越來(lái)越大,十分臃腫。盡管在項(xiàng)目架構(gòu)上做了讀寫分離,也會(huì)導(dǎo)致查詢的時(shí)候出現(xiàn)比較慢的情況,導(dǎo)致線上慢查詢的出現(xiàn)。

這種情況下導(dǎo)致的慢查詢,單純從sql優(yōu)化的角度是無(wú)法解決的,此時(shí)我們就會(huì)用到分庫(kù)分表。由于我們目前的問(wèn)題是部分mysql表比較大,采用分表的方式即可解決,本文主要討論分表的情況。

1、分表的方式

  • 垂直分表

簡(jiǎn)單理解:把同一個(gè)表中的數(shù)據(jù)按列拆分到不同的表中。

所謂的垂直分表指的是將表結(jié)構(gòu)按照功能模塊、關(guān)系密切程度劃分出來(lái),部署到不同的庫(kù)或者不同的表中。

  • 水平分表

簡(jiǎn)單理解:把同一個(gè)表中的數(shù)據(jù)按行拆分到不同的表中。

所謂的水平分表,即將數(shù)據(jù)按照某種規(guī)則存儲(chǔ)到不同的表中。例如日志表,可以使用按月或者按天分表,即每個(gè)月的日志數(shù)據(jù)單獨(dú)存儲(chǔ)在一張表中。這些表同時(shí)屬于一張主表,擁有相同的表結(jié)構(gòu),但查詢時(shí)可以大大減輕主表查詢的負(fù)擔(dān)。

二、代碼實(shí)現(xiàn)

主要使用mybatis-plus提供的功能來(lái)實(shí)現(xiàn)功能。

1、pom文件依賴

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.1</version>
        </dependency>

2、配置文件

# mybatis-plus 配置
mybatis-plus.configuration.call-setters-on-nulls=true
# xml 文件路徑
mybatis-plus.mapper-locations=classpath*:mapping/*.xml
# entity 文件路徑
mybatis-plus.type-aliases-package=com.geniuworks.bot.entity
# 打印sql語(yǔ)句執(zhí)行日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

# 需要按月分表的表名
mp.tableNames=message

3、MybatisPlusConfig實(shí)現(xiàn)

MybatisPlusConfig配置類實(shí)現(xiàn):

package com.geniuworks.bot.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.parsers.DynamicTableNameParser;
import com.baomidou.mybatisplus.extension.parsers.ITableNameHandler;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.geniuworks.bot.entity.Tables;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @Author dingws
 * @PackageName 
 * @Package 
 * @Date 2022/1/5 1:53 下午
 * @Version 1.0
 */
@Configuration
@Slf4j
public class MybatisPlusConfig {

    @Autowired
    private Tables tableNames;

    /**
     *
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
        dynamicTableNameParser.setTableNameHandlerMap(new HashMap<String, ITableNameHandler>(2){{
            //涉及表集合
            List<String> tables = tableNames.getTableNames();
            //動(dòng)態(tài)表規(guī)則 初始表名+_+code
            tables.forEach(tableTitle -> put(tableTitle,(metaObject, sql, tableName) -> tableName + String.valueOf(getParamValue("month",metaObject))));
        }});
        paginationInterceptor.setSqlParserList(Collections.singletonList(dynamicTableNameParser));
        return paginationInterceptor;
    }

    /**
     *
     * @param title
     * @param metaObject
     * @return
     */
    private Object getParamValue(String title, MetaObject metaObject){
        //獲取參數(shù)
        Object originalObject = metaObject.getOriginalObject();
        JSONObject originalObjectJSON = JSON.parseObject(JSON.toJSONString(originalObject));
        JSONObject boundSql = originalObjectJSON.getJSONObject("boundSql");
        JSONObject parameterObject = boundSql.getJSONObject("parameterObject");
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM");
        if(parameterObject.get(title) == null){
            return "";
        }
        Date date = parameterObject.getObject(title, Date.class);
        log.info("param value = " + formatter.format(date));
        return "_" + formatter.format(date);
    }
}

Tables類實(shí)現(xiàn):

package com.geniuworks.bot.entity;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.util.List;

/**
 * @Author dingws
 * @PackageName 
 * @Package 
 * @Date 2022/1/5 2:18 下午
 * @Version 1.0
 */
@Configuration
@ConfigurationProperties("mp")
@Data
public class Tables {
    private List<String> tableNames;
}

4、優(yōu)雅的使用

在使用的時(shí)候,只需要在mysql表對(duì)應(yīng)的entity里添加一個(gè)字段month即可。

如果month不為空就會(huì)按照month的日期所在的月份對(duì)數(shù)據(jù)庫(kù)表明進(jìn)行動(dòng)態(tài)拼接。如果month為空則不進(jìn)行拼接,直接訪問(wèn)總表。

entity類實(shí)現(xiàn):

package com.geniuworks.bot.entity;

import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Message {
    private String id;

    private String sessionId;

    private Date createdTime;

    private String content;

	// 根據(jù)該字段所在的月分,區(qū)分訪問(wèn)的表名
    private Date month;
}

mapper類實(shí)現(xiàn):

package com.geniuworks.bot.mapper;

import com.geniuworks.bot.entity.Message;
import com.geniuworks.bot.vo.MessageVo;
import com.geniuworks.bot.vo.StatisticsVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Mapper
public interface MessageMapper {

    /**
     * insert record to table
     * @param record the record
     * @return insert count
     */
    int insert(Message record);

    /**
     * insert record to table selective
     * @param record the record
     * @return insert count
     */
    int insertSelective(Message record);

    /**
     * update record selective
     * @param record the updated record
     * @return update count
     */
    int updateByPrimaryKeySelective(Message record);

    /**
     * update record
     * @param record the updated record
     * @return update count
     */
    int updateByPrimaryKey(Message record);

5、mysql表名拆分

需要手動(dòng)把當(dāng)年需要的數(shù)據(jù)庫(kù)手動(dòng)創(chuàng)建出來(lái),命名規(guī)則對(duì)應(yīng)MybatisPlusConfig類中的拼接規(guī)則。

三、遇到的問(wèn)題

由于我一直用的是mybatis組件,需要升級(jí)為mybatis-plus,在升級(jí)的過(guò)程中出現(xiàn)如下的問(wèn)題。

1、Invalid bound statement (not found)

問(wèn)題原因: pom文件依賴的是mybatis-plus,配置文件中使用的是mybatis的配置,導(dǎo)致mybatis加載失敗。

解決方法:把配置文件的mybatis配置改為mybatis-plus配置

2、resultType=“java.util.Map”,返回字段名被包裝

問(wèn)題原因: 在未升級(jí)成mybatis-plus之前,可以直接放回?cái)?shù)據(jù)庫(kù)中的字段命名。 升級(jí)之后,mybatis-plus將放回字段自動(dòng)映射為entity中的字段命名。

解決方案: 梳理受到影響的代碼邏輯,更新使用的字段命名。

到此這篇關(guān)于springboot 按月分表的實(shí)現(xiàn)方式的文章就介紹到這了,更多相關(guān)springboot 按月分表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的事件處理機(jī)制詳細(xì)解讀

    Java中的事件處理機(jī)制詳細(xì)解讀

    這篇文章主要介紹了Java中的事件處理機(jī)制詳細(xì)解讀,ava事件處理是采取"委派事件模型",當(dāng)事件發(fā)生時(shí),產(chǎn)生事件的對(duì)象會(huì)把此"信息"傳遞給"事件的監(jiān)聽者"處理,需要的朋友可以參考下
    2024-01-01
  • JAVA如何判斷上傳文件后綴名是否符合規(guī)范MultipartFile

    JAVA如何判斷上傳文件后綴名是否符合規(guī)范MultipartFile

    這篇文章主要介紹了JAVA判斷上傳文件后綴名是否符合規(guī)范MultipartFile,文中通過(guò)實(shí)例代碼介紹了java實(shí)現(xiàn)對(duì)上傳文件做安全性檢查,需要的朋友可以參考下
    2023-11-11
  • SpringBoot整合MyBatis Plus實(shí)現(xiàn)基本CRUD與高級(jí)功能

    SpringBoot整合MyBatis Plus實(shí)現(xiàn)基本CRUD與高級(jí)功能

    Spring Boot是一款用于快速構(gòu)建Spring應(yīng)用程序的框架,而MyBatis Plus是MyBatis的增強(qiáng)工具,本文將詳細(xì)介紹如何在Spring Boot項(xiàng)目中整合MyBatis Plus,并展示其基本CRUD功能以及高級(jí)功能的實(shí)現(xiàn)方式,需要的朋友可以參考下
    2024-02-02
  • Java Web三層架構(gòu)的配置詳解

    Java Web三層架構(gòu)的配置詳解

    這篇文章主要介紹了Java Web三層架構(gòu)的配置方法,需要的朋友可以參考下
    2014-10-10
  • MyBatis?詳細(xì)講解動(dòng)態(tài)?SQL的使用

    MyBatis?詳細(xì)講解動(dòng)態(tài)?SQL的使用

    動(dòng)態(tài)?SQL?是?MyBatis?的強(qiáng)大特性之一。如果你使用過(guò)?JDBC?或其它類似的框架,你應(yīng)該能理解根據(jù)不同條件拼接?SQL?語(yǔ)句有多痛苦,例如拼接時(shí)要確保不能忘記添加必要的空格,還要注意去掉列表最后一個(gè)列名的逗號(hào)。利用動(dòng)態(tài)?SQL,可以徹底擺脫這種痛苦
    2022-04-04
  • springboot整合mybatis-plus實(shí)現(xiàn)多表分頁(yè)查詢的示例代碼

    springboot整合mybatis-plus實(shí)現(xiàn)多表分頁(yè)查詢的示例代碼

    這篇文章主要介紹了springboot整合mybatis-plus實(shí)現(xiàn)多表分頁(yè)查詢的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 使用okhttp替換Feign默認(rèn)Client的操作

    使用okhttp替換Feign默認(rèn)Client的操作

    這篇文章主要介紹了使用okhttp替換Feign默認(rèn)Client的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • SpringBoot3實(shí)戰(zhàn)教程之實(shí)現(xiàn)接口簽名驗(yàn)證功能

    SpringBoot3實(shí)戰(zhàn)教程之實(shí)現(xiàn)接口簽名驗(yàn)證功能

    接口簽名是一種重要的安全機(jī)制,用于確保 API 請(qǐng)求的真實(shí)性、數(shù)據(jù)的完整性以及防止重放攻擊,這篇文章主要介紹了SpringBoot3實(shí)戰(zhàn)教程之實(shí)現(xiàn)接口簽名驗(yàn)證功能,需要的朋友可以參考下
    2025-04-04
  • 關(guān)于thymeleaf判斷對(duì)象是否為空的相關(guān)邏輯處理

    關(guān)于thymeleaf判斷對(duì)象是否為空的相關(guān)邏輯處理

    這篇文章主要介紹了關(guān)于thymeleaf判斷對(duì)象是否為空的相關(guān)邏輯處理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • 談?wù)凥ttpClient使用詳解

    談?wù)凥ttpClient使用詳解

    這篇文章給大家介紹HttpClient使用,httpClient是一個(gè)客戶端的http通信實(shí)現(xiàn)庫(kù),HttpClient的目標(biāo)是發(fā)送和接收HTTP報(bào)文。本文講解的非常詳細(xì),對(duì)HttpClient使用感興趣的朋友可以參考下
    2015-10-10

最新評(píng)論

仲巴县| 沿河| 新乡县| 敦煌市| 巴彦淖尔市| 长乐市| 鲁甸县| 呼图壁县| 阜宁县| 宜兴市| 屏南县| 纳雍县| 虎林市| 城市| 禄劝| 醴陵市| 博白县| 巴彦淖尔市| 体育| 禄丰县| 镇原县| 广丰县| 资中县| 丰镇市| 长治县| 江北区| 南木林县| 彩票| 申扎县| 明光市| 河东区| 兴安盟| 禹城市| 巴林右旗| 凤冈县| 商都县| 六枝特区| 攀枝花市| 巴东县| 马关县| 和林格尔县|