您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“springboot按月分表的方法是什么”,內容詳細,步驟清晰,細節處理妥當,希望這篇“springboot按月分表的方法是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
在實際工作中,會遇到業務比較集中的情況,隨著時間推延,這部分業務關聯的mysql表就會越來越大,十分臃腫。盡管在項目架構上做了讀寫分離,也會導致查詢的時候出現比較慢的情況,導致線上慢查詢的出現。
這種情況下導致的慢查詢,單純從sql優化的角度是無法解決的,此時我們就會用到分庫分表。由于我們目前的問題是部分mysql表比較大,采用分表的方式即可解決,本文主要討論分表的情況。
垂直分表
簡單理解:把同一個表中的數據按列拆分
到不同的表中。
所謂的垂直分表指的是將表結構按照功能模塊、關系密切程度劃分出來,部署到不同的庫或者不同的表中。
水平分表
簡單理解:把同一個表中的數據按行拆分
到不同的表中。
所謂的水平分表,即將數據按照某種規則存儲到不同的表中。例如日志表,可以使用按月或者按天分表,即每個月的日志數據單獨存儲在一張表中。這些表同時屬于一張主表,擁有相同的表結構,但查詢時可以大大減輕主表查詢的負擔。
主要使用mybatis-plus提供的功能來實現功能。
<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語句執行日志 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl # 需要按月分表的表名 mp.tableNames=message
MybatisPlusConfig配置類實現:
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(); //動態表規則 初始表名+_+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){ //獲取參數 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類實現:
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; }
在使用的時候,只需要在mysql表對應的entity里添加一個字段month即可。
如果month不為空就會按照month的日期所在的月份對數據庫表明進行動態拼接。如果month為空則不進行拼接,直接訪問總表。
entity類實現:
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; // 根據該字段所在的月分,區分訪問的表名 private Date month; }
mapper類實現:
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);
需要手動把當年需要的數據庫手動創建出來,命名規則對應MybatisPlusConfig類中的拼接規則。
由于我一直用的是mybatis組件,需要升級為mybatis-plus,在升級的過程中出現如下的問題。
問題原因: pom文件依賴的是mybatis-plus,配置文件中使用的是mybatis的配置,導致mybatis加載失敗。
解決方法:把配置文件的mybatis配置改為mybatis-plus配置
問題原因: 在未升級成mybatis-plus之前,可以直接放回數據庫中的字段命名。 升級之后,mybatis-plus將放回字段自動映射為entity中的字段命名。
解決方案: 梳理受到影響的代碼邏輯,更新使用的字段命名。
讀到這里,這篇“springboot按月分表的方法是什么”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。