知识点记录(知识点)
前端:
前端运行流程:
index.html -> main.js->App.vue
p17父子组件之间的值传递
-
prop
= 单向数据传递(父传子)。 -
v-model
= 双向绑定(父子同步)。
CORS:跨域请求,8081访问8089
跨域请求是浏览器的一种保护策略,不是浏览器不会出现cors
var let const 区别
router.js实现路由跳转,匹配某个API跳转到某个页面
我的填充屏幕和他写的不一样,后期debug的时候记得考虑进去
JS代码没看懂
绑定变量??:collapse="true"
通过检查页面,看出折叠之后得到页面宽度,调整背景和他相同
标签里面不能写注解
写函数用剪头函数,别用Function,写Function用不了this变量
apifox不是前后端分离,所以可以使用apifox
sessionStorage范围很窄,新开Tab会失效,重新打开也会失效(我刷新没失效)
点击之后,页面部分内容变化,用子路由实现
<router-view/>
渲染路由地址所对应的页面,可以进行嵌套渲染子路由
在elementplus组件的对应API里如果没有找到,就是HTML属性
p50element组件里面的
@prev-click 点击时执行的函数会自动传入当前页,特别神奇,不知道怎么做到
p51<el-table>的插槽
javascript
<el-table :data="tableData">
<el-table-column prop="name" label="姓名" />
<el-table-column prop="age" label="年龄" />
</el-table>
默认情况下在<el-table>中只能写这样的代码,表示tableData(通常是个数组)中的name字段显示在第一列,列名叫做姓名
而加入插槽之后,可以自定义一些内容化,例如常见的两种插槽名:
#default
表示自定义单元格这种的内容
常见用法为
javascript
<el-table :data="tableData">
<el-table-column prop="name" label="姓名" />
<el-table-column label="操作">
<template #default="scope">
<el-button size="small" @click="edit(scope.row)">编辑</el-button>
<el-button size="small" type="danger" @click="remove(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
表示在"操作"列里加入"编辑"和"删除"按钮,点击分别调用edit(scope.row)和remove(scope.row)函数。
其中scope代表你拿到一个scope对象,其中包括:
scope.row当前行对象
scope.colume当前列信息
scope.$index当前行索引
例如举例代码这种情况,只用到了scope中的row属性,即可在获取对象时写为#default="{ row }",表示只获得其中的row,可以更加简洁。
#header
同理,这个用法是在列的名称那里,让他不是单纯的文字,加入一些小图片,按钮之类的。
p50页面跳转
目前一共见到了三种页面跳转
① index="/dashboard/user"
这是 Element Plus 的 <el-menu>
组件里使用的写法。
-
当你给
el-menu-item
设置index="/dashboard/user"
时,它会配合router
属性,自动调用this.$router.push("/dashboard/user")
。 -
相当于 Vue Router 的跳转,只是 Element Plus 封装了一层。
-
适合在菜单导航中用。
② window.location.href = "/dashboard"
这是 浏览器原生跳转:
-
整个页面会 刷新(后端重新加载页面)。
-
相当于直接在地址栏输入
/dashboard
然后回车。 -
不会保留 Vue 的前端状态(例如 Vuex 中的数据会丢失)。
-
优点:简单粗暴,适合需要完全刷新应用的场景。
③ this.$router.push("/dashboard/user/" + id)
这是 Vue Router 提供的 SPA 跳转方式:
-
不会刷新整个页面,只会让 前端路由切换到对应的组件。
-
Vue 应用的数据(Vuex / Pinia 里的 store、全局状态)不会丢失。
-
体验更顺畅,常用在按钮点击、代码逻辑跳转中。
动态路由的路由配置要用:+变量名,例如:'user/:id'
%route和$router
$route:获取当前路由的属性信息
this.$route.path 拿到当前路径
this.$route.params.id 拿到路由地址中的id参数
$router:调用当前路由对象的方法,比如:
this.$router.push("/dashboard/user"); 跳转到指定的路由地址
this.$router.go(-1); 跳转到上一个路由地址
验证规则:
required:可不可以不选
长度:最大最小多少位
正则输入:可以规定什么符号,是否是中文?数字?英文?手机号?身份证号? 之前编译原理好像学过。
提示的消息:
用什么触发
提交新增用户,一个个传很麻烦,老师讲用formData提交。
验证输入框的合法性
在账号密码登录的时候,是先验证,再创建表单,然后再赋值
新建用户的时候是,先创建表单,赋值,然后再验证,验证成功后提交表单
不知道是否严谨
用户加密,他们说前端也需要加密
弹幕:前端用SHA-256加密然后后端二次加密
局部内容块的刷新
弹幕:可以直接调之前的user的查询,直接就解决了
v-if = "一个boolean变量",这个路由内容是否显示
v-show是隐藏,v-if是直接删除
多级页面的数据穿透
可以在父页面写一个
provide(),与data()、mounted()同级,其中提供的函数和数据可以供本页面和子页面使用
子页面使用可以用inject()进行注入(以数组的形式)
这里大家注意一下有个东西是单向数据流动,子组件能用父组件的值但是不能修改,但是可以使用父组件的自己的函数让父组件自己修改父组件的值
所以是子页面调用父页面写的reload()函数,逻辑是先删掉页面,然后再把显示页面,使子页面重新加载
$nextTick()就是你修改了 任何 绑定到元素中的数据, 会等重新渲染完毕后, 自动执行该函数
批量删除,我感觉前端可以先隐藏复选框,点击批量删除的时候再显示,别的操作也用不到复选框
数据权限这块,我觉得直接没权限的连用户详情页都看不到,自己的详情信息去"我的资料里面看"
其实活动预算这里设计成不同的活动预算范围,让用户去选择会比较好
他cost设计成必须是整数或者两位小数,我觉得不如底层存两位小数,输入格式不符合,进行自动补齐
比如说整数自动补全成两位小数,一位小数自动补全成两位小数。
后端:
建项目->看依赖->配文件->写代码
basePackage用.做分割不是/
阿里巴巴Java开发手册
应用分层:
终端显示层,请求处理层(Web),业务逻辑层(Service层),通用处理层(Manager层),数据持久层(DAO层)
领域对象划分:
DO等价于model
Query(controller->service->manager->dao,从上往下传递参数)
VO(等价于result中的R层)
数据传输过程:
Query(controller->service->manager->dao)
controller返回到终端是用R返回
DO/model(dao->manager->service->controller)
resp.data就是后端返回的R对象
ObjectUtils是spring框架的一个对象判断判断空就如果是一个Collection类型是不是空
可以通过反射机制,查看SpringBoot为我们准备了什么东西,例如方法啊,例如线程池是什么实现
@GetMapping表示doGet()方法加上对应的接口,就会转到下面这里来
@RequestParam(value = "current")接收一个名字叫current的参数,required = false表示可以传,也可以不传
用page 分页插件实现分页
p51@PathVariable(value = "id")
把 URL 路径中的参数 绑定到方法的参数上
类反射出来的xml文件,可以自己编写数据集,有时查的数据需要进行连接,会扩大表的内容,导致他有原表没有的元素,此时就需要重新建立一个数据集
Query在传输据的时候,可以用要和tUser之间进行属性复制,复制的要求是,属性名和属性类型必须都相同
新建用户时创建人的id获取不到,用jwt来解析出当前的登录用户的id
弹幕:直接从springsecurity的上下文对象中获取不就行了
他又封装了个BaseQuery确实有点麻烦
弹幕:我直接用Mybatisplus的公共字段注入 填充 很方便
数据库底层是有一个login_act,phone,email的联合索引,所以说这三个不能出现,同时重复
删掉admin,后端抛异常,前端没捕获
t_activity外键约束t_user 方式为RESTRICT(禁止操作)导致无法删除admin
全局异常捕获,捕获异常,进行弹窗说明
复选框的勾选会触发handleSelectionChange函数,把勾选的条目传入这个函数
批量删除:
后端DeleteMapping这可以直接用List<String>接收参数,spring会自动类型转换的
用CacheUtils返回热点数据,在用户点击下拉框时进行访问,先访问Redis,Redis没有查询数据库,并将数据存入Redis,减轻数据库压力
这里缓存查出来是倒叙,想要正序采用rightpushall就行了
因为你后端创建了一个新类,需要重启的,不能直接build
<=在xml中不识别,可以用MyBatis的转义符号
是否可以用between...and...,
有个人问between后字符是否可以为空,或者and后字段是否可以为空
我和DeepSeek/chatGPT的QA环节:
(前面还有,没来得及记)
Q:为什么要在JcLiankeyunServerApplication里面进行@MapperScan(basePackages = "com.github.jaysee66.jc_liankeyun_server.mapper")
A:这是一个非常好的问题,它触及了 Spring Boot 整合 MyBatis 的核心配置之一。简单来说,这个注解的作用是**告诉 Spring 去哪里寻找 MyBatis 的 Mapper 接口,以便将它们注册为 Spring 容器中的 Bean**。
- 核心作用:解决"接口"如何变成"Bean"的问题
MyBatis 的 Mapper 是"接口"(Interface),它不是具体的类,你不能用 `new` 来创建它的实例。但 Spring 管理的是 **"Bean"** (对象实例)。
因此,需要一个机制来**动态创建这些 Mapper 接口的实现类对象**,并将它们放入 Spring 容器中。
@MapperScan 注解就是启用这个机制的"开关"和"导航"。
- 如果没有 `@MapperScan`,会怎样?
你需要在每一个 Mapper 接口上都加上 `@Mapper` 注解,像这样:java
java
@Mapper // 每个接口都要加,很麻烦
public interface UserMapper {
// ...
}
@Mapper // 每个接口都要加,很麻烦
public interface ProductMapper {
// ...
}
```
这样做的"缺点"是:
非常繁琐:每个 Mapper 接口都要手动加注解,容易忘记。
不易维护:如果有很多 Mapper,代码会显得很冗余。
- `@MapperScan` 的优势:批量注册和集中管理
批量处理:`@MapperScan(basePackages = "com.github.jaysee66...mapper")` 的意思是:"Spring,请你去扫描这个包路径下的所有接口,并把它们都当成 MyBatis 的 Mapper,自动为它们创建实现类并注册为 Bean"。
集中配置:只需要在主配置类(通常是 `XxxApplication`)上写一次,整个项目的 Mapper 就都能被自动发现和管理,非常方便和清晰。
这就好比:
不用 `@MapperScan`:你需要把仓库里的每件货物(Mapper 接口)都贴上一个标签(`@Mapper`)。
使用 `@MapperScan`:你只需要在仓库门口贴一张总告示(`@MapperScan`),写明"这个区域(包路径)里的所有东西都是货物",管理员(Spring)就会自动处理它们。
- 为什么偏偏放在 JcLiankeyunServerApplication 里?
因为带有 @SpringBootApplication注解的类,是 Spring Boot 应用的"主入口和核心配置类"。
Spring Boot 会自动扫描**这个类所在的包及其所有子包**。将 `@MapperScan` 放在这里,可以确保扫描配置生效,并且符合 Spring Boot 的"约定大于配置"的原则。
这是一种**最佳实践**,将所有全局配置放在主应用程序类中,一目了然。
总结
在你的 JcLiankeyunServerApplication中添加 @MapperScan是为了:
-
自动化:省去在每个 Mapper 接口上手动添加 `@Mapper` 注解的麻烦。
-
批量化:一次性扫描并注册指定包路径下的所有 Mapper 接口。
-
集中化:将重要的框架配置信息放在应用程序的入口处,便于管理和维护。
所以,这是一个非常标准和必要的配置,几乎在所有 Spring Boot + MyBatis 的项目中都会这样使用。
整个SecurityConfig详细讲讲
待查询的疑问:
有好多东西,光引入了,根本没讲怎么来的,需要探究一下
R,JWTUtils,JSONUtils,RedisService
4.3Nodejs环境变量配置
6.5Vue三部分都是干什么的
6.6CreateApp是干嘛的
6.11Redis的端口和使用
6.13Redis的黑窗口怎么用,MySQL反向工程有什么用?我的MyBatis设置界面和课程的界面不一样
6.xx public Collection<? extends GrantedAuthority> getAuthorities() {是什么函数,GrantedAuthority是什么类型
@JsonIgnore有什么用
SecurityConfig用户不需要配什么意思?
@Bean注解有什么用
SecurityFilterChain是什么东西
p36JWT怎么生成的
p36redisTemplate.opsForValue()是什么东西redisTemplate怎么用
好多p了Security里面的流式编程里面都是什么意思,我不太懂
p44redis序列化
p49想把分页条做的高级一点,先按照老师的写了
p65builder设计模式?
实现AOP?
有人说用MyBatis的动态SQL能解决这个问题
bug合集:
一些在逻辑上相较于源码的更改:
问题:
在UserView界面显示"用户管理''界面,在这个页面中,我可以点击详情按钮,实现查看该用户详情。之前我已经在显示用户管理界面的时候查到了所有信息,但是并没有全部显示,这个课程中老师在跳转到详情页时,重新查了一次数据。
弹幕就爆发了争吵如下:
有一派是:
- 这不是乱搞吗,前面列表已经查询到了全部信息,这里又在查一次,当网络资源不要钱吗?
- 通过组件之间传参就可以把这个id对应的用户全部信息传递到这个组件;结果非要重复查询
- 你可以不按他这样做,自己把用户详情这里做成一个模态框子组件,这样就可以父子组件传值,把用户数据传过来了
另一派是
- 我问你如果你前面查询到了全部信息, 还没到你点详情的时候, 信息变了, 或者登陆失效了咋整 ?
- 出现错读。db变了,你还拿前端的信息展示呢。 就是应该重新查万一有人修改了信息他这再一查就不对了
ChatGPT的回答:
所以,老师那种写法其实是比较规范的做法,特别是 后台管理系统 这类数据可能随时被修改的场景。别人说"浪费资源",更多是站在 理论优化角度,但在实际工程里,这点消耗是完全可以接受的。
我的新奇想法:
我想过用传ID的方式,把整个对象的详细信息封装成JSON,然后透过路由传过去(反正就一个对象)。
chatGPT的看法:
⚠️ 问题在哪
-
URL 长度限制
- 浏览器和服务器对 URL 长度有上限(一般 2k--8k),对象一旦属性多了,可能超长报错。
-
可读性 & 安全性差
- URL 上会直接显示一大串 JSON,既丑又可能泄漏敏感数据(邮箱、手机号等)。
-
数据同步问题
- 如果用户在详情页刷新页面,query 里的 JSON 就没了(除非你强制写死在 URL 上)。
-
不是常规做法
- 大多数项目都是传 id ,详情页再查。前端传对象更多见于 父子组件通信,而不是跨页面。