redis笔记
Redis
1 Redis和mysql客户端和服务端
mysql端口:3306
redis端口:6379
端口号是暴露给外部设备的逻辑端点,告诉外部设备这个端口号对应不同的服务,用于连接服务端通信。
Pid是计算机内部不同进程的唯一标识,用于计算机内部管理区分不同的服务
2 token和cookie的区别
理解二者本质就可以明白了。
- cookie是一种存储机制,存储在客户端表示用户标号,cookie里面可以存储token,数字等其他形式字符。
- token是一个随机字符串,可以存在客户端的cookie里,也可以存在服务端的session或者reids里。
二者本质就不一样,cookie是一种存储机制,token是一个字符串。
3.redis的相关配置
3.1 区分timeout和connect-time的区别
4 redis做缓存和cpu缓存区别?
下面这两个介绍了什么是缓存,redis做缓存和cpu的内部缓存区别?
先说结论:cpu是硬件级缓存,redis是软件级缓存,二者没有直接关联,但是都是通过缓存提升访问速度。
理解这个概念要梳理清楚cpu,内存,硬盘之间的关系,cpu缓存和redis缓存的区别。java客户端由服务器,这个服务器上有cpu;redis服务器上也有宿主机的cpu;但是注意,java客户端和reids服务器都是运行在宿主机上的服务程序,他们访问内存中的数据可以从本地宿主机上读取缓存,但是java客户端通过网络传输读取数据一定是从redis服务器的宿主机的内存中进行读取。
参考两个博主解释:
1.[如何快速了解什么是计算机的缓存 - 知乎](https://zhuanlan.zhihu.com/p/19591511172#:~:text=1、 CPU 缓存:位于 CPU 内部的缓存,分为一级缓存(L1)、二级缓存(L2)和三级缓存(L3)。 这些缓存是最接近 CPU,的,因此访问速度最快。 CPU 缓存的作用是暂时存储 CPU 频繁使用的数据,以避免每次都从主内存中获取数据。 2、 内存缓存:在操作系统层面上,内存也可以作为缓存使用。)
5 reids基本语法及使用
5.1 五种基本数据类型
5.2 字符串常用命令
5.3 哈希结构常用命令
5.4 集合操作命令
5.5 列表操作命令
5.6 redis通用命令
6 redis使用
6.1 redis使用配置
6.2 redis使用场景——缓存
6.3 redis使用场景——限流
(1)自定义限流注解
注解的属性定义规范
注意两个问题:
- 注解的属性定义为什么和抽象方法一样?
- 注解的属性定义怎样定义?
7 redis开发笔记
配合spring_rbac这个项目熟悉。
1.
工具类里面封装的set方法value写成了string,导致我无法存入user类型
// redisUtil.set("userId" + user.getUserId(), "user{" + user + "}");
不用工具类,用原生的opsForValue的set方法可以存储user实体类类型
// redisTemplate.opsForValue().set(user.getUserName(), user);
2.
public List<DictData> selectDictDataByType(String dictType) {
Object dictDataList1 = redisUtil.get(dictType);
//这个地方注意:要用!=null判断,如果redis里面没有这个键会返回null,这时候再用isEmpty()判断是否是空列表就不行了
- mybatis返回list用isEmpty判断是否是空列表,mybatis不会返回空,他会返回空列表。
- redis这里如果键不存在的话,返回的是null,而不是空列表
if (dictDataList1 != null) {
System.out.println("这是redis里面存储的数据" + dictDataList1);
return (List<DictData>) dictDataList1;
} else {
List<DictData> dictDataList2 = dictDataMapper.selectDictDataBytype(dictType);
System.out.println("这是mysql里面存储的数据" + dictDataList2);
redisTemplate.opsForValue().set(dictType, dictDataList2);
return dictDataList2;
}
3.
<insert id="insertDictType" parameterType="DictType">
insert into tb_dict_type(
<if test="dictName != null and dictName != ''">dict_name,</if>
<if test="dictType != null and dictType != ''">dict_type,</if>
<if test="status != null">status,</if>
<if test="remark != null and remark != ''">remark,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
create_time
)values(
<if test="dictName != null and dictName != ''">#{dictName},</if>
<if test="dictType != null and dictType != ''">#{dictType},</if>
<if test="status != null">#{status},</if>
<if test="remark != null and remark != ''">#{remark},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
sysdate()
)
</insert>
sysdate(),返回数据插入的时间,由数据库服务器生成
4.
看哪个完整系统接口的时候,发现他添加数据时候service层校验逻辑写在了controller层,
经过查找发现,传统的项目,service层的业务逻辑包括了从数据库查出来的校验逻辑,而现在的项目,校验方法还是写在
service层,但是校验逻辑写在了controller层也可以,看你自己了。
5.写了这几个接口,我现在总结一下我书写的命名规范:
(1)crud名字命名上(简单crud,不涉及校验逻辑的情况下):
- mapper层方法名用:
- insert
- delete
- update
- select
- service层和controller层方法名:
- add/save
- delete
- update
- select
controller层的请求地址可以省略后缀重点表示crud就可以
(2)如果包含校验逻辑
controller和mapper层方法命名不变
-service层变化
- isAdd (是否添加)
- isUpdate(是否修改)
- delete 删除 这个删除注意:(业务表用update逻辑删除,字典表用delete物理删除)
- select
校验逻辑一般简单开发就两种:
- 用javaweb的传统方法:先执行一个selectByid/selectByCondition,查询数据库里面是否有值,然后再根据返回结果添加
- 用抛出异常,这里分为两种情况:
- 如果你自己不想自定义,也不用返回给前端响应结果,只想在控制台看到异常
IllegalStateException用于抛出查过来的用户为空时候的异常
表示“数据状态不合法”,适合业务逻辑校验(如订单不存在):
java
User user = userDao.findById(userId);
if (user == null) {
throw new IllegalStateException("用户不存在"); // ✅ 标准异常,无需自定义
}
IllegalArgumentException用于想要再service判断请求此参数的时候
当方法参数明显无效或违反基本约定时抛出:
public User getUserById(Long userId) {
if (userId == null || userId <= 0) {
throw new IllegalArgumentException("用户ID必须为正数");
}
- 如果想要自己定义具体的不同类型异常,并响应给前端,用rbac业务里面的异常处理方法
- 注意这里异常处理可以放在controller抛出,或者service抛出,我感觉还是再service
比较符合各类校验。
(3)补一个mybatis查询结果的常见情况
查询方法 返回值(无数据时) 判断方式
- User findById(Long id) null if (user == null)
- List<User> selectList() 空集合 ([]) if (list.isEmpty())
- Map<String, User> selectMap() 空 Map ({}) if (map.isEmpty())
6.
4.24 字典类型表的crud写完了
准备些字典数据表的crud
7.
4.24晚上仔细看了看前后端分离和不分离区别
- 前后端不分离特征:
- 路由控制权再controller层,controller层既要返回或者跳转页面路由还要把数据返回到页面上
- 数据绑定:返回的页面中的数据由后端程序员绑定插入(jsp可能还会混合java代码)。由后端程序员决定插入数据到哪里。
- 页面渲染:页面由服务器渲染完成
总体上:前端就写三大件,然后把三大件给后端。
-后端如果用jsp,后端程序员要把html转为jsp,开发。
-后端如果用thymlef模板,后端程序员不用转为jsp,直接再html里面加属性,绑数据。
注意:这两种都是前后端不分离的情形,数据绑定都是由后端决定的。
-前后端分离特征:
- 路由控制权在前端,前端控制页面路由的跳转,调用后端urlAPI。
- 数据绑定自由,后端只返回数据格式json,前端获取到数据,自行决定如何展示,展示多少。
- 页面渲染,前端页面渲染由浏览器完成。
7.今天写删除和更新字典数据的时候,发现很省力的地方。
- 删除的service层的删除返回类型void,只在controller层返回成功就行。
- 更新的service层更新返回row,只在controller层判断row就行,
原来是在service层判断row,在返回boolean类型,controller在判断boolea,这样只判断一次row更方便。
- 添加和查询该判断还是要判断的,就删除和修改可以省力点。
8.
在 MySQL 数据库中,DATE_FORMAT函数的语法为DATE_FORMAT(date, format),
其中date是要格式化的日期或日期时间表达式,format是指定的格式字符串。
- DATE_FORMAT(NOW(), '%Y-%m-%d')会将当前时间按照年-月-日的格式进行显示,如2025-04-25。
- 注意:%y表示两位,%Y表示四位。
9.
<if test="status != null and status != ''" >status = #{status},</if>
<if test="remark != null and remark != ''">remark = #{remark},</if>
再次巩固这里
- 前端不写任何东西,后端sql里面得到的是''空字符串
- 前端json中删除这个字段,后端sql里没有是null
10.throw new ServiceException(String.format("%1$s已经被分配,无法删除", dictType.getDictName()));
String.fommat()里面%1$s,别忘了s,,String.format("%1$s已经被分配,无法删除", dictType.getDictName()) 这行代码的作用是将 dictType.getDictName() 的值插入到格式字符串中 %1$s 的位置,生成一个新的字符串,
11.截至2025/4/25,字典数据表和字典类型表,基本的缓存已经全部完成和测试完成。
接下来,看那个缓存注解和刷新缓存,重置缓存的方法。
12.截至2025/4/25晚上22.46,缓存系列全部写完测完。
13.明天尽量把限流加进来。4.26,限流成功熟悉并加入
14.补充一下第七点前后端分离的情况
不论是前后端分离还是不分离,前端都是通过浏览器的网络接口向后端发送请求的。
只不过前后端不分离的html代码中的数据是由后端服务器生成的,js什么的都是前端写的,运行在浏览器里面。
- 前后端分离,前端服务器,后端服务器
1.浏览器根据输入的地址向服务器(前端服务器或与前端资源所在位置对应的服务器)发送请求,获取前端的 HTML、CSS、JavaScript 等静态资源。
2.浏览器接收并解析这些资源,构建出页面的初始结构和样式,并执行 JavaScript 代码来初始化页面的交互逻辑等。
3.当用户在页面上进行操作,触发与后端数据交互的请求时,浏览器会根据前端代码中定义的逻辑,向后端服务器发送请求,请求中通常会包含相关的参数和数据。
4.后端服务器接收到请求后,进行相应的处理,如查询数据库、进行业务逻辑计算等,然后将处理结果以 JSON、XML 等格式的数据响应给浏览器。
5.浏览器接收后端返回的数据后,会将数据交给前端的 JavaScript 代码进行处理。前端 JavaScript 代码会根据数据来更新页面的内容、样式或执行其他交互操作,而不是将数据交给前端服务器处理。前端服务器主要负责提供静态资源,在前后端分离架构中,一般不会处理后端返回给浏览器的数据。
6.所以说前端服务器只是存放静态资源用的,处理后端数据还是在浏览器里面根据js代码处理
- 前后端不分离,在浏览器上输入地址,直接访问后端服务器,后端服务器返回生成的页面和数据给浏览器解析。
- 浏览器是一个软件应用程序,负责解析前端代码,前端代码运行的环境。
- 前端是设计页面的,编写三大件代码,设计后由浏览器解析代码并渲染在浏览器显示屏上。
渲染是指将 HTML、CSS 和 JavaScript 代码转换为用户可见的页面的过程
踩坑记录
1.Another Redis-desktop-manager的json格式是严格的json格式,数值后面不能有L后缀,否则无法变成json格式,这里注意一下。但是redis-desktop-manager这个散打选手居然可以解析,虽然他太破烂,机制不够严谨。
这个Another Redis-desktop-manager是真好用,界面无敌,优雅极了。
作者:yzh先生
博客:https://www.cnblogs.com/ZiJun
本文版权归作者和博客园共有,转载请在文章中注明原文链接:https://www.cnblogs.com/ZiJun/p/18852475 ,愿尊重劳动成果,谢谢!
若有关于博客内容的各种问题,欢迎在评论区讨论或发消息,让我们一起进步!