您好,登錄后才能下訂單哦!
本文小編為大家詳細(xì)介紹“springboot按月分表的方法是什么”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“springboot按月分表的方法是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。
在實(shí)際工作中,會(huì)遇到業(yè)務(wù)比較集中的情況,隨著時(shí)間推延,這部分業(yè)務(wù)關(guān)聯(lián)的mysql表就會(huì)越來(lái)越大,十分臃腫。盡管在項(xiàng)目架構(gòu)上做了讀寫(xiě)分離,也會(huì)導(dǎo)致查詢(xún)的時(shí)候出現(xiàn)比較慢的情況,導(dǎo)致線(xiàn)上慢查詢(xún)的出現(xiàn)。
這種情況下導(dǎo)致的慢查詢(xún),單純從sql優(yōu)化的角度是無(wú)法解決的,此時(shí)我們就會(huì)用到分庫(kù)分表。由于我們目前的問(wèn)題是部分mysql表比較大,采用分表的方式即可解決,本文主要討論分表的情況。
垂直分表
簡(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),但查詢(xún)時(shí)可以大大減輕主表查詢(xún)的負(fù)擔(dān)。
主要使用mybatis-plus提供的功能來(lái)實(shí)現(xiàn)功能。
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.1</version> </dependency>
# 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
MybatisPlusConfig配置類(lèi)實(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類(lèi)實(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; }
在使用的時(shí)候,只需要在mysql表對(duì)應(yīng)的entity里添加一個(gè)字段month即可。
如果month不為空就會(huì)按照month的日期所在的月份對(duì)數(shù)據(jù)庫(kù)表明進(jìn)行動(dòng)態(tài)拼接。如果month為空則不進(jìn)行拼接,直接訪(fǎng)問(wèn)總表。
entity類(lèi)實(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ū)分訪(fǎng)問(wèn)的表名 private Date month; }
mapper類(lèi)實(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);
需要手動(dòng)把當(dāng)年需要的數(shù)據(jù)庫(kù)手動(dòng)創(chuàng)建出來(lái),命名規(guī)則對(duì)應(yīng)MybatisPlusConfig類(lèi)中的拼接規(guī)則。
由于我一直用的是mybatis組件,需要升級(jí)為mybatis-plus,在升級(jí)的過(guò)程中出現(xiàn)如下的問(wèn)題。
問(wèn)題原因: pom文件依賴(lài)的是mybatis-plus,配置文件中使用的是mybatis的配置,導(dǎo)致mybatis加載失敗。
解決方法:把配置文件的mybatis配置改為mybatis-plus配置
問(wèn)題原因: 在未升級(jí)成mybatis-plus之前,可以直接放回?cái)?shù)據(jù)庫(kù)中的字段命名。 升級(jí)之后,mybatis-plus將放回字段自動(dòng)映射為entity中的字段命名。
解決方案: 梳理受到影響的代碼邏輯,更新使用的字段命名。
讀到這里,這篇“springboot按月分表的方法是什么”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。