文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

mybatisplus复合主键CRUD的示例分析

2023-06-29 10:41

关注

这篇文章主要介绍了mybatisplus复合主键CRUD的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

mybatisplus 复合主键CRUD

需求描述

最近接到个挺有意思的需求,做用户观看学习视频时长的一个数据埋点

储存用户观看视频时长、记录的接口的调用肯定会特别频繁,因为每间隔指定时间每个用户都会调用,如果在这个接口里直接操作数据库将会给我们的数据库带来一定的压力,在我的代码中是不允许的,而我是这样完成这个需求的:

首先将用户观看视频的时长、记录存储到阿里云的日志库里,随后以定时器从阿里云的日志库中拉取用户观看视频的数据同步到我们的数据库中。

而就是最后这一步,同步数据到数据库中,这里的数据量肯定是庞大的,所以我做了分表。

但是尽管做了分表数据量也不少,如果通过自增的主键id去编辑数据那么我在更新数据之前都要先从数据库中查询一次,然后在更新

在数据量大的情况下依然会给我们数据库造成不少压力,且这个定时器的执行时长将会拉大,这是我不能接受的

所以直接使用复合主键,以视频id+用户id去批量更新数据,这样就会快很多,然而mybatisplus却仅支持单一主键操作,这就让我刚屡清楚的思路陷入了僵局

不过还是让我找到了支持复合主键的框架

mybatisplus-plus

是不是看起来挺离谱的?啥玩意就plus-plus?别急,让我们来看看代码先
注意mybatisplus与mybatisplus-plus的版本兼容性

首先引入jar包

<dependency>     <groupId>com.github.jeffreyning</groupId>     <artifactId>mybatisplus-plus</artifactId>     <version>1.5.1-RELEASE</version></dependency><dependency>     <groupId>com.baomidou</groupId>     <artifactId>mybatis-plus-boot-starter</artifactId>     <version>3.1.0</version> </dependency> <dependency>     <groupId>com.baomidou</groupId>     <artifactId>mybatis-plus-generator</artifactId>     <version>3.1.0</version> </dependency>

PO对象

package com.youxue.model.lesson;import com.baomidou.mybatisplus.annotation.TableField;import com.baomidou.mybatisplus.annotation.TableName;import com.fasterxml.jackson.databind.annotation.JsonDeserialize;import com.fasterxml.jackson.databind.annotation.JsonSerialize;import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;import com.github.jeffreyning.mybatisplus.anno.MppMultiId;import com.youxue.sharding.annotation.TableIndex;import com.youxue.sharding.annotation.TableIndices;import com.youxue.sharding.model.BaseShardingPo;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;import lombok.EqualsAndHashCode;import lombok.experimental.Accessors;import java.io.Serializable;import java.time.LocalDateTime;@Data@EqualsAndHashCode(callSuper = false)@Accessors(chain = true)@TableName("UserWatchVideoLog")@ApiModel(value="UserWatchVideoLogPo对象", description="用户观看视频时长表")@TableIndices({        @TableIndex(name = "IX_USERID" ,ddl = "CREATE NONCLUSTERED INDEX [IX_USERID] ON UserWatchVideoLog ( [UserId] DESC)" ),        @TableIndex(name = "IX_LESSONITEMID_USERID" ,ddl = "CREATE NONCLUSTERED INDEX [IX_LESSONITEMID_USERID] ON UserWatchVideoLog (LessonItemId ASC,UserId ASC)" )})public class UserWatchVideoLogPo implements Serializable, BaseShardingPo {    @MppMultiId // 复合主键    @TableField("userId")    @ApiModelProperty(value = "用户id")    private Integer userId;    @TableField("lessonItemId")    @ApiModelProperty(value = "子课程id")    private Integer lessonItemId;    @ApiModelProperty(value = "观看时长 单位秒(s)")    @TableField("seconds")    private Integer seconds;    @ApiModelProperty(value = "科目id")    @TableField("subjectId")    private Integer subjectId;    @ApiModelProperty(value = "视频观看时长  单位秒(s)")    @TableField("VideoProgress")    private Integer videoProgress;    @ApiModelProperty(value = "视频来源 默认 0 ")    @TableField("[Resource]")    private Integer resource;    @ApiModelProperty(value = "类型  默认 0 ")    @TableField("[Type]")    private Integer type;    @ApiModelProperty(value = "创建时间")    @TableField("CreateTime")    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")    @JsonDeserialize(using = LocalDateTimeDeserializer.class)    @JsonSerialize(using = LocalDateTimeSerializer.class)    private LocalDateTime createTime;    @ApiModelProperty(value = "修改时间")    @TableField("UpdateTime")    private LocalDateTime updateTime;}

@MppMultiId 注解即声明为复合主键,并以@TableField 主键 声明表字段

Service接口

package com.youxue.service.lesson;import com.github.jeffreyning.mybatisplus.service.IMppService;import com.youxue.model.lesson.UserWatchVideoLogPo;public interface IUserWatchVideoLogService extends IMppService<UserWatchVideoLogPo> {}

Impl类

package com.youxue.service.lesson.impl;import com.github.jeffreyning.mybatisplus.service.MppServiceImpl;import com.youxue.dao.lesson.UserWatchVideoLogMapper;import com.youxue.model.lesson.UserWatchVideoLogPo;import com.youxue.service.lesson.IUserWatchVideoLogService;import org.springframework.stereotype.Service;@Servicepublic class UserWatchVideoLogServiceImpl extends MppServiceImpl<UserWatchVideoLogMapper, UserWatchVideoLogPo> implements IUserWatchVideoLogService {}

Mapper接口

package com.youxue.dao.lesson;import com.github.jeffreyning.mybatisplus.base.MppBaseMapper;import com.youxue.model.lesson.UserWatchVideoLogPo;public interface UserWatchVideoLogMapper extends MppBaseMapper<UserWatchVideoLogPo> {}

service 继承 IMppService ,mapper 继承 MppBaseMapper,impl 继承 MppServiceImpl 实现 service

并在启动类上添加 @EnableMPP 注解

随后直接在测试用例中运行(测试用例中未使用分表):

@Autowiredprivate IUserWatchVideoLogService userWatchVideoLogService;@Testpublic void testUserWatchVideo() {        UserWatchVideoLogPo userWatchVideoLogPo = new UserWatchVideoLogPo()                .setUserId(6202238)                .setLessonItemId(56303)                .setSeconds(8888)                .setResource(11);        boolean create = userWatchVideoLogService.save(userWatchVideoLogPo);        System.out.println(create);        System.out.println("create result :" + create);        System.out.println("================ create end ==================");// 断点01        UserWatchVideoLogPo watchVideoLogPo = userWatchVideoLogService.selectByMultiId(userWatchVideoLogPo);        System.out.println(watchVideoLogPo.toString());        System.out.println("================ retrieve end ==================");        userWatchVideoLogPo.setSeconds(99999);        userWatchVideoLogPo.setResource(22);        // 断点03                boolean upd = userWatchVideoLogService.updateByMultiId(userWatchVideoLogPo);        System.out.println("upd result :" + upd);        System.out.println("================ update end ==================");        // 断点03        boolean remove = userWatchVideoLogService.deleteByMultiId(userWatchVideoLogPo);        System.out.println("remove result :" + remove);        System.out.println("================ remove end ==================");}

我在save 方法后每个方法出都打了断点,下面我们来看看运行结果

mybatisplus复合主键CRUD的示例分析

可以看到,添加方法打印的SQL与mybatisplus并没有什么区别,随后看一下数据库中的数据

mybatisplus复合主键CRUD的示例分析

是正常的,我们来看一下查询操作

mybatisplus复合主键CRUD的示例分析

可以看到,这里的where条件后跟的是两个查询条件,是不是很棒。再看看编辑操作

mybatisplus复合主键CRUD的示例分析

mybatisplus复合主键CRUD的示例分析

可以到编辑操作的SQL也是已两个条件操作的,数据也更新过来了,最后删除操作:

mybatisplus复合主键CRUD的示例分析

至此支持复合组件的CRUD就完成了

而 mybatisplus-plus 作为 mybatisplus 的升级版 新颖的功能肯定不止于此

根据多个字段联合主键增删改查 

原生mybatisplus只支持一个主键,

mpp支持多个字段联合主键(复合主键)增删改查,

mapper需要继承MppBaseMapper
实体类中联合主键的字段需要用@MppMultiId注解修饰
如果需要在service使用多主键相关操作包括saveOrUpdateByMultiId和批量操作

updateBatchByMultiId和saveOrUpdateBatchByMultiId,可以直接继承IMppService接口

优化分页插件实现在不分页时进行排序操作

原生mybatisplus分页与排序是绑定的,mpp优化了分页插件,使用MppPaginationInterceptor插件
在不分页的情况下支持排序操作
page参数size设置为-1可实现不分页取全量数据,同时设置OrderItem可以实现排序

自动填充优化功能 & 自动扫描Entity类构建ResultMap功能

原生mybatisplus只能做%s+1和now两种填充,mybatisplus-plus在插入或更新时对指定字段进行自定义复杂sql填充。
需要在实体类字段上用原生注解@TableField设置fill=FieldFill.INSERT fill=FieldFill.UPDATE或fill=FieldFill.INSERT_UPDATE否则不会触发自定义填充
mybatisplus-plus使用@InsertFill注解触发插入时,执行注解中自定义的sql填充实体类字段
mybatisplus-plus使用@UpdateFill注解触发更新时,执行注解中自定义的sql填充实体类字段
还可以自动填充主键字段,解决原生mybatisplus不支持多个主键的问题
使用ColNameUtil.pn静态方法,获取实体类中读取方法对应的列名称

感谢你能够认真阅读完这篇文章,希望小编分享的“mybatisplus复合主键CRUD的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯