一篇文章快速掌握redis、mp、es、rocketmq使用
仿b站前后端分离微服务项目,
实现了以下功能:
视频的上传、查看与上传时获取封面
视频的点赞、评论、可同时新增和删除多个收藏记录的收藏、多功能的弹幕
用户的个人信息查看编辑、用户之间的关注
用户的个人主页权限修改、查看、由个人主页权限动态决定的用户个人主页内容的获取
手机号、邮箱、图形验证码的多种方式登录
支持临时会话的服务器为代理的一对一实时私聊
基于讯飞星火的文生文、文生图、(全网首发)智能PPT
关注up动态视频、评论、点赞、私聊消息的生成与推送
基于es实现的视频和用户的聚合搜索、推荐视频
网关的路由和统一鉴权与授权
基于双token的七天内无感刷新token
防csrf、xss、抓包、恶意上传脚本攻击
统一处理异常和泛型封装响应体、自定义修改响应序列化值
简易的仿redis缓存读取与数据过期剔除实现
xxl-job+ redis+ rocketmq+ es+ 布隆过滤器的自定义es与mysql数据同步
slueth+zipkin的多服务间请求链路追踪
集中多服务日志到一个文件目录下与按需添加特定内容入日志
多服务的详细接口文档
项目地址LABiliBili,github地址GitHub - aigcbilibili/aigcbilibili: 仿bilibili前后端实现,演示地址https://labilibili.com/video/演示.mp4,如果大家觉得有帮助的话可以去github点个小星星♪(・ω・)ノ
下面是项目中redis、mybatis-plus、es、rocketmq的使用
(由于使用父子模块写法,所以子模块引入依赖的版本都在父pom.xml文件中查看,下方不再给出版本号)
redis的使用
准备工作
引入SpringBoot集成后的依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
配置连接地址
spring: redis: host:localhost:84 # password: 默认为空
在容器中注册bean
@Configuration public class RedisConfig { private final RedisConnectionFactory redisConnectionFactory; public RedisConfig(RedisConnectionFactory redisConnectionFactory) { this.redisConnectionFactory = redisConnectionFactory; } @Bean public <T> RedisTemplate<String, T> objectRedisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, T> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new GenericFastJsonRedisSerializer()); return redisTemplate; } @Bean public RedisMessageListenerContainer redisMessageListenerContainer() { RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer(); redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory); return redisMessageListenerContainer; } @Bean public RedisTemplate<String, byte[]> bytesRedisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, byte[]> template = new RedisTemplate<>(); template.setKeySerializer(RedisSerializer.string()); template.setValueSerializer(RedisSerializer.byteArray()); template.setHashKeySerializer(RedisSerializer.string()); template.setHashValueSerializer(RedisSerializer.byteArray()); template.setConnectionFactory(redisConnectionFactory); return template; } @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, String> template = new RedisTemplate<>(); template.setKeySerializer(RedisSerializer.string()); template.setValueSerializer(RedisSerializer.string()); template.setHashKeySerializer(RedisSerializer.string()); template.setHashValueSerializer(RedisSerializer.string()); template.setConnectionFactory(redisConnectionFactory); return template; } }
若要在项目代码基础上做修改需注意在项目代码中用的@Resource注解,而该注解默认是byName,这里的Name指的是配置类中标注了@Bean注解的方法的名字,如使用redis时键值类型都为String类型时则注入redisTemplate,分别为String和object类型时则使用objectRedisTemplate,否则项目运行不会报错但实际调用方法时会报与预期类型不匹配。
使用redis
引入依赖、编写配置文件、编写配置类后就可以在业务层注入需要的某个redisTemplate的Bean来使用了,spring-boot-starter-data-redis针对redis数据结构封装了两层,调用两层后才能针对redis中某种数据结构进行增删改查操作,以最常见的键值数据结构为例
redisTemplate.opsForValue().set(Object key,Object value); 存入一对键值对,默认永不超时 redisTemplate.opsForValue().set(Object key,Object value,long timeout,TimeUnit timeUnit); 存入一对键值对,在以传入的时间单位为单位的前提下过了timeout时间后过期 redisTemplate.opsForValue().get(Object key); 根据键名获取键值对的值
走到这一步已经可以自如使用redis了,而redis的存取方法有相当多的重载版本,可以根据需求去使用
mybatis-plus的自动填充值处理器、条件mapper的使用
引入依赖
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> </dependency>
按特定注解编写实体类
@Data @Accessors(chain = true) @TableName("chat_notice") public class Chat { @TableField("sender_id") private Integer senderId; @TableField("content") private String content; @TableField("receiver_id") private Integer receiverId; @TableField(value = "create_time",fill = FieldFill.INSERT) private LocalDateTime createTime; @TableId(type = IdType.AUTO) private Integer id; @TableField(value = "status",fill = FieldFill.INSERT) private Integer status; }
其中@TableField是一般字段,负责将数据库表的列名与Java对象属性名映射到一起,@TableId是id字段,不同type值决定了id增长策略,默认雪花算法,当前代码是设定为自增主键。@TableName标识该实体类对应数据库中的表。
自动填充值处理器的使用
package ljl.bilibili.handler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.time.LocalDateTime; import java.util.Date; import java.util.UUID; /** *自动填充处理器 */ @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("cover", "https://labilibili.com/user-cover/default.png", metaObject); this.setFieldValByName("nickname", "新用户"+ UUID.randomUUID().toString().substring(0,10), metaObject); this.setFieldValByName("createTime", LocalDateTime.now(), metaObject); this.setFieldValByName("danmakuCount", 0, metaObject); this.setFieldValByName("playCo unt",0, metaObject); this.setFieldValByName("likeCount",0, metaObject); this.setFieldValByName("collectCount",0, metaObject); this.setFieldValByName("commentCount",0, metaObject); this.setFieldValByName("status",0,metaObject); this.setFieldValByName("collectGroup",0,metaObject); this.setFieldValByName("remotelyLike",0,metaObject); this.setFieldValByName("fansList",0,metaObject); this.setFieldValByName("idolList",0,metaObject); } @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject); } }
编写一个实现了MetaObjectHandler接口的处理器类并使用@Component注解注册到容器中,实现insertFill和updateFill实现新增和修改时自动修改值
@TableField(value = "create_time",fill = FieldFill.INSERT) private LocalDateTime createTime; this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
在需要自动更新的实体属性的@TableField注解中标注fill的类型,然后在实现的方法中将该属性字段名、自动赋予的值填进去,最后一个参数固定为传递进实现方法的参数metaObject。这里需注意自动赋予的值的类型必须和该实体属性的类型一致。
固定格式的mapper
@Mapper public interface CommentNoticeMapper extends BaseMapper<CommentNotice> { }
继承BaseMapper并将泛型的值限定为该Mapper对应操作的实体类的类名,在该Mapper类上标记@Mapper注解即可在业务层引入该Mapper后使用
增删改查操作的使用
前提都是在业务代码中引入了该Mapper
@Resource CommentNoticeMapper commentNoticeMapper;
查询
创建一个查询需要用到的封装查询条件wrapper LambdaQueryWrapper<CommentNotice> wrapper=new LambdaQueryWrapper<>(); 等价于where 列值(↑commentNotice实体对应的属性)=1 wrapper.eq(CommentNotice::getSta
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
该专栏存放前后端分离仿b站微服务项目相关教程与简历话术