update doc

This commit is contained in:
Shuaishuai Dai 2022-10-21 17:02:22 +08:00
parent 4531b35003
commit 9679fa76ea
27 changed files with 521 additions and 16 deletions

File diff suppressed because one or more lines are too long

Binary file not shown.

After

(image error) Size: 189 KiB

Binary file not shown.

After

(image error) Size: 170 KiB

Binary file not shown.

After

(image error) Size: 140 KiB

Binary file not shown.

After

(image error) Size: 210 KiB

Binary file not shown.

After

(image error) Size: 87 KiB

Binary file not shown.

After

(image error) Size: 164 KiB

Binary file not shown.

After

(image error) Size: 130 KiB

Binary file not shown.

After

(image error) Size: 213 KiB

Binary file not shown.

After

(image error) Size: 108 KiB

Binary file not shown.

After

(image error) Size: 186 KiB

Binary file not shown.

After

(image error) Size: 164 KiB

View File

@ -0,0 +1,72 @@
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [www.php.cn](https://www.php.cn/java/guide/478876.html)
> idea 快捷键有Ctrl+F、Ctrl+R、Ctrl+Z、Ctrl+Y、Ctrl+X、Ctrl+C、Ctrl+D、Alt+`、Alt+Q、Alt+F1、Alt+F2、Alt+F3、Alt+F7、Shift+F1、Shift+F2 等。
> idea 快捷键有Ctrl+F、Ctrl+R、Ctrl+Z、Ctrl+Y、Ctrl+X、Ctrl+C、Ctrl+D、Alt+`、Alt+Q、Alt+F1、Alt+F2、Alt+F3、Alt+F7、Shift+F1、Shift+F2 等。
本教程操作环境windows7 系统、IntelliJ IDEA2018.3 版、Dell G3 电脑。
## 常用
| 快捷键 | 介绍 |
| --------------------- | ------------------------------------------------------- |
| main/psvm | 快速生成main |
| sout | 快速生成System.out.print |
| Alt+Insert | 生成代码(如get,set方法,构造函数等) 或者右键Generate |
| Alt+鼠标左键 | 整列编辑 |
| Ctrl+Alt+V | 补齐返回类型及变量 |
| Ctrl+Alt+T | 快捷代码块 try catch 等 |
| Ctrl+Alt+O | 优化导入的类和包 |
| Ctrl+D | 复制当前行到下一行 |
| Ctrl+Y | 删除一行 |
| Alt + Shift +上下箭头 | 上下移动当前行 |
| Ctrl+F/R | 查找/替换 |
| CTRL+ALT+L | 格式化代码 |
| CTRL+ALT+I | 自动缩进 |
| Ctrl + W | 快速选中 |
| Alt + 上下方向键 | 方法快速跳转 |
| Ctrl + Alt + Enter | 在当前行之前插入一行 |
| Shift + Enter | 在当前行之后插入一行 |
| CTRL + / | 注释 [CTRL + SHIFT + / 取消注释CTRL + SHIFT + \] |
## Ctrl
<table><thead><tr><th>快捷键</th><th>介绍</th></tr></thead><tbody><tr><td>Ctrl + F</td><td>在当前文件进行文本查找 <code>(必备)</code></td></tr><tr><td>Ctrl + R</td><td>在当前文件进行文本替换 <code>(必备)</code></td></tr><tr><td>Ctrl + Z</td><td>撤销 <code>(必备)</code></td></tr><tr><td>Ctrl + Y</td><td>删除光标所在行 或 删除选中的行 <code>(必备)</code></td></tr><tr><td>Ctrl + X</td><td>剪切光标所在行 或 剪切选择内容</td></tr><tr><td>Ctrl + C</td><td>复制光标所在行 或 复制选择内容</td></tr><tr><td>Ctrl + D</td><td>复制光标所在行 或 复制选择内容,并把复制内容插入光标位置下面 <code>(必备)</code></td></tr><tr><td>Ctrl + W</td><td>递进式选择代码块。可选中光标所在的单词或段落,连续按会在原有选中的基础上再扩展选中范围 <code>(必备)</code></td></tr><tr><td>Ctrl + E</td><td>显示最近打开的文件记录列表</td></tr><tr><td>Ctrl + N</td><td>根据输入的 <strong>类名</strong> 查找类文件</td></tr><tr><td>Ctrl + G</td><td>在当前文件跳转到指定行处</td></tr><tr><td>Ctrl + J</td><td>插入自定义动态代码模板</td></tr><tr><td>Ctrl + P</td><td>方法参数提示显示</td></tr><tr><td>Ctrl + Q</td><td>光标所在的变量 / 类名 / 方法名等上面(也可以在提示补充的时候按),显示文档内容</td></tr><tr><td>Ctrl + U</td><td>前往当前光标所在的方法的父类的方法 / 接口定义</td></tr><tr><td>Ctrl + B</td><td>进入光标所在的方法 / 变量的接口或是定义出,等效于 <code>Ctrl + 左键单击</code></td></tr><tr><td>Ctrl + K</td><td>版本控制提交项目,需要此项目有加入到版本控制才可用</td></tr><tr><td>Ctrl + T</td><td>版本控制更新项目,需要此项目有加入到版本控制才可用</td></tr><tr><td>Ctrl + H</td><td>显示当前类的层次结构</td></tr><tr><td>Ctrl + O</td><td>选择可重写的方法</td></tr><tr><td>Ctrl + I</td><td>选择可继承的方法</td></tr><tr><td>Ctrl + +</td><td>展开代码</td></tr><tr><td>Ctrl + -</td><td>折叠代码</td></tr><tr><td>Ctrl + /</td><td>注释光标所在行代码,会根据当前不同文件类型使用不同的注释符号 <code>(必备)</code></td></tr><tr><td>Ctrl + [</td><td>移动光标到当前所在代码的花括号开始位置</td></tr><tr><td>Ctrl + ]</td><td>移动光标到当前所在代码的花括号结束位置</td></tr><tr><td>Ctrl + F1</td><td>在光标所在的错误代码出显示错误信息</td></tr><tr><td>Ctrl + F3</td><td>调转到所选中的词的下一个引用位置</td></tr><tr><td>Ctrl + F4</td><td>关闭当前编辑文件</td></tr><tr><td>Ctrl + F8</td><td>在 Debug 模式下,设置光标当前行为断点,如果当前已经是断点则去掉断点</td></tr><tr><td>Ctrl + F9</td><td>执行 Make Project 操作</td></tr><tr><td>Ctrl + F11</td><td>选中文件 / 文件夹,使用助记符设定 / 取消书签</td></tr><tr><td>Ctrl + F12</td><td>弹出当前文件结构层,可以在弹出的层上直接输入,进行筛选</td></tr><tr><td>Ctrl + Tab</td><td>编辑窗口切换,如果在切换的过程又加按上 delete则是关闭对应选中的窗口</td></tr><tr><td>Ctrl + Enter</td><td>智能分隔行</td></tr><tr><td>Ctrl + End</td><td>跳到文件尾</td></tr><tr><td>Ctrl + Home</td><td>跳到文件头</td></tr><tr><td>Ctrl + Space</td><td>基础代码补全,默认在 Windows 系统上被输入法占用,需要进行修改,建议修改为 <code>Ctrl + 逗号</code> <code>(必备)</code></td></tr><tr><td>Ctrl + Delete</td><td>删除光标后面的单词或是中文句</td></tr><tr><td>Ctrl + BackSpace</td><td>删除光标前面的单词或是中文句</td></tr><tr><td>Ctrl + 1,2,3...9</td><td>定位到对应数值的书签位置</td></tr><tr><td>Ctrl + 左键单击</td><td>在打开的文件标题上,弹出该文件路径</td></tr><tr><td>Ctrl + 光标定位</td><td>按 Ctrl 不要松开,会显示光标所在的类信息摘要</td></tr><tr><td>Ctrl + 左方向键</td><td>光标跳转到当前单词 / 中文句的左侧开头位置</td></tr><tr><td>Ctrl + 右方向键</td><td>光标跳转到当前单词 / 中文句的右侧开头位置</td></tr><tr><td>Ctrl + 前方向键</td><td>等效于鼠标滚轮向前效果</td></tr><tr><td>Ctrl + 后方向键</td><td>等效于鼠标滚轮向后效果</td></tr></tbody></table>
Alt
---
<table><thead><tr><th>快捷键</th><th>介绍</th></tr></thead><tbody><tr><td>Alt + `</td><td>显示版本控制常用操作菜单弹出层</td></tr><tr><td>Alt + Q</td><td>弹出一个提示,显示当前类的声明 / 上下文信息</td></tr><tr><td>Alt + F1</td><td>显示当前文件选择目标弹出层,弹出层中有很多目标可以进行选择</td></tr><tr><td>Alt + F2</td><td>对于前面页面,显示各类浏览器打开目标选择弹出层</td></tr><tr><td>Alt + F3</td><td>选中文本,逐个往下查找相同文本,并高亮显示</td></tr><tr><td>Alt + F7</td><td>查找光标所在的方法 / 变量 / 类被调用的地方</td></tr><tr><td>Alt + F8</td><td>在 Debug 的状态下,选中对象,弹出可输入计算表达式调试框,查看该输入内容的调试结果</td></tr><tr><td>Alt + Home</td><td>定位 / 显示到当前文件的 <code>Navigation Bar</code></td></tr><tr><td>Alt + Enter</td><td>IntelliJ IDEA 根据光标所在问题,提供快速修复选择,光标放在的位置不同提示的结果也不同 <code>(必备)</code></td></tr><tr><td>Alt + Insert</td><td>代码自动生成,如生成对象的 set / get 方法构造函数toString() 等</td></tr><tr><td>Alt + 左方向键</td><td>按左方向切换当前已打开的文件视图</td></tr><tr><td>Alt + 右方向键</td><td>按右方向切换当前已打开的文件视图</td></tr><tr><td>Alt + 前方向键</td><td>当前光标跳转到当前文件的前一个方法名位置</td></tr><tr><td>Alt + 后方向键</td><td>当前光标跳转到当前文件的后一个方法名位置</td></tr><tr><td>Alt + 1,2,3...9</td><td>显示对应数值的选项卡,其中 1 是 Project 用得最多</td></tr></tbody></table>
Shift
-----
<table><thead><tr><th>快捷键</th><th>介绍</th></tr></thead><tbody><tr><td>Shift + F1</td><td>如果有外部文档可以连接外部文档</td></tr><tr><td>Shift + F2</td><td>跳转到上一个高亮错误 或 警告位置</td></tr><tr><td>Shift + F3</td><td>在查找模式下,查找匹配上一个</td></tr><tr><td>Shift + F4</td><td>对当前打开的文件,使用新 Windows 窗口打开,旧窗口保留</td></tr><tr><td>Shift + F6</td><td>对文件 / 文件夹 重命名</td></tr><tr><td>Shift + F7</td><td>在 Debug 模式下,智能步入。断点所在行上有多个方法调用,会弹出进入哪个方法</td></tr><tr><td>Shift + F8</td><td>在 Debug 模式下,跳出,表现出来的效果跟 <code>F9</code> 一样</td></tr><tr><td>Shift + F9</td><td>等效于点击工具栏的 <code>Debug</code> 按钮</td></tr><tr><td>Shift + F10</td><td>等效于点击工具栏的 <code>Run</code> 按钮</td></tr><tr><td>Shift + F11</td><td>弹出书签显示层</td></tr><tr><td>Shift + Tab</td><td>取消缩进</td></tr><tr><td>Shift + ESC</td><td>隐藏当前 或 最后一个激活的工具窗口</td></tr><tr><td>Shift + End</td><td>选中光标到当前行尾位置</td></tr><tr><td>Shift + Home</td><td>选中光标到当前行头位置</td></tr><tr><td>Shift + Enter</td><td>开始新一行。光标所在行下空出一行,光标定位到新行位置</td></tr><tr><td>Shift + 左键单击</td><td>在打开的文件名上按此快捷键,可以关闭当前打开文件</td></tr><tr><td>Shift + 滚轮前后滚动</td><td>当前文件的横向滚动轴滚动</td></tr></tbody></table>
Ctrl + Alt
----------
<table><thead><tr><th>快捷键</th><th>介绍</th></tr></thead><tbody><tr><td>Ctrl + Alt + L</td><td>格式化代码,可以对当前文件和整个包目录使用 <code>(必备)</code></td></tr><tr><td>Ctrl + Alt + O</td><td>优化导入的类,可以对当前文件和整个包目录使用 <code>(必备)</code></td></tr><tr><td>Ctrl + Alt + I</td><td>光标所在行 或 选中部分进行自动代码缩进,有点类似格式化</td></tr><tr><td>Ctrl + Alt + T</td><td>对选中的代码弹出环绕选项弹出层</td></tr><tr><td>Ctrl + Alt + J</td><td>弹出模板选择窗口,讲选定的代码加入动态模板中</td></tr><tr><td>Ctrl + Alt + H</td><td>调用层次</td></tr><tr><td>Ctrl + Alt + B</td><td>在某个调用的方法名上使用会跳到具体的实现处,可以跳过接口</td></tr><tr><td>Ctrl + Alt + V</td><td>快速引进变量</td></tr><tr><td>Ctrl + Alt + Y</td><td>同步、刷新</td></tr><tr><td>Ctrl + Alt + S</td><td>打开 IntelliJ IDEA 系统设置</td></tr><tr><td>Ctrl + Alt + F7</td><td>显示使用的地方。寻找被该类或是变量被调用的地方,用弹出框的方式找出来</td></tr><tr><td>Ctrl + Alt + F11</td><td>切换全屏模式</td></tr><tr><td>Ctrl + Alt + Enter</td><td>光标所在行上空出一行,光标定位到新行</td></tr><tr><td>Ctrl + Alt + Home</td><td>弹出跟当前文件有关联的文件弹出层</td></tr><tr><td>Ctrl + Alt + Space</td><td>类名自动完成</td></tr><tr><td>Ctrl + Alt + 左方向键</td><td>退回到上一个操作的地方 <code>(必备)<strong>(注意与其他软件快捷键冲突)</strong></code></td></tr><tr><td>Ctrl + Alt + 右方向键</td><td>前进到上一个操作的地方 <code>(必备)<strong>(注意与其他软件快捷键冲突)</strong></code></td></tr><tr><td>Ctrl + Alt + 前方向键</td><td>在查找模式下,跳到上个查找的文件</td></tr><tr><td>Ctrl + Alt + 后方向键</td><td>在查找模式下,跳到下个查找的文件</td></tr></tbody></table>
Ctrl + Shift
------------
<table><thead><tr><th>快捷键</th><th>介绍</th></tr></thead><tbody><tr><td>Ctrl + Shift + F</td><td>根据输入内容查找整个项目 或 指定目录内文件 <code>(必备)</code></td></tr><tr><td>Ctrl + Shift + R</td><td>根据输入内容替换对应内容,范围为整个项目 或 指定目录内文件 <code>(必备)</code></td></tr><tr><td>Ctrl + Shift + J</td><td>自动将下一行合并到当前行末尾 <code>(必备)</code></td></tr><tr><td>Ctrl + Shift + Z</td><td>取消撤销 <code>(必备)</code></td></tr><tr><td>Ctrl + Shift + W</td><td>递进式取消选择代码块。可选中光标所在的单词或段落,连续按会在原有选中的基础上再扩展取消选中范围 <code>(必备)</code></td></tr><tr><td>Ctrl + Shift + N</td><td>通过文件名定位 / 打开文件 / 目录,打开目录需要在输入的内容后面多加一个正斜杠 <code>(必备)</code></td></tr><tr><td>Ctrl + Shift + U</td><td>对选中的代码进行大 / 小写轮流转换 <code>(必备)</code></td></tr><tr><td>Ctrl + Shift + T</td><td>对当前类生成单元测试类,如果已经存在的单元测试类则可以进行选择</td></tr><tr><td>Ctrl + Shift + C</td><td>复制当前文件磁盘路径到剪贴板</td></tr><tr><td>Ctrl + Shift + V</td><td>弹出缓存的最近拷贝的内容管理器弹出层</td></tr><tr><td>Ctrl + Shift + E</td><td>显示最近修改的文件列表的弹出层</td></tr><tr><td>Ctrl + Shift + H</td><td>显示方法层次结构</td></tr><tr><td>Ctrl + Shift + B</td><td>跳转到类型声明处</td></tr><tr><td>Ctrl + Shift + I</td><td>快速查看光标所在的方法 或 类的定义</td></tr><tr><td>Ctrl + Shift + A</td><td>查找动作 / 设置</td></tr><tr><td>Ctrl + Shift + /</td><td>代码块注释 <code>(必备)</code></td></tr><tr><td>Ctrl + Shift + [</td><td>选中从光标所在位置到它的顶部中括号位置</td></tr><tr><td>Ctrl + Shift + ]</td><td>选中从光标所在位置到它的底部中括号位置</td></tr><tr><td>Ctrl + Shift + +</td><td>展开所有代码</td></tr><tr><td>Ctrl + Shift + -</td><td>折叠所有代码</td></tr><tr><td>Ctrl + Shift + F7</td><td>高亮显示所有该选中文本,按 Esc 高亮消失</td></tr><tr><td>Ctrl + Shift + F8</td><td>在 Debug 模式下,指定断点进入条件</td></tr><tr><td>Ctrl + Shift + F9</td><td>编译选中的文件 / 包 / Module</td></tr><tr><td>Ctrl + Shift + F12</td><td>编辑器最大化</td></tr><tr><td>Ctrl + Shift + Space</td><td>智能代码提示</td></tr><tr><td>Ctrl + Shift + Enter</td><td>自动结束代码,行末自动添加分号 <code>(必备)</code></td></tr><tr><td>Ctrl + Shift + Backspace</td><td>退回到上次修改的地方</td></tr><tr><td>Ctrl + Shift + 1,2,3...9</td><td>快速添加指定数值的书签</td></tr><tr><td>Ctrl + Shift + 左方向键</td><td>在代码文件上,光标跳转到当前单词 / 中文句的左侧开头位置,同时选中该单词 / 中文句</td></tr><tr><td>Ctrl + Shift + 右方向键</td><td>在代码文件上,光标跳转到当前单词 / 中文句的右侧开头位置,同时选中该单词 / 中文句</td></tr><tr><td>Ctrl + Shift + 左方向键</td><td>在光标焦点是在工具选项卡上,缩小选项卡区域</td></tr><tr><td>Ctrl + Shift + 右方向键</td><td>在光标焦点是在工具选项卡上,扩大选项卡区域</td></tr><tr><td>Ctrl + Shift + 前方向键</td><td>光标放在方法名上,将方法移动到上一个方法前面,调整方法排序</td></tr><tr><td>Ctrl + Shift + 后方向键</td><td>光标放在方法名上,将方法移动到下一个方法前面,调整方法排序</td></tr></tbody></table>
Alt + Shift
-----------
<table><thead><tr><th>快捷键</th><th>介绍</th></tr></thead><tbody><tr><td>Alt + Shift + N</td><td>选择 / 添加 task</td></tr><tr><td>Alt + Shift + F</td><td>显示添加到收藏夹弹出层</td></tr><tr><td>Alt + Shift + C</td><td>查看最近操作项目的变化情况列表</td></tr><tr><td>Alt + Shift + F</td><td>添加到收藏夹</td></tr><tr><td>Alt + Shift + I</td><td>查看项目当前文件</td></tr><tr><td>Alt + Shift + F7</td><td>在 Debug 模式下,下一步,进入当前方法体内,如果方法体还有方法,则会进入该内嵌的方法中,依此循环进入</td></tr><tr><td>Alt + Shift + F9</td><td>弹出 <code>Debug</code> 的可选择菜单</td></tr><tr><td>Alt + Shift + F10</td><td>弹出 <code>Run</code> 的可选择菜单</td></tr><tr><td>Alt + Shift + 左键双击</td><td>选择被双击的单词 / 中文句,按住不放,可以同时选择其他单词 / 中文句</td></tr><tr><td>Alt + Shift + 前方向键</td><td>移动光标所在行向上移动</td></tr><tr><td>Alt + Shift + 后方向键</td><td>移动光标所在行向下移动</td></tr></tbody></table>
Ctrl + Shift + Alt
------------------
<table><thead><tr><th>快捷键</th><th>介绍</th></tr></thead><tbody><tr><td>Ctrl + Shift + Alt + V</td><td>无格式黏贴</td></tr><tr><td>Ctrl + Shift + Alt + N</td><td>前往指定的变量 / 方法</td></tr><tr><td>Ctrl + Shift + Alt + S</td><td>打开当前项目设置</td></tr><tr><td>Ctrl + Shift + Alt + C</td><td>复制参考信息</td></tr></tbody></table>
其他
--
<table><thead><tr><th>快捷键</th><th>介绍</th></tr></thead><tbody><tr><td>F2</td><td>跳转到下一个高亮错误 或 警告位置 <code>(必备)</code></td></tr><tr><td>F3</td><td>在查找模式下,定位到下一个匹配处</td></tr><tr><td>F4</td><td>编辑源</td></tr><tr><td>F7</td><td>在 Debug 模式下,进入下一步,如果当前行断点是一个方法,则进入当前方法体内,如果该方法体还有方法,则不会进入该内嵌的方法中</td></tr><tr><td>F8</td><td>在 Debug 模式下,进入下一步,如果当前行断点是一个方法,则不进入当前方法体内</td></tr><tr><td>F9</td><td>在 Debug 模式下,恢复程序运行,但是如果该断点下面代码还有断点则停在下一个断点上</td></tr><tr><td>F11</td><td>添加书签</td></tr><tr><td>F12</td><td>回到前一个工具窗口</td></tr><tr><td>Tab</td><td>缩进</td></tr><tr><td>ESC</td><td>从工具窗口进入代码文件窗口</td></tr><tr><td>连按两次 Shift</td><td>弹出 <code>Search Everywhere</code> 弹出层</td></tr></tbody></table>

View File

@ -0,0 +1,48 @@
## 使用RestTemplate优雅的发送Get请求
在我们的项目中,如果借助 [RestTemplate](https://so.csdn.net/so/search?q=RestTemplate&spm=1001.2101.3001.7020) 发送带参数的 Get 请求,我们可以通过拼接字符串的方式将 url 拼接出来,比如下面这种方式:
```java
String url = "http://127.0.0.1:8080/rest/get? + id;
ResponseEntity<RestVO> forEntity = restTemplate.getForEntity(url, RestVO.class);
```
然而这种方式不太优雅,我们还可以通过以下几种方式发送 Get 请求
#### 方式 1使用占位符
```java
String url = "http://127.0.0.1:8080/rest/path/{name}/{id}";
Map<String, Object> params = new HashMap<>();
params.put("name", "这是name");
params.put("id", 1L);
ResponseEntity<RestVO> forEntity = restTemplate.getForEntity(url, RestVO.class, params);
```
Map 的 key 要和 `url `中的占位符一致
#### 方式 2使用 LinkedMultiValueMap 和 UriComponentsBuilder
```java
String url = "http://127.0.0.1:8080/rest/get";
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("name", "这是name");
params.add("id", "1");
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
URI uri = builder.queryParams(params).build().encode().toUri();
ResponseEntity<RestVO> forEntity = restTemplate.getForEntity(uri, RestVO.class);
return forEntity.getBody();
```
方式 2 看起来是最优雅的,将参数的设置和 `url `分离。
#### Map 转 MultiValueMap
```java
Map<String,String> params = new HashMap<>();
MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>(
params.entrySet().stream().collect(
Collectors.toMap(Map.Entry::getKey, e -> Collections.singletonList(e.getValue()))));
```

View File

@ -0,0 +1,99 @@
## Mybatis-Plus
### LambdaUpdateWapper 配合泛型使用报错com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: can not find lambda cache for this property [xxx] of entity [com.xxx.si.fss.ssf.ass.entity.xxx]
```java
public interface CloseV1Service<T extends CloseStatefulEntity> {
BaseMapper<T> getBaseMapper();
default void action(CloseOperateVO operateVO){
if (NullUtils.isEmpty(operateVO.getId())){
throw new MyException(RestResponse.MSG.PARAM_VALUE_ERROR).setMsg("未发现指定操作对象id");
}
T closeEntity = getBaseMapper().selectById(operateVO.getId());
if (closeEntity==null){
throw new MyException(RestResponse.MSG.NO_DATA_EXISTS);
}
closeEntity.closeable(operateVO.getCloseAction());
LambdaUpdateWrapper<T> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper
.eq(T::getId,operateVO.getId()) //此处抛出异常
.set(T::getCloseStatus, operateVO.getCloseAction().getStepState());
getBaseMapper().update(null,lambdaUpdateWrapper);
}
}
```
#### 原因LambdaUpdateWrapper没有指定实体类类型
#### 解决方法为LambdaUpdateWrapper对象指定实体类类型
```java
@Validated
public interface CloseV1Service<T extends CloseStatefulEntity> {
Class<T> getTClass();
BaseMapper<T> getBaseMapper();
default void action(@NotNull(message = "操作VO对象不能为空") @Valid CloseOperateVO operateVO){
if (NullUtils.isEmpty(operateVO.getId())){
throw new MyException(RestResponse.MSG.PARAM_VALUE_ERROR).setMsg("未发现指定操作对象id");
}
T closeEntity = getBaseMapper().selectById(operateVO.getId());
if (closeEntity==null){
throw new MyException(RestResponse.MSG.NO_DATA_EXISTS);
}
closeEntity.closeable(operateVO.getCloseAction());
//Wrappers.lambdaUpdate(getTClass()); 创建LambdaUpdate时指定实体类
LambdaUpdateWrapper<T> lambdaUpdateWrapper = Wrappers.lambdaUpdate(getTClass());
//或者lambdaUpdateWrapper.setEntityClass(getTClass());
lambdaUpdateWrapper.eq(T::getId,operateVO.getId()).set(T::getCloseStatus, operateVO.getCloseAction().getStepState());
getBaseMapper().update(null,lambdaUpdateWrapper);
}
}
```
### LambdaUpdateWapper 配合泛型使用出现错误java.lang.BootstrapMethodError: call site initialization exception
```java
public interface CloseV1Service<T extends CloseStatefulEntity & CloseV1able> {
Class<T> getTClass();
BaseMapper<T> getBaseMapper();
default void action(@NotNull(message = "操作VO对象不能为空") @Valid CloseOperateVO operateVO){
if (NullUtils.isEmpty(operateVO.getId())){
throw new MyException(RestResponse.MSG.PARAM_VALUE_ERROR).setMsg("未发现指定操作对象id");
}
T closeEntity = getBaseMapper().selectById(operateVO.getId());
if (closeEntity==null){
throw new MyException(RestResponse.MSG.NO_DATA_EXISTS);
}
closeEntity.closeable(operateVO.getCloseAction());
LambdaUpdateWrapper<T> lambdaUpdateWrapper = Wrappers.lambdaUpdate(getTClass());
lambdaUpdateWrapper
.eq(T::getId,operateVO.getId()) //此处抛出异常 因为CloseStatefulEntity存在getId()方法 而CloseV1able不存在
.set(T::getCloseStatus, operateVO.getCloseAction().getStepState());
getBaseMapper().update(null,lambdaUpdateWrapper);
}
}
```
#### 原因LambdaUpdateWrapper设置的泛型是因为有两个上界LambdaUpdateWrapper使用方法引用时泛型的方法这个方法只在泛型一个上界类中存在则抛出java.lang.BootstrapMethodError: call site initialization exception异常
#### 解决办法:在两个上界中都添加用到的方法或者只设置一个上界

View File

@ -0,0 +1,118 @@
## Springboot-WebSocket
### **问题**java websocket服务器发生EOFException异常,断开和客户端的连接
#### **原因**:使用了 Nginx 反向代理后默认超过60S没有数据传输的连接会自动断开。
#### **解决方案一:**
nginx配置
```Shell
location /finance/ws/ {
proxy_pass http://192.168.3.47:56667/finance/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
```
可以更新配置
/etc/nginx/nginx.conf
```Shell
# 在http模块中添加
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
```
map指令的作用该作用主要是根据客户端请求中的值来构造改变connection_upgrade的值即根据变量的值创建新的变量connection_upgrade 创建的规则就是{}里面的东西。其中的规则没有做匹配,因此使用默认的,即 http_upgrade为空字符串的话那么值就是 close。
则代理配置更新为:
```Shell
location /finance/ws/ {
proxy_pass http://192.168.3.47:56667/finance/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
```
如上配置其实无法解决nginx默认60s没有任何传输请求断开的问题可以适当延长**proxy_read_timeout的时间**
#### 解决方案二后台判断有连接客户端的情况通过心跳机制每隔30-50秒和客户端主动建立连接。**
1.创建定时任务
```Java
@Slf4j
//Component 注入到Spring容器
@Component
public class HeartbeatWebSocket {
//使用@cheduled定义一个方法为计划任务fixedDelay属性表示表示上一次任务执行完成后多久再执行参数类型long,单位ms
@Scheduled(fixedDelay = 50000)
private void heartbeat() {
//这个Map存储了所有连接的会话
ConcurrentMap<Long, MonthEndCarryForwardServer> sessionPool = MonthEndCarryForwardServer.getSessionPool();
if (!sessionPool.isEmpty()){
//循环会话池 对每个会话发送ping指令
sessionPool.forEach((k,v)->{
try {
//发送指令
v.getSession().getBasicRemote().sendText("ping");
} catch (IOException e) {
e.printStackTrace();
log.error("心跳发送出错:",e);
}
});
}
}
}
```
注解`@Scheduled`属性含义:
```Java
cron表达式指定任务在特定时间执行
fixedDelay:表示上一次任务执行完成后多久再执行参数类型long,单位ms
fixedDelayString:与fixedDelay一样只是参数类型是String
fixedRate:表示按一定的频率执行任务参数类型long,单位ms 如: fixedRate(5000)表示这个定时器任务每5秒执行一次
fixedRateString:与fixedRate一样只是参数类型变为String
initialDelay:表示延迟多久再第一次执行任务参数类型为long ,单位ms
initialDelayString与initialDelay一样只是参数类型String
```
2.在Springboot Application启动类上添加`@EnableScheduling`注解启用 Spring 的计划任务执行功能
```Java
@EnableScheduling //启用 Spring 的计划任务执行功能 注:不添加此注解无法开启计划任务
@SpringBootApplication(scanBasePackages = "com.guadou.erp")
public class FinanceApplication {
public static void main(String[] args) throws UnknownHostException {
ConfigurableApplicationContext context = SpringApplication.run(FinanceApplication.class, args);
AppConfig appConfig = new AppConfig(context);
appConfig.setAppName("Finance APP");
}
}
```
### **问题**:测试方法无法启动 Error creating bean with name 'serverEndpointExporter' defined in class path resource
#### 解决方案:设置@SpringBootTest的属性为SpringBootTest.WebEnvironment.RANDOM_PORT
```java
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AppTest.class,webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
```

View File

@ -0,0 +1,3 @@
## 踩坑记录
格式化时间格式"HH:mm:ss" "hh:mm:ss"

View File

@ -2,7 +2,7 @@
### 【1235】 This version of MySQL doesnt yet support LIMIT & IN/ALL/ANY/SOME subquery
+ ##### 含义:这版本的 MySQL 不支持使用 LIMIT 子句的 IN/ALL/ANY/SOME 子查询
+ ##### 说明:当前版本的 MySQL 不支持使用 LIMIT 子句的 IN/ALL/ANY/SOME 子查询
+ ##### 问题SQL

2
mysql/MySql 技巧.md Normal file
View File

@ -0,0 +1,2 @@
# MySql 技巧

View File

@ -1,29 +1,92 @@
Ubuntu20.04 设置开机自启
========================
### 第一步
> 本文由 [简悦 SimpRead](http://ksria.com/simpread/) 转码, 原文地址 [blog.csdn.net](https://blog.csdn.net/qq_43685040/article/details/111574332)
第一步
---
执行 **ls /lib/systemd/system** 你可以看到有很多启动脚本,其中就有我们需要的 **rc-local.service**
![](assets/20201223103738935.png)
### 第二步
第二步
---
打开 **rc-local.service**脚本内容,内容如下:
打开 **rc-local.service** 脚本内容,内容如下:
![](assets/20201223103800889.png)
一般正常的启动文件主要分成三部分
* \[Unit\] 段: 启动顺序与依赖关系
* \[Service\] 段: 启动行为,如何启动,启动类型
* \[Install\] 段: 定义如何安装这个配置文件,即怎样做到开机启动
* 可以看出,/etc/rc.local 的启动顺序是在网络后面,但是显然它少了 Install 段,也就没有定义如何做到开机启动,所以显然这样配置是无效的。 因此我们就需要在后面帮他加上 \[Install\] 段:
* **[Unit]** 段: 启动顺序与依赖关系
* **[Service]** 段: 启动行为, 如何启动,启动类型
* **[Install]** 段: 定义如何安装这个配置文件,即怎样做到开机启动
————————————————
版权声明本文为CSDN博主「任求其-zzx」的原创文章遵循CC 4.0 BY-SA版权协议转载请附上原文出处链接及本声明。
原文链接https://blog.csdn.net/qq\_43685040/article/details/111574332
可以看出,**/etc/rc.local** 的启动顺序是在网络后面,但是显然它少了 **Install** 段,也就没有定义如何做到开机启动,所以显然这样配置是无效的。 因此我们就需要在后面帮他加上 **[Install]** 段:
### 第三步
```shell
[Install]
WantedBy=multi-user.target
Alias=rc-local.service
### 第四步
```
### 第五步
![](assets/20201223103837439.png)
### 第六步
PS添加了 [Install] 内容后,下面两行的 **WantedBy****Alias** 两个英文跟上面的都是绿色的,要是绿色才有用。
一般需要先修改 **rc-local.service** 的权限才可以进行编辑。
```
sudo chmod 777 /lib/systemd/syste,/rc-local.service
```
第三步
---
查看系统中有无 **/etc/rc.local** 这个文件,没有则自己创建一个。
然后把你需要启动脚本写入 **/etc/rc.local** ,我们不妨写一些测试的脚本放在里面,以便验证脚本是否生效.
```shell
#!/bin/sh
echo "看到这行字,说明添加自启动脚本成功。" > /usr/local/test.log
exit 0
```
![](assets/20201223103852538.png)
PS**#!/bin/sh** 这一行一定要加上!一定要加上!
第四步
---
**rc.local** 加上权限
```
sudo chmod +x /etc/rc.local
```
做完这一步,还需要最后一步 前面我们说 **systemd** 默认读取 **/etc/systemd/system** 下的配置文件, 所以还需要在 **/etc/systemd/system** 目录下创建软链接
```shell
ln -s /lib/systemd/system/rc.local.service /etc/systemd/system/
```
![](assets/20201223103909625.png)
第五步
---
重启 **Ubuntu** 后,去 **/usr/local** 下看看有没有生成 **test.log** 这个文件以及这个文件的内容。
![](assets/20201223104001940.png)
第六步
---
如果在 **/etc/rc.local** 中添加的是 **./test.sh** 这种类型的,要在末尾加上 &,如下图, **不然重启 ubuntu 的时候会卡在启动界面进不去系统。**
![](assets/20201223163227878.png)
https://www.cnblogs.com/wtil/p/12808424.html

Binary file not shown.

After

(image error) Size: 198 KiB

Binary file not shown.

After

(image error) Size: 199 KiB

Binary file not shown.

After

(image error) Size: 214 KiB

Binary file not shown.

After

(image error) Size: 102 KiB

Binary file not shown.

After

(image error) Size: 34 KiB

Binary file not shown.

After

(image error) Size: 410 KiB

Binary file not shown.

After

(image error) Size: 74 KiB