技术标签: jeecgboot分表 javaWeb知识 mybatis分表 mysql分表实现
在jeecgboot 使用mybatis框架,mybatis-plus3.1.1后支持分表,以下是在jeecg项目中实行分表
一、修改mybatis-plus版本后,必须要在3.1.1版本后
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.1.2</version>
</dependency>
二、修改entity实体把@TableName注释掉
@Data
//@TableName("empss_visual_meter_usage_hour")
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="empss_visual_meter_usage_hour对象", description="表具每小时用量")
public class UsageHour{
/**统计时间*/
@Excel(name = "统计时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "统计时间")
private java.util.Date statTime;
/**表具编号*/
@Excel(name = "表具编号", width = 15)
@ApiModelProperty(value = "表具编号")
private java.lang.String code;
}
其他的controller、service、mapperd类等不需要改变
三、修改MybatisPlusConfig配置类paginationInterceptor()方法
@Bean
public PaginationInterceptor paginationInterceptor() {
// return new PaginationInterceptor();
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
DynamicTableNameParser dynamicTableNameParser = new DynamicTableNameParser();
dynamicTableNameParser.setTableNameHandlerMap(new HashMap<String, ITableNameHandler>(2) {
{
//实现entity中usageHour类分表,这里按statTime,statTime为Date类型,分表时要转为年和类,注意usage_hour对应usageHour类的类名
put("usage_hour", (metaObject, sql, tableName) -> {
// 通过metaObject 可以获取传入参数,这里实现你自己的动态规则
//获取参数
Object originalObject = metaObject.getOriginalObject();
JSONObject originalObjectJSON = JSON.parseObject(JSON.toJSONString(originalObject));
JSONObject boundSql = originalObjectJSON.getJSONObject("boundSql");
JSONObject parameterObject = boundSql.getJSONObject("parameterObject");
String valueOf = String.valueOf(parameterObject);
Long statTime=0L;
if(valueOf.contains("{\"ew\":{")) {
statTime=getTimeByEw(parameterObject);
}else if(valueOf.contains("{\"et\":{")){
statTime=getTimeByEt(parameterObject);
}else {
statTime = parameterObject.getLong("statTime");
}
String formatDate = DateUtils.formatDate(statTime);
String year=formatDate.substring(0, 4);
//表名
return "empss_visual_meter_usage_hour_"+year;
});
//多个entity分表,实现entity中usageDay类分表,
put("usage_day", (metaObject, sql, tableName) -> {
//获取参数
Object originalObject = metaObject.getOriginalObject();
JSONObject originalObjectJSON = JSON.parseObject(JSON.toJSONString(originalObject));
JSONObject boundSql = originalObjectJSON.getJSONObject("boundSql");
JSONObject parameterObject = boundSql.getJSONObject("parameterObject");
String valueOf = String.valueOf(parameterObject);
Long statTime=0L;
if(valueOf.contains("{\"ew\":{")) {
statTime=getTimeByEw(parameterObject);
}else if(valueOf.contains("{\"et\":{")){
statTime=getTimeByEt(parameterObject);
}else {
// save ,update
statTime = parameterObject.getLong("statTime");
}
String formatDate = DateUtils.formatDate(statTime);
String year=formatDate.substring(0, 4);
return "empss_visual_meter_usage_day_"+year;
});
}
/**
* 使用QueryWrapper<T> query 查询时获取stat_time参数
* @param parameterObject
* @return
*/
private Long getTimeByEw(JSONObject parameterObject) {
JSONObject ew=parameterObject.getJSONObject("ew");
String sqlSegment = ew.getString("sqlSegment");
JSONObject paramNameValuePairs=ew.getJSONObject("paramNameValuePairs");
int indexOf = sqlSegment.indexOf("stat_time = #{ew.paramNameValuePairs.");
String substring = sqlSegment.substring(indexOf+37, indexOf+37+9);
Long statTime = paramNameValuePairs.getLong(substring);
return statTime;
}
/**
* 使用saveOrUpdateBatch 批量更新时时获取statTime参数
* @param parameterObject
* @return
*/
private Long getTimeByEt(JSONObject parameterObject) {
JSONObject et=parameterObject.getJSONObject("et");
Long statTime = et.getLong("statTime");
return statTime;
}
});
paginationInterceptor.setSqlParserList(Collections.singletonList(dynamicTableNameParser));
return paginationInterceptor;
}
四、分表时,应该要按某个字段分表,在增删改查时必须要带了了改字段信息,如果要实行更新ID进行修改和查询,可以在保存实现时加上分表字段信息,例如我按statTime(统计时间分表),我在save方法时,在ID前加上统计时间信息
Date statTime = usageHour.getStatTime();
SimpleDateFormat shortDateFormat = new SimpleDateFormat("yyyy");
String format = shortDateFormat.format(statTime);
usageHour.setId(format+UUID.fastUUID().toString());
usageHourService.save(usageHour);
在queryById或增删改时,更加传入的ID获取不同的表。
文章浏览阅读1.1k次。例如100行数据填入word,每页固定展示5行,需要20页_python docx设置每页行数
文章浏览阅读7k次。目录前言OpenEmu简介OpenEmu实际体验最后前言 这次的文章和以往不太一样, 不谈技术, 来谈谈情怀. 记得那是我小学二三年级的时候吧, 我妈给我买了一个Game Boy, 价格记不清了, 反正不贵, 而且是黑白的那种, 应该就是初代Game Boy吧. 然后还配了一张口袋妖怪青的卡. 在那个魔域啊, 传奇啊, 或者什么类似网游盛..._openemu苹果电脑
文章浏览阅读108次。声明:该博文以socket中,关闭输出流为例进行说明。为了方便讲解,我们把DataOutputstream dout = new DataOutputStream(new BufferedOutputStream(mySocket.getOutputStream()));中的dout做为Socket输出流的代言。同样的,din是输入流的代言。可以造成dout被关闭的操作有:1、调用dout.clo..._error:java.net.socketexception: socket output is shutdown
文章浏览阅读4.2k次,点赞2次,收藏8次。SPP模块首要作用是用来解决输入图像尺寸不统一的问题,SPP中不同大小特征的融合,有利于待检测图像中目标大小差异较大的情况,尤其是对于yolov3一般针对的复杂多目标图像。代码实现:_yolo中使用spp的目的是什么
文章浏览阅读1k次。文章目录1.kafka基本原理1.1 消息系统的作用1.2 kafka核心概念1.3 kafka集群架构1.4 kafka高性能高可用原理2.kafka运维实战2.1 kafka生产集群部署方案2.2 kafka常用命2.3 kafka监控-Kafkamanager3.kafka开发实战3.1 kafka生产者3.1.1 生产者发消息原理3.1.2 生产者demo代码3.1.3 生产者核心参数3.2 kafka消费者3.2.1 消费者消费几个重要概念3.2.2 消费者demo代码3.2.3 消费者重要参数_kafka、zookeeper运维
文章浏览阅读432次。1、Yii框架工作流程(MVC文件后缀都是php):models文件夹下建模型,写AR类、对应数据库相关表、定义属性标签、写验证规则、保存表之前调用的方式,用于保存非表单获取的默认数据(如添加数据的时间等,此步如不需要可省略)->controllers文件夹下建控制器、写保存表单的动作->views文件夹下建模板,动态显示视图。2、YII中各种类模型中添加:use yii\ba..._yii后台 记录哪张表哪条数据
文章浏览阅读2.2k次,点赞7次,收藏40次。外观模式实例问题描述结构图编程实现需要交互的类Facade类客户端问题描述某软件公司为新开发的智能手机控制与管理软件提供一键备份功能,通过该功能可以将原本存储在手机中的通讯录、短信、照片、音乐等资料一次性拷贝到移动存储介质中(例如:SD卡)中。在实现过程中需要与多个已有的类进行交互,如通讯录管理类、短信管理类。结构图编程实现需要交互的类public class ContactsManager { private String contacts; public Contacts_某软件公司为新开发的智能手机控制与管理软件提供了一键备份功能,通过该功能可以
文章浏览阅读1k次。本文转自:http://www.99inf.net/SoftwareDev/VC/22322.htmWindows给我们或是说给它自己定义了许多丰富的通用控件,如:Edit、ComboBox 、ListBox……等,这些控件功能丰富,能为我们开发工作带来极大方面,试想:我们单单是自己实现一个EDIT控件是多么的艰难!但是,在实际开发中还是有些情况这些标准控件也无能为力,比如:在我们的应用中要求_vs怎么用mfc画出迷宫
文章浏览阅读6.4k次,点赞5次,收藏42次。【矩阵学习】Jacobian矩阵和Hessian矩阵Jacobian 矩阵Jacobian 行列式功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchar..._海森矩阵判断是否为驻点
文章浏览阅读487次。计算机网络这门课是在大二上的时候是作为主修课,当然上这门课的时候有点划水了。后来接触到校招这方面,下定决心恶补计算机网络这方面的知识,就买了一本《计算机网络:自顶向下的方法》研习。如果不想读谢希仁那版书(毕竟晦涩难懂),又想比较系统的了解计算机网络这方面知识,这本书真的非常推荐。划重点:简单回顾一下HTTP及其报文。1、什么是HTTP协议?HTTP 超文本传输协议 (HTTP-Hypertext transfer protocol),是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用_协议报文和数据报文的区别
文章浏览阅读535次。Flash / Flex Tutorial - How to Create a crossdomain.xml file.This brief tutorial will teach you how to create a crossdomain.xml file so that you can access files and information from outside domains
文章浏览阅读1.3k次。Redis Sentinel 机制与用法(一)概述Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动_sentinel: redis://10.43.19.251:26379 频繁 added down