-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
444 lines (238 loc) · 653 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>随笔小记</title>
<subtitle>Java 前端</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://lwblog.xyz/"/>
<updated>2020-09-05T07:18:53.334Z</updated>
<id>http://lwblog.xyz/</id>
<author>
<name>Mr.Wang</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>Spring_Cloud笔记一</title>
<link href="http://lwblog.xyz/posts/2e26b41f.html"/>
<id>http://lwblog.xyz/posts/2e26b41f.html</id>
<published>2020-09-05T04:47:11.000Z</published>
<updated>2020-09-05T07:18:53.334Z</updated>
<content type="html"><![CDATA[<h1 id="SpringCloud微服务"><a href="#SpringCloud微服务" class="headerlink" title="SpringCloud微服务"></a>SpringCloud微服务</h1><h2 id="1-微服务架构编码构建"><a href="#1-微服务架构编码构建" class="headerlink" title="1. 微服务架构编码构建"></a>1. 微服务架构编码构建</h2><h3 id="1-1-IDEA新建project工作空间"><a href="#1-1-IDEA新建project工作空间" class="headerlink" title="1.1 IDEA新建project工作空间"></a>1.1 IDEA新建project工作空间</h3><p>创建父工程步骤:</p><ol><li><p>微服务cloud整体聚合父工程Project</p><ul><li><p>NewProject<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghrsexqhlnj31lq0m646d.jpg" alt=""></p></li><li><p>聚合总工程名字:cloud2020</p></li><li><p>Maven选版本:3.6.3</p></li><li><p>工程名字****</p></li><li><p>字符编码<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghrsumj5jxj314h0u0gv4.jpg" alt=""></p></li><li><p>注解生效激活<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghrswv04h1j31hy0oqjz7.jpg" alt=""></p></li><li><p>java编译版本选jdk1.8<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghrsy39tbij31hy0jgdkt.jpg" alt=""></p></li><li><p>File Type过滤<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghrt1bozpmj31470u0aim.jpg" alt=""><br>填入的代码块:</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">*.hprof;*.idea;*.iml;*.pyc;*.pyo;*.rbc;*.yarb;*~;.DS_Store;.git;.hg;.svn;CVS;__pycache__;_svn;vssver.scc;vssver2.scc;</span><br></pre></td></tr></table></figure></li></ul></li><li><p>父工程POM</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> <!--表示这是一个pom父工程的文件--></span><br><span class="line"> <packaging>pom</packaging></span><br><span class="line"></span><br><span class="line"> <!-- 统一管理jar包版本 --></span><br><span class="line"> <properties></span><br><span class="line"> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></span><br><span class="line"> <maven.compiler.source>1.8</maven.compiler.source></span><br><span class="line"> <maven.compiler.target>1.8</maven.compiler.target></span><br><span class="line"> <junit.version>4.12</junit.version></span><br><span class="line"> <log4j.version>1.2.17</log4j.version></span><br><span class="line"> <lombok.version>1.16.18</lombok.version></span><br><span class="line"> <mysql.version>8.0.19</mysql.version></span><br><span class="line"> <druid.version>1.1.16</druid.version></span><br><span class="line"> <mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version></span><br><span class="line"> </properties></span><br><span class="line"> <!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version --></span><br><span class="line"> <dependencyManagement></span><br><span class="line"> <dependencies></span><br><span class="line"> <!--spring boot 2.2.2--></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-dependencies</artifactId></span><br><span class="line"> <version>2.2.2.RELEASE</version></span><br><span class="line"> <type>pom</type></span><br><span class="line"> <scope>import</scope></span><br><span class="line"> </dependency></span><br><span class="line"> <!--spring cloud Hoxton.SR1--></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-dependencies</artifactId></span><br><span class="line"> <version>Hoxton.SR1</version></span><br><span class="line"> <type>pom</type></span><br><span class="line"> <scope>import</scope></span><br><span class="line"> </dependency></span><br><span class="line"> <!--spring cloud alibaba 2.1.0.RELEASE--></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.alibaba.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-alibaba-dependencies</artifactId></span><br><span class="line"> <version>2.1.0.RELEASE</version></span><br><span class="line"> <type>pom</type></span><br><span class="line"> <scope>import</scope></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>mysql</groupId></span><br><span class="line"> <artifactId>mysql-connector-java</artifactId></span><br><span class="line"> <version>${mysql.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.alibaba</groupId></span><br><span class="line"> <artifactId>druid</artifactId></span><br><span class="line"> <version>${druid.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.mybatis.spring.boot</groupId></span><br><span class="line"> <artifactId>mybatis-spring-boot-starter</artifactId></span><br><span class="line"> <version>${mybatis.spring.boot.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>junit</groupId></span><br><span class="line"> <artifactId>junit</artifactId></span><br><span class="line"> <version>${junit.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>log4j</groupId></span><br><span class="line"> <artifactId>log4j</artifactId></span><br><span class="line"> <version>${log4j.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.projectlombok</groupId></span><br><span class="line"> <artifactId>lombok</artifactId></span><br><span class="line"> <version>${lombok.version}</version></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"> </dependencyManagement></span><br><span class="line"> <build></span><br><span class="line"> <plugins></span><br><span class="line"> <plugin></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-maven-plugin</artifactId></span><br><span class="line"> <configuration></span><br><span class="line"> <fork>true</fork></span><br><span class="line"> <addResources>true</addResources></span><br><span class="line"> </configuration></span><br><span class="line"> </plugin></span><br><span class="line"> </plugins></span><br><span class="line"> </build></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></li><li><p>Maven工程落地细节复习</p><ul><li>Maven中的DependencyManager和dependencies<br>maven使用DependencyManager元素来提供了一种管理依赖版本号的方式。<strong><em>==通常会在一个组织或者项目的最顶层的父pom中看到此元素。==</em></strong><br>使用dependencyManagement可以使所有子项目中引用一个依赖而不用显示列出版本号。Maven会沿父子层级向上走,直到找到dependencyManagement元素的项目 ,然后它就会使用版本号<br>如果某一个子项目需要另外一个版本,加上version即可。如果子项目中声明了版本号,那么使用子项目中的jar包。</li></ul></li></ol><p><strong><em>==dependencyManagement只是声明依赖,并不实现引入,一次子项目需要显式的声明需要用的依赖。==</em></strong></p><pre><code>* maven中跳过单元测试</code></pre><ol start="2"><li>父工程创建完成后执行<code>mvn:install</code>将父工程发不到仓库方便子工程继承<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghru63tkvyj30qm0so1kx.jpg" alt=""></li></ol><h3 id="1-2-Rest微服务工程构建"><a href="#1-2-Rest微服务工程构建" class="headerlink" title="1.2 Rest微服务工程构建"></a>1.2 Rest微服务工程构建</h3><h4 id="1-2-1-构建步骤"><a href="#1-2-1-构建步骤" class="headerlink" title="1.2.1 构建步骤"></a>1.2.1 构建步骤</h4><h5 id="1-2-1-1-Cloud-provider-payment8001微服务提供者支付Module模块"><a href="#1-2-1-1-Cloud-provider-payment8001微服务提供者支付Module模块" class="headerlink" title="1.2.1.1 Cloud-provider-payment8001微服务提供者支付Module模块"></a>1.2.1.1 Cloud-provider-payment8001微服务提供者支付Module模块</h5><ol><li><p>建cloud-provider-payment8001<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghrufr0a73j31b20u0n7f.jpg" alt=""></p></li><li><p>改pom文件</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br></pre></td><td class="code"><pre><span class="line"> <?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <parent></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </parent></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <artifactId>cloud-provider-payment8001</artifactId></span><br><span class="line"></span><br><span class="line"> <dependencies></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-web</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-actuator</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.mybatis.spring.boot</groupId></span><br><span class="line"> <artifactId>mybatis-spring-boot-starter</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.alibaba</groupId></span><br><span class="line"> <artifactId>druid-spring-boot-starter</artifactId></span><br><span class="line"> <version>1.1.10</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>mysql</groupId></span><br><span class="line"> <artifactId>mysql-connector-java</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-jdbc</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-devtools</artifactId></span><br><span class="line"> <scope>runtime</scope></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.projectlombok</groupId></span><br><span class="line"> <artifactId>lombok</artifactId></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-test</artifactId></span><br><span class="line"> <scope>test</scope></span><br><span class="line"> </dependency></span><br><span class="line"> <!--<dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-autoconfigure</artifactId></span><br><span class="line"> <version>2.3.1.RELEASE</version></span><br><span class="line"> </dependency>--></span><br><span class="line"> </dependencies></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></li><li><p>写yml</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 8001</span><br><span class="line"></span><br><span class="line">spring:</span><br><span class="line"> application:</span><br><span class="line"> name: cloud-payment-service</span><br><span class="line"> datasource:</span><br><span class="line"> driver-class-name: com.mysql.cj.jdbc.Driver</span><br><span class="line"> # serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true</span><br><span class="line"> url: jdbc:mysql://111.229.203.5:3306/db2019?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&useSSL=false</span><br><span class="line"> username: weaver</span><br><span class="line"> password: 192612</span><br><span class="line"> type: com.alibaba.druid.pool.DruidDataSource</span><br><span class="line"></span><br><span class="line">mybatis:</span><br><span class="line"> mapperLocations: classpath:mapper/*.xml</span><br><span class="line"> type-aliases-package: com.atguigu.springcloud.entities</span><br></pre></td></tr></table></figure></li><li><p>主启动</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud;</span><br><span class="line"></span><br><span class="line">import org.springframework.boot.SpringApplication;</span><br><span class="line">import org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 主启动类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-15-22-19</span><br><span class="line"> */</span><br><span class="line">@SpringBootApplication</span><br><span class="line">public class PaymentMain8001 {</span><br><span class="line"> public static void main(String[] args) {</span><br><span class="line"> SpringApplication.run(PaymentMain8001.class,args);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>业务类</p><ol><li><p>建表sql</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">CREATE TABLE `payment` (</span><br><span class="line">`id` BIGINT (20) NOT NULL AUTO_INCREMENT COMMENT 'ID',</span><br><span class="line">`serial` VARCHAR (200) DEFAULT'',</span><br><span class="line">PRIMARY KEY (id)</span><br><span class="line">) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8</span><br></pre></td></tr></table></figure></li><li><p>entitles</p><ul><li><p>主实体Payment</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.entities;</span><br><span class="line"></span><br><span class="line">import lombok.AllArgsConstructor;</span><br><span class="line">import lombok.Data;</span><br><span class="line">import lombok.NoArgsConstructor;</span><br><span class="line"></span><br><span class="line">import java.io.Serializable;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 支付实体类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-16-00-08</span><br><span class="line"> */</span><br><span class="line">@Data</span><br><span class="line">@AllArgsConstructor</span><br><span class="line">@NoArgsConstructor</span><br><span class="line">public class Payment implements Serializable {</span><br><span class="line"> private Long id;</span><br><span class="line"> private String serial;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>son封装体CommonResult</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.entities;</span><br><span class="line"></span><br><span class="line">import lombok.AllArgsConstructor;</span><br><span class="line">import lombok.Data;</span><br><span class="line">import lombok.NoArgsConstructor;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 穿结果给前端的类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-16-00-14</span><br><span class="line"> */</span><br><span class="line">@Data</span><br><span class="line">@AllArgsConstructor</span><br><span class="line">@NoArgsConstructor</span><br><span class="line">public class CommonResult<T> {</span><br><span class="line"> private Integer code;</span><br><span class="line"> private String message;</span><br><span class="line"> private T data;</span><br><span class="line"> public CommonResult(Integer code,String message){</span><br><span class="line"> this(code,message,null);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul></li><li><p>dao</p><ul><li><p>接口PaymentDao</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.dao;</span><br><span class="line"></span><br><span class="line">import com.atguigu.springcloud.entities.Payment;</span><br><span class="line">import org.apache.ibatis.annotations.Mapper;</span><br><span class="line">import org.apache.ibatis.annotations.Param;</span><br><span class="line">import org.springframework.stereotype.Repository;</span><br><span class="line">import org.springframework.web.bind.annotation.RestController;</span><br><span class="line"></span><br><span class="line">//@Repository</span><br><span class="line">@Mapper</span><br><span class="line">public interface PaymentDao {</span><br><span class="line"> public int create(Payment payment);</span><br><span class="line"> public Payment getPaymentById(@Param("id")Long id);</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>mybatis的映射文件PaymentMapper.xml</p><ul><li><p>路径:<code>src\main\resources\mapper\PaymentMapper.xml</code></p></li><li><p>mapper映射文件</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><!DOCTYPE mapper</span><br><span class="line"> PUBLIC '-//mybatis.org//DTD Mapper 3.0//EN'</span><br><span class="line"> 'http://mybatis.org/dtd/mybatis-3-mapper.dtd'></span><br><span class="line"><mapper namespace="com.atguigu.springcloud.dao.PaymentDao"></span><br><span class="line"> <insert id="create" parameterType="Payment" useGeneratedKeys="true" keyProperty="id"></span><br><span class="line"> insert into payment(serial) values (#{serial});</span><br><span class="line"> </insert></span><br><span class="line"> <resultMap id="BaseResultMap" type="Payment"></span><br><span class="line"> <id column="id" property="id" jdbcType="BIGINT"></id></span><br><span class="line"> <result column="serial" property="serial" jdbcType="VARCHAR"/></span><br><span class="line"> </resultMap></span><br><span class="line"> <select id="getPaymentById" parameterType="Long" resultMap="BaseResultMap"></span><br><span class="line"> select * from payment where id = #{id};</span><br><span class="line"> </select></span><br><span class="line"></mapper></span><br></pre></td></tr></table></figure></li></ul></li></ul></li><li><p>service</p><ul><li><p>接口PaymentService</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.service;</span><br><span class="line"></span><br><span class="line">import com.atguigu.springcloud.entities.Payment;</span><br><span class="line">import org.apache.ibatis.annotations.Param;</span><br><span class="line"></span><br><span class="line">public interface PaymentService {</span><br><span class="line"> public int create(Payment payment);</span><br><span class="line"> public Payment getPaymentById(Long id);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>实现类</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.service.impl;</span><br><span class="line"></span><br><span class="line">import com.atguigu.springcloud.dao.PaymentDao;</span><br><span class="line">import com.atguigu.springcloud.entities.Payment;</span><br><span class="line">import com.atguigu.springcloud.service.PaymentService;</span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line">import org.springframework.stereotype.Service;</span><br><span class="line"></span><br><span class="line">import javax.annotation.Resource;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 支付功能的service层</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-16-00-42</span><br><span class="line"> */</span><br><span class="line">@Service</span><br><span class="line">public class PaymentServiceImpl implements PaymentService {</span><br><span class="line"> @Resource</span><br><span class="line"> private PaymentDao paymentDao;</span><br><span class="line"> @Override</span><br><span class="line"> public int create(Payment payment) {</span><br><span class="line"> return paymentDao.create(payment);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @Override</span><br><span class="line"> public Payment getPaymentById(Long id) {</span><br><span class="line"> return paymentDao.getPaymentById(id);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul></li><li><p>controller</p></li></ol></li></ol><pre><code><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.Controller;</span><br><span class="line"></span><br><span class="line">import com.atguigu.springcloud.entities.CommonResult;</span><br><span class="line">import com.atguigu.springcloud.entities.Payment;</span><br><span class="line">import com.atguigu.springcloud.service.PaymentService;</span><br><span class="line">import lombok.extern.slf4j.Slf4j;</span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line">import org.springframework.web.bind.annotation.*;</span><br><span class="line"></span><br><span class="line">import javax.annotation.Resource;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 支付的控制层</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-16-00-48</span><br><span class="line"> */</span><br><span class="line">@RestController</span><br><span class="line">@Slf4j</span><br><span class="line">public class PaymentController {</span><br><span class="line"></span><br><span class="line"> @Resource</span><br><span class="line"> private PaymentService paymentService;</span><br><span class="line"></span><br><span class="line"> @PostMapping(value = "/payment/create")</span><br><span class="line"> public CommonResult create(Payment payment){</span><br><span class="line"> int result = paymentService.create(payment);</span><br><span class="line"> log.info("****插入结果:"+result);</span><br><span class="line"> if(result > 0){</span><br><span class="line"> return new CommonResult(200,"插入数据库成功",result);</span><br><span class="line"> }else{</span><br><span class="line"> return new CommonResult(444,"插入数据失败");</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> @GetMapping(value = "/payment/get/{id}")</span><br><span class="line"> public CommonResult getPaymentById(@PathVariable("id") Long id){</span><br><span class="line"> Payment payment = paymentService.getPaymentById(id);</span><br><span class="line"> log.info("****查询结果:"+payment);</span><br><span class="line"> if(payment != null){</span><br><span class="line"> return new CommonResult(200,"查询成功",payment);</span><br><span class="line"> }else{</span><br><span class="line"> return new CommonResult(444,"没有对应记录,查询查询失败");</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></code></pre><h5 id="1-2-1-2-热部署Devtools"><a href="#1-2-1-2-热部署Devtools" class="headerlink" title="1.2.1.2 热部署Devtools"></a>1.2.1.2 热部署Devtools</h5><ol><li><p>Adding devtools to your project</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-devtools</artifactId></span><br><span class="line"> <scope>runtime</scope></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br></pre></td></tr></table></figure></li><li><p>Adding plugin to your pom.xml<br>下段的配置我们需要粘贴进聚合父类总工程的pom.xml里面</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><build></span><br><span class="line"> <plugins></span><br><span class="line"> <plugin></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-maven-plugin</artifactId></span><br><span class="line"> <configuration></span><br><span class="line"> <fork>true</fork></span><br><span class="line"> <addResources>true</addResources></span><br><span class="line"> </configuration></span><br><span class="line"> </plugin></span><br><span class="line"> </plugins></span><br><span class="line"> </build></span><br></pre></td></tr></table></figure></li><li><p>Enabling automatic build<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghsqe7i9egj314b0u0n5w.jpg" alt=""></p></li><li><p>Update the value of<br>使用快捷键<code>command+option+shift+/</code>选择<code>Registry</code><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghsqkdotlwj30nc08mae8.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghsqlsjiadj31d80te79m.jpg" alt=""></p></li><li><p>重启IDEA<br>关闭并重新启动idea开发工具</p></li></ol><h5 id="1-2-1-3-cloud-consumer-order80微服务消费者订单Module模块"><a href="#1-2-1-3-cloud-consumer-order80微服务消费者订单Module模块" class="headerlink" title="1.2.1.3 cloud-consumer-order80微服务消费者订单Module模块"></a>1.2.1.3 cloud-consumer-order80微服务消费者订单Module模块</h5><ol><li><p>建cloud-consumer-order80<br>同8001服务端创建moudle的方法相同</p></li><li><p>改POM</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <parent></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </parent></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <artifactId>cloud-consumer-order80</artifactId></span><br><span class="line"> <dependencies></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-web</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-actuator</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-devtools</artifactId></span><br><span class="line"> <scope>runtime</scope></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.projectlombok</groupId></span><br><span class="line"> <artifactId>lombok</artifactId></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-test</artifactId></span><br><span class="line"> <scope>test</scope></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></li><li><p>写YML</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 80</span><br></pre></td></tr></table></figure></li><li><p>主启动<br>同上</p></li><li><p>业务类</p><ul><li><p>RestTemplate是什么<br>RestTemplate提供了多种便捷访问远程Http服务的方法<br>是一种简单便捷的访问restful服务模版累,是Spring提供的用于访问Rest服务的客户端模版工具集</p></li><li><p>官网及使用<br><a href="https://docs.spring.io/spring-framework/docs/5.2.2.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html" target="_blank" rel="noopener">官网地址</a></p></li><li><p><strong>使用:*</strong><br>使用restTemplate访问restful接口非常的简单粗暴无脑。(url,requestMap,ResponseBean.class)这三个参数分别代表Rest请求地址、请求参数、Http响应转换被转换成对象类型</p></li><li><p>config配置类</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.config;</span><br><span class="line"></span><br><span class="line">import org.springframework.beans.factory.annotation.Configurable;</span><br><span class="line">import org.springframework.context.annotation.Bean;</span><br><span class="line">import org.springframework.context.annotation.Configuration;</span><br><span class="line">import org.springframework.web.client.RestTemplate;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 配置类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-16-20-33</span><br><span class="line"> */</span><br><span class="line"></span><br><span class="line">@Configuration</span><br><span class="line">public class ApplicationContextConfig {</span><br><span class="line"> @Bean</span><br><span class="line"> public RestTemplate getRestTemplate(){</span><br><span class="line"> return new RestTemplate();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>创建controller</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.controller;</span><br><span class="line"></span><br><span class="line">import com.atguigu.springcloud.entities.CommonResult;</span><br><span class="line">import com.atguigu.springcloud.entities.Payment;</span><br><span class="line">import lombok.extern.slf4j.Slf4j;</span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line">import org.springframework.web.bind.annotation.GetMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.PathVariable;</span><br><span class="line">import org.springframework.web.bind.annotation.RestController;</span><br><span class="line">import org.springframework.web.client.RestTemplate;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 订单类web层</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-16-19-57</span><br><span class="line"> */</span><br><span class="line">@RestController</span><br><span class="line">@Slf4j</span><br><span class="line">public class OrderController {</span><br><span class="line"> public static final String PAYMENT_URL = "http://localhost:8001";</span><br><span class="line"> @Autowired</span><br><span class="line"> private RestTemplate restTemplate;</span><br><span class="line"></span><br><span class="line"> @GetMapping("/consumer/payment/create")</span><br><span class="line"> public CommonResult<Payment> create(Payment payment){</span><br><span class="line"> return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);</span><br><span class="line"> }</span><br><span class="line"> @GetMapping("/consumer/payment/get/{id}")</span><br><span class="line"> public CommonResult<Payment> getPayment(@PathVariable("id")Long id){</span><br><span class="line"> return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul></li><li><p>测试</p><ul><li>先启动cloud-provider-payment8001</li><li>再启动cloud-consumer-order80</li><li>idea右下角弹出窗口,选择show,共同管理两个端口号</li><li>使用<a href="http://localhost/consumer/payment/get/31访问,80为默认端口号可省略不写" target="_blank" rel="noopener">http://localhost/consumer/payment/get/31访问,80为默认端口号可省略不写</a></li><li>不要忘记<code>@RequestBody</code>注解</li></ul></li><li><p>Run Dashboard的配置</p><ul><li><p>通过修改idea的workspace.xml的方式来快速打开Run Dashboard窗口</p></li><li><p>开启Run DashBoard</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><option name="configurationTypes"></span><br><span class="line"> <set></span><br><span class="line"> <option value="SpringBootApplicationConfigurationType" /></span><br><span class="line"> </set></span><br><span class="line"> </option></span><br></pre></td></tr></table></figure></li><li><p>可能由于idea版本的不同,需要关闭重新启动</p></li></ul></li></ol><h5 id="1-2-1-4-工程重构"><a href="#1-2-1-4-工程重构" class="headerlink" title="1.2.1.4 工程重构"></a>1.2.1.4 工程重构</h5><ol><li><p>观察问题<br>系统中有重复的部分,需要进行重构</p></li><li><p>新建-cloud-api-commons</p></li><li><p>pom</p><pre><code><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <parent></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </parent></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <artifactId>cloud-api-commons</artifactId></span><br><span class="line"></span><br><span class="line"> <dependencies></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-devtools</artifactId></span><br><span class="line"> <scope>runtime</scope></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.projectlombok</groupId></span><br><span class="line"> <artifactId>lombok</artifactId></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>cn.hutool</groupId></span><br><span class="line"> <artifactId>hutool-all</artifactId></span><br><span class="line"> <version>5.1.0</version></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></code></pre></li><li><p>entities</p></li><li><p>maven命令<code>clean install</code></p></li><li><p>订单80和支付8001分别改造</p><ul><li><p>删除各自的原先有过的entities文件夹</p></li><li><p>各自黏贴pom内容</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><!--引入自定义的api通用包--></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <artifactId>cloud-api-commons</artifactId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </dependency></span><br></pre></td></tr></table></figure></li></ul></li></ol><h4 id="1-2-2-目前工程详图"><a href="#1-2-2-目前工程详图" class="headerlink" title="1.2.2 目前工程详图"></a>1.2.2 目前工程详图</h4><h2 id="2-Eureka服务注册与发现"><a href="#2-Eureka服务注册与发现" class="headerlink" title="2. Eureka服务注册与发现"></a>2. Eureka服务注册与发现</h2><h3 id="2-1-Eureka基础知识"><a href="#2-1-Eureka基础知识" class="headerlink" title="2.1 Eureka基础知识"></a>2.1 Eureka基础知识</h3><ol><li><p>什么是服务治理</p></li><li><p>什么是服务注册<br>Eureka Server 作为服务注册功能的服务器,它是服务注册中心,而系统中其他微服务,使用 Eureka 的客户端连接到 Eureka Server 并维持心跳连接,这样系统维护人员就可以通过 Eureka Server来监控各个微服务是否正常运行。<br>在服务注册与发现中有一个注册中心,服务器启动时,会把当前自己的服务器信息比如服务地址,通信地址等注册到注册中心上,另一方(消费者)以别名的方式在注册中心上获取实际的服务器通讯地址,然后再实现本地RPC调用远程RPC。<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghtrn44cudj31b90gngtz.jpg" alt=""></p></li><li><p>Eureka两组件</p><ol><li>Eureka Server 提供服务注册服务<br>各个微服务节点通过配置启动后,会在 EurekaServer中进行注册,这样 EurekaServer中的服务注册表中将会存储所有可用服务节点的信息。</li><li>EurekaClient通过注册中心进行访问<br>是一个Java客户端,用于简化与 Eureka Server的交互,客户端也同时具备一个内置的,使用 轮询负载算法的负载均衡器。在应用启动后,将会向Eureka Server 发送心跳(默认周期30秒)。如果Eureka Server 在多个心跳周期内没有接收到某个节点的心跳,EurekaServer将会从服务注册表中将这个服务节点移除(默认90秒)</li></ol></li></ol><h3 id="2-2-单机Eureka构建步骤"><a href="#2-2-单机Eureka构建步骤" class="headerlink" title="2.2 单机Eureka构建步骤"></a>2.2 单机Eureka构建步骤</h3><h4 id="2-2-1-IDEA生成eurekaServer端服务注册中心类似物业公司"><a href="#2-2-1-IDEA生成eurekaServer端服务注册中心类似物业公司" class="headerlink" title="2.2.1 IDEA生成eurekaServer端服务注册中心类似物业公司"></a>2.2.1 IDEA生成eurekaServer端服务注册中心类似物业公司</h4><ol><li><p>建Moudel<code>cloud-eureka-server7001</code></p></li><li><p>改POM</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <parent></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </parent></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <artifactId>cloud-eureka-server7001</artifactId></span><br><span class="line"></span><br><span class="line"> <dependencies></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <artifactId>cloud-api-commons</artifactId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-web</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-actuator</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-devtools</artifactId></span><br><span class="line"> <scope>runtime</scope></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.projectlombok</groupId></span><br><span class="line"> <artifactId>lombok</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-test</artifactId></span><br><span class="line"> <scope>test</scope></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>junit</groupId></span><br><span class="line"> <artifactId>junit</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></li><li><p>写YML</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 7001</span><br><span class="line">eureka:</span><br><span class="line"> instance:</span><br><span class="line"> hostname: localhost # eureka服务端实例名称</span><br><span class="line"> client:</span><br><span class="line"> #false表示不向注册中心注册自己</span><br><span class="line"> register-with-eureka: false</span><br><span class="line"> #false表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务</span><br><span class="line"> fetch-registry: false</span><br><span class="line"> service-url:</span><br><span class="line"> # 设置与 eureka server交互的地址查询服务和注册服务都需要依赖这个地址</span><br><span class="line"> defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/</span><br></pre></td></tr></table></figure></li><li><p>主启动</p><p> <code>@EnableEurekaServer</code>:声明自己是 eureka 的服务端</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">package com.atguitu.springcloud;</span><br><span class="line"></span><br><span class="line">import org.springframework.boot.SpringApplication;</span><br><span class="line">import org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line">import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: Eureka主启动类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-17-14-21</span><br><span class="line"> */</span><br><span class="line">@SpringBootApplication</span><br><span class="line">@EnableEurekaServer //表示这个就是注册中心,等级注册</span><br><span class="line">public class EurekaMain7001 {</span><br><span class="line"> public static void main(String[] args) {</span><br><span class="line"> SpringApplication.run(EurekaMain7001.class,args);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>测试</p><ul><li>测试地址:<code>http://localhost:7001</code></li><li>结果页面<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghtsvv46ukj31cp0u0guw.jpg" alt=""></li></ul></li></ol><h4 id="2-2-2-EurekaClient端cloud-provider-payment8001将注册进EurekaServer成为服务提供者provider,类似尚硅谷学校对外提供授课服务"><a href="#2-2-2-EurekaClient端cloud-provider-payment8001将注册进EurekaServer成为服务提供者provider,类似尚硅谷学校对外提供授课服务" class="headerlink" title="2.2.2 EurekaClient端cloud-provider-payment8001将注册进EurekaServer成为服务提供者provider,类似尚硅谷学校对外提供授课服务"></a>2.2.2 EurekaClient端cloud-provider-payment8001将注册进EurekaServer成为服务提供者provider,类似尚硅谷学校对外提供授课服务</h4><ol><li><p>建立<code>cloud-provider-payment8001</code></p></li><li><p>改POM<br>增加客户端的jar包</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><!--eureka-client--></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></span><br><span class="line"> </dependency></span><br></pre></td></tr></table></figure></li><li><p>写YML<br>更改8001的yaml配置文件,增加一下配置</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">eureka:</span><br><span class="line"> client:</span><br><span class="line"> #表示是否将自己注册进EurekaServer默认为true</span><br><span class="line"> register-with-eureka: true</span><br><span class="line"> #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用 负载均衡</span><br><span class="line"> fetch-registry: false</span><br><span class="line"> service-url:</span><br><span class="line"> # 入住的地址</span><br><span class="line"> defaultZone: http://localhost:7001/eureka</span><br></pre></td></tr></table></figure></li><li><p>主启动<br>在主启动上添加<code>@EnableEurekaClient</code>注解,表示这个是客户端</p></li><li><p>测试</p><ul><li>先要启动EurekaServer</li><li>地址:<a href="http://localhost:7001/" target="_blank" rel="noopener">http://localhost:7001/</a><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghttlxh4fwj31ft0u0qce.jpg" alt=""></li><li>微服务注册名配置说明<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghttmktrtcj316q0lo7kj.jpg" alt=""></li></ul></li><li><p>自我保护机制</p></li></ol><h4 id="2-2-3-EurekaClient端cloud-consumer-order80将注册进EurekaServer成为服务消费者consumer-类似来尚硅谷上课消费的各位同学"><a href="#2-2-3-EurekaClient端cloud-consumer-order80将注册进EurekaServer成为服务消费者consumer-类似来尚硅谷上课消费的各位同学" class="headerlink" title="2.2.3 EurekaClient端cloud-consumer-order80将注册进EurekaServer成为服务消费者consumer,类似来尚硅谷上课消费的各位同学"></a>2.2.3 EurekaClient端cloud-consumer-order80将注册进EurekaServer成为服务消费者consumer,类似来尚硅谷上课消费的各位同学</h4><ol><li>修改<code>cloud-consumer-order80</code>模块</li><li>POM文件修改,同8001模块相同</li><li>写YML</li><li>主启动,同8001模块相同</li><li>测试<ul><li>先要启动EurekaServer,7001服务</li><li>在要启动服务提供者provider,8001服务</li><li>eureka服务器<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghtu58jt0rj31c70u0dqi.jpg" alt=""></li><li><a href="http://localhost/consumer/payment/get/31" target="_blank" rel="noopener">http://localhost/consumer/payment/get/31</a></li></ul></li></ol><h3 id="2-3-集群Eureka构建步骤"><a href="#2-3-集群Eureka构建步骤" class="headerlink" title="2.3 集群Eureka构建步骤"></a>2.3 集群Eureka构建步骤</h3><h4 id="2-3-1-集群原理说明"><a href="#2-3-1-集群原理说明" class="headerlink" title="2.3.1 集群原理说明"></a>2.3.1 集群原理说明</h4><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghtuonapuxj31da0fan8m.jpg" alt=""><br>微服务RPC远程服务调用最核心是什么:<br>高可用,如果注册中心只有一个,出了故障就会导致整个服务环境不可用<br>解决方法:搭建Eureka注册中心集群,实现负载均衡+故障排错<br><strong><em>集群注册的原理:</em></strong>互相注册,相互守望<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghtusj1w51j30k80a4t9f.jpg" alt=""></p><h4 id="2-3-2-EurekaServer集群环境构建步骤"><a href="#2-3-2-EurekaServer集群环境构建步骤" class="headerlink" title="2.3.2 EurekaServer集群环境构建步骤"></a>2.3.2 EurekaServer集群环境构建步骤</h4><ol><li><p>参考<code>cloud-eureka-server7001</code>新建<code>cloud-eureka-server7002</code></p></li><li><p>改POM</p></li><li><p>修改映射配置<br>在系统的hosts文件中添加一下配置</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">127.0.0.1 eureka7001.com</span><br><span class="line">127.0.0.1 eureka7002.com</span><br></pre></td></tr></table></figure></li><li><p>写YML(以前单机)<br> <del>单机的看以前的配置</del></p><ul><li><p>7001的yml配置文件</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 7001</span><br><span class="line">eureka:</span><br><span class="line"> instance:</span><br><span class="line"> hostname: 127.0.0.1 # eureka服务端实例名称,集群名字要不同有区分</span><br><span class="line"> client:</span><br><span class="line"> #false表示不向注册中心注册自己</span><br><span class="line"> register-with-eureka: false</span><br><span class="line"> #false表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务</span><br><span class="line"> fetch-registry: false</span><br><span class="line"> service-url:</span><br><span class="line"> # 设置与 eureka server交互的地址查询服务和注册服务都需要依赖这个地址</span><br><span class="line"> defaultZone: http://localhost:7002/eureka/</span><br></pre></td></tr></table></figure></li><li><p>7002的yml配置文件</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 7002</span><br><span class="line">eureka:</span><br><span class="line"> instance:</span><br><span class="line"> hostname: localhost</span><br><span class="line"> client:</span><br><span class="line"> #false表示不向注册中心注册自己</span><br><span class="line"> register-with-eureka: false</span><br><span class="line"> #false表示自己就是注册中心,职责是维护服务实例,并不需要去检索服务</span><br><span class="line"> fetch-registry: false</span><br><span class="line"> service-url:</span><br><span class="line"> # 设置与 eureka server交互的地址查询服务和注册服务都需要依赖这个地址</span><br><span class="line"> defaultZone: http://127.0.0.1:7001/eureka/</span><br></pre></td></tr></table></figure></li></ul></li><li><p>主启动</p></li></ol><h4 id="2-3-3-将支付服务8001微服务发布到上面2台Eureka集群配置中"><a href="#2-3-3-将支付服务8001微服务发布到上面2台Eureka集群配置中" class="headerlink" title="2.3.3 将支付服务8001微服务发布到上面2台Eureka集群配置中"></a>2.3.3 将支付服务8001微服务发布到上面2台Eureka集群配置中</h4><p>yml配置文件的修改<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghtx03t8v2j31ji0kukjl.jpg" alt=""></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 8001</span><br><span class="line"></span><br><span class="line">spring:</span><br><span class="line"> application:</span><br><span class="line"> name: cloud-payment-service</span><br><span class="line"> datasource:</span><br><span class="line"> driver-class-name: com.mysql.cj.jdbc.Driver</span><br><span class="line"> # serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true</span><br><span class="line"> url: jdbc:mysql://111.229.203.5:3306/db2019?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&useSSL=false</span><br><span class="line"> username: weaver</span><br><span class="line"> password: 192612</span><br><span class="line"> type: com.alibaba.druid.pool.DruidDataSource</span><br><span class="line"></span><br><span class="line">mybatis:</span><br><span class="line"> mapperLocations: classpath:mapper/*.xml</span><br><span class="line"> type-aliases-package: com.atguigu.springcloud.entities</span><br><span class="line"></span><br><span class="line">eureka:</span><br><span class="line"> client:</span><br><span class="line"> #表示是否将自己注册进EurekaServer默认为true</span><br><span class="line"> register-with-eureka: true</span><br><span class="line"> #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用 负载均衡</span><br><span class="line"> fetch-registry: false</span><br><span class="line"> service-url:</span><br><span class="line"> # 入住的地址</span><br><span class="line"> #defaultZone: http://localhost:7001/eureka</span><br><span class="line"> # 集群的配置</span><br><span class="line"> defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka</span><br></pre></td></tr></table></figure><h4 id="2-3-4-将订单服务80微服务发布到上面2台Eureka集群配置中"><a href="#2-3-4-将订单服务80微服务发布到上面2台Eureka集群配置中" class="headerlink" title="2.3.4 将订单服务80微服务发布到上面2台Eureka集群配置中"></a>2.3.4 将订单服务80微服务发布到上面2台Eureka集群配置中</h4><p>修改配置同<strong><em>2.3.3</em></strong></p><h4 id="2-3-5-测试01"><a href="#2-3-5-测试01" class="headerlink" title="2.3.5 测试01"></a>2.3.5 测试01</h4><ol><li>先要启动EurekaServer,7001/7002服务</li><li>再要启动服务提供者provider,8001服务</li><li>再要启动消费者,80</li><li><a href="http://localhost/consumer/payment/get/31" target="_blank" rel="noopener">http://localhost/consumer/payment/get/31</a></li></ol><h4 id="2-3-6-支付服务提供者8001集群环境构建"><a href="#2-3-6-支付服务提供者8001集群环境构建" class="headerlink" title="2.3.6 支付服务提供者8001集群环境构建"></a>2.3.6 支付服务提供者8001集群环境构建</h4><ol><li><p>参考<code>cloud-provider-payment8001</code>新建<code>cloud-provider-payment8002</code></p></li><li><p>改POM<br> 同8001的POM文件一致</p></li><li><p>写YML</p><ul><li>7001</li><li>7002</li></ul></li><li><p>主启动类</p></li><li><p>修改8001/8002的Controller</p><ul><li><p>8001<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghu3xu9igpj31je0qc1ky.jpg" alt=""></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">// 在各个方法中调用 serverPort 查看端口号</span><br><span class="line">@Value("${server.port}")</span><br><span class="line">private String serverPort;</span><br></pre></td></tr></table></figure></li><li><p>8002<br>配置方法同8001</p></li></ul></li></ol><h4 id="2-3-7-负载均衡"><a href="#2-3-7-负载均衡" class="headerlink" title="2.3.7 负载均衡"></a>2.3.7 负载均衡</h4><ol><li>bug<br> 订单服务访问地址不能写死</li><li>使用<code>@LoadBalance</code>注解赋予RestTemplate负载均衡的能力<ul><li>在之前单机版中写死为8001,但是集群后有8001与8002,</li><li>进入 <a href="http://eureka7001.com:7001/" target="_blank" rel="noopener">http://eureka7001.com:7001/</a> 查看 8001 与 8002 对应的名称 application</li><li>将 PAYMENT_URL 改为 http+application 名 :<a href="http://CLOUD-PAYMENT-SERVICE" target="_blank" rel="noopener">http://CLOUD-PAYMENT-SERVICE</a></li><li>此时未开启负载均衡不能访问页面:将80端口下的配置类ApplicationContextConfig 下生成的 RestTemplate 的bean方法上添加注解 @LoadBalanced</li><li><a href="http://localhost/consumer/payment/get/34" target="_blank" rel="noopener">http://localhost/consumer/payment/get/34</a> 访问查看端口号,可以看到在8001与8002之间来回切换</li><li>在客户端的yml配置中需要开启对负载均衡的支持<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghu41i0w8gj31ok0qm7wi.jpg" alt=""></li></ul></li><li>ApplicationContextBean<br> 提前说下Ribbon的负载均衡功能</li></ol><h4 id="2-3-8-测试02"><a href="#2-3-8-测试02" class="headerlink" title="2.3.8 测试02"></a>2.3.8 测试02</h4><ol><li>先要启动EurekaServer,7001/7002服务</li><li>再要启动服务提供者provider,8001/8002服务</li><li><a href="http://localhost/consumer/payment/get/31" target="_blank" rel="noopener">http://localhost/consumer/payment/get/31</a></li><li>结果<ul><li>负载均衡效果达到</li><li>8001/8002端口交替出现</li></ul></li><li>Ribbon和Eureka整合后Consumer可以直接调用服务而不用再关心地址和端口号,且该服务还有负载功能了</li></ol><h3 id="2-4-actuator微服务信息完善"><a href="#2-4-actuator微服务信息完善" class="headerlink" title="2.4 actuator微服务信息完善"></a>2.4 actuator微服务信息完善</h3><ol><li><p>主机名称:服务名称修改</p><ul><li><p>当前问题<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghu4act4d8j31jf0u0wmb.jpg" alt=""></p></li><li><p>修改cloud-provider-payment8001</p><ul><li><p>修改部分</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">instance:</span><br><span class="line"> instance-id: payment8002 # 自定义主机名</span><br><span class="line"> #prefer-ip-address: true # 设置暴露ip地址</span><br></pre></td></tr></table></figure><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghu4fqizzkj31ne0p01ky.jpg" alt=""></p></li><li><p>完整内容</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 8002</span><br><span class="line"></span><br><span class="line">spring:</span><br><span class="line"> application:</span><br><span class="line"> #s</span><br><span class="line"> name: cloud-payment-service</span><br><span class="line"> datasource:</span><br><span class="line"> driver-class-name: com.mysql.cj.jdbc.Driver</span><br><span class="line"> # serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true</span><br><span class="line"> url: jdbc:mysql://111.229.203.5:3306/db2019?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&useSSL=false</span><br><span class="line"> username: weaver</span><br><span class="line"> password: 192612</span><br><span class="line"> type: com.alibaba.druid.pool.DruidDataSource</span><br><span class="line"></span><br><span class="line">mybatis:</span><br><span class="line"> mapperLocations: classpath:mapper/*.xml</span><br><span class="line"> type-aliases-package: com.atguigu.springcloud.entities</span><br><span class="line"></span><br><span class="line">eureka:</span><br><span class="line"> client:</span><br><span class="line"> #表示是否将自己注册进EurekaServer默认为true</span><br><span class="line"> register-with-eureka: true</span><br><span class="line"> #是否从EurekaServer抓取已有的注册信息,默认为true。单节点无所谓,集群必须设置为true才能配合ribbon使用 负载均衡</span><br><span class="line"> fetch-registry: false</span><br><span class="line"> service-url:</span><br><span class="line"> # 入住的地址</span><br><span class="line"> #defaultZone: http://localhost:7001/eureka</span><br><span class="line"> # 集群的配置</span><br><span class="line"> defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka</span><br><span class="line"> instance:</span><br><span class="line"> instance-id: payment8002 # 自定义主机名</span><br><span class="line"> prefer-ip-address: true # 设置暴露ip地址</span><br></pre></td></tr></table></figure></li></ul></li><li><p>修改之后<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghu4ik12bxj31qo0u0aif.jpg" alt=""></p></li></ul></li><li><p>访问信息有ip信息提示</p><ul><li>当前问题:没有ip提示</li><li>修改修改cloud-provider-payment8001<ul><li>修改部分<br>见上面截图部分</li><li>完整内容<br>见上面截图部分</li></ul></li><li>修改之后</li></ul></li></ol><h3 id="2-5-服务发现Discovery"><a href="#2-5-服务发现Discovery" class="headerlink" title="2.5 服务发现Discovery"></a>2.5 服务发现Discovery</h3><ol><li><p>对于注册进eureka里面的微服务,可以通过服务发现来获得该服务的信息</p></li><li><p>修改cloud-provider-payment8001的Controller<br> <strong><em>目前存在一个问题,返回的discoveryClient中不能像视频中一样返回带有服务名称的json串,目前返回的为空</em></strong></p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">@Resource</span><br><span class="line"> private DiscoveryClient discoveryClient;</span><br><span class="line"></span><br><span class="line"> @GetMapping("/payment/discovery")</span><br><span class="line"> public DiscoveryClient discovery(){</span><br><span class="line"> // 得到所有服务名</span><br><span class="line"> List<String> services = discoveryClient.getServices();</span><br><span class="line"> services.forEach(ele->{</span><br><span class="line"> log.info("***service***"+ele);</span><br><span class="line"> });</span><br><span class="line"> // 得到服务名对应的信息</span><br><span class="line"> List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");</span><br><span class="line"> instances.forEach(ele->{</span><br><span class="line"> log.info(ele.getServiceId()+"\t"+ele.getHost()+"\t"+ele.getPort()+"\t"+ele.getUri());</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> return discoveryClient;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure></li><li><p>8001主启动类<br> 8001 主类添加注解 <code>@EnableDiscoveryClient</code></p></li><li><p>自测</p><ul><li>先要启动EurekaServer,7001/7002服务</li><li>再启动8001主启动类,需要稍等一会</li><li><a href="http://localhost:8001/payment/discovery" target="_blank" rel="noopener">http://localhost:8001/payment/discovery</a></li></ul></li></ol><h3 id="2-6-Eureka自我保护"><a href="#2-6-Eureka自我保护" class="headerlink" title="2.6 Eureka自我保护"></a>2.6 Eureka自我保护</h3><ol><li><p>故障现象<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghuvpxtwcaj31ew0ianea.jpg" alt=""></p></li><li><p>导致原因<br>一句话:某一时刻某一个微服务不可用了,Eureka不会立即清理,依旧会对该微服务的信息进行保存。属于CAP里面的AP分支</p><ol><li>为什么会产生自我保护?<br>为了防止 EurekaClient 可以正常运行,但是在 EurekaServer 网络不通的情况下,EurekaServer 不会立刻将 EurekaClient 服务剔除。</li><li>什么是自我保护模式?<br>默认情况下,EurekaServer在一定时间内没有接收到某个微服务实例的心跳,EurekaServer将会注销该实例(默认90s),但是当网络分区故障发生,微服务与 EurekaServer 之间无法正常通信,以上行为就非常危险。当EurekaServer节点在短时间内丢失过多客户端时,那么这个节点就会进入自我保护模式。<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghuvxf920dj30vu0hkh1b.jpg" alt=""></li></ol></li><li><p>怎么禁止自我保护(一般生产环境中不会禁止自我保护)</p><ul><li><p>注册中心eureakeServer端7001</p><ol><li><p>出厂默认,自我保护机制是开启的<code>eureka.server.enable-self-preservation = true</code></p></li><li><p>使用<code>eureka.server.enable-self-preservation = false</code>可以禁用自我保护模式</p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghuy88tgopj318o0iyb29.jpg" alt=""></p></li><li><p>关闭效果</p></li><li><p>在eurekaServer端7001处设置关闭自我保护机制</p></li></ol></li><li><p>生产者客户端eureakeClient端8001</p><ul><li><p><code>eureka.instance.lease-renewal-interval-in-seconds=30 eureka.instance.lease-expiration-duration-in-seconds=90</code></p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghuy8sj2ooj31mw0nsx6p.jpg" alt=""></p></li><li><p>测试</p><ul><li>7001和8001都配置完成</li><li>先启动7001在启动8001</li><li>先关闭8001 马上被删除</li></ul></li></ul></li></ul></li></ol><h2 id="3-Zookeeper服务注册与发现"><a href="#3-Zookeeper服务注册与发现" class="headerlink" title="3. Zookeeper服务注册与发现"></a>3. Zookeeper服务注册与发现</h2><h3 id="3-1-Eureka停止更新了你怎么办"><a href="#3-1-Eureka停止更新了你怎么办" class="headerlink" title="3.1 Eureka停止更新了你怎么办"></a>3.1 Eureka停止更新了你怎么办</h3><p><a href="https://github.com/Netflix/eureka/wiki" target="_blank" rel="noopener">https://github.com/Netflix/eureka/wiki</a></p><h3 id="3-2-SpringCloud整合Zookeeper代替Eureka"><a href="#3-2-SpringCloud整合Zookeeper代替Eureka" class="headerlink" title="3.2 SpringCloud整合Zookeeper代替Eureka"></a>3.2 SpringCloud整合Zookeeper代替Eureka</h3><h4 id="3-2-1-注册中心Zookeeper"><a href="#3-2-1-注册中心Zookeeper" class="headerlink" title="3.2.1 注册中心Zookeeper"></a>3.2.1 注册中心Zookeeper</h4><ol><li>zookeeper是一个分布式协调工具,可以实现注册中心功能</li><li>关闭Linux服务器防火墙后启动zookeeper服务器</li><li>zookeeper服务器取代Eureka服务器,zk作为服务注册中心</li></ol><h4 id="3-2-2-服务提供者"><a href="#3-2-2-服务提供者" class="headerlink" title="3.2.2 服务提供者"></a>3.2.2 服务提供者</h4><ol><li><p>新建<code>cloud-provider-payment8004</code></p></li><li><p>POM</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <parent></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </parent></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <artifactId>cloud-consumerzk-order80</artifactId></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></li><li><p>YML</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"># 8004表示注册到zookeeper服务器的支付服务提供端口号</span><br><span class="line">server:</span><br><span class="line"> port: 8004</span><br><span class="line"></span><br><span class="line"># 服务别名----注册zookeeper到注册中心名称</span><br><span class="line">spring:</span><br><span class="line"> application:</span><br><span class="line"> name: cloud-provider-payment</span><br><span class="line"> cloud:</span><br><span class="line"> zookeeper:</span><br><span class="line"> connect-string: 49.235.24.12:2181</span><br></pre></td></tr></table></figure></li><li><p>主启动类</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud;</span><br><span class="line"></span><br><span class="line">import org.springframework.boot.SpringApplication;</span><br><span class="line">import org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line">import org.springframework.cloud.client.discovery.EnableDiscoveryClient;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: zk服务端启动类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-18-17-20</span><br><span class="line"> */</span><br><span class="line">@SpringBootApplication</span><br><span class="line">//该注解用于向使用consul或者zookeeper作为注册中心时注册服务</span><br><span class="line">@EnableDiscoveryClient</span><br><span class="line">public class PaymentMain8004 {</span><br><span class="line"> public static void main(String[] args) {</span><br><span class="line"> SpringApplication.run(PaymentMain8004.class,args);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>Controller</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.controller;</span><br><span class="line"></span><br><span class="line">import lombok.extern.slf4j.Slf4j;</span><br><span class="line">import org.springframework.beans.factory.annotation.Value;</span><br><span class="line">import org.springframework.web.bind.annotation.GetMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.RestController;</span><br><span class="line"></span><br><span class="line">import java.util.UUID;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 控制层</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-18-20-32</span><br><span class="line"> */</span><br><span class="line">@RestController</span><br><span class="line">@Slf4j</span><br><span class="line">public class PaymentController {</span><br><span class="line"> @Value("${server.port}")</span><br><span class="line"> private String serverPort;</span><br><span class="line"></span><br><span class="line"> @GetMapping(value = "/payment/zk")</span><br><span class="line"> public String paymentzk(){</span><br><span class="line"> return "springcloud with zookeeper:"+serverPort+"\t"+ UUID.randomUUID().toString();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>启动8004注册进zookeeper</p><ul><li>启动后的问题</li><li>解决zookeeper半分jar包冲突</li><li>排除zk冲突后的新POM</li></ul></li><li><p>验证测试<br><a href="http://localhost:8004/payment/zk" target="_blank" rel="noopener">http://localhost:8004/payment/zk</a></p></li><li><p>验证测试2<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghv9w26r5jj31ei0f0wqm.jpg" alt=""></p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"># 获取服务名</span><br><span class="line">[zk: localhost:2181(CONNECTED) 0] ls /services</span><br><span class="line">[cloud-provider-payment]</span><br><span class="line"># 获取流水号</span><br><span class="line">[zk: localhost:2181(CONNECTED) 1] ls /services/cloud-provider-payment</span><br><span class="line">[efc76371-522d-4d5d-8f56-f8fe4deb7a47]</span><br><span class="line"># 获取详细信息</span><br><span class="line">[zk: localhost:2181(CONNECTED) 2] get /services/cloud-provider-payment/efc76371-522d-4d5d-8f56-f8fe4deb7a47</span><br><span class="line">{"name":"cloud-provider-payment","id":"efc76371-522d-4d5d-8f56-f8fe4deb7a47","address":"WINDOWS-N0GUAG7","port":8004,"sslPort":null,"payload":{"@class":"org.springframework.cloud.zookeeper.discovery.ZookeeperInstance","id":"application-1","name":"cloud-provider-payment","metadata":{}},"registrationTimeUTC":1590232919360,"serviceType":"DYNAMIC","uriSpec":{"parts":[{"value":"scheme","variable":true},{"value":"://","variable":false},{"value":"address","variable":true},{"value":":","variable":false},{"value":"port","variable":true}]}}</span><br></pre></td></tr></table></figure></li><li><p>思考</p><ul><li><p>服务节点是临时还是持久</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">[zk: localhost:2181(CONNECTED) 18] ls /services/cloud-provider-payment</span><br><span class="line">[efc76371-522d-4d5d-8f56-f8fe4deb7a47]</span><br><span class="line">[zk: localhost:2181(CONNECTED) 19] ls /services/cloud-provider-payment</span><br><span class="line">[efc76371-522d-4d5d-8f56-f8fe4deb7a47]</span><br><span class="line">[zk: localhost:2181(CONNECTED) 20] ls /services/cloud-provider-payment</span><br><span class="line">[efc76371-522d-4d5d-8f56-f8fe4deb7a47]</span><br><span class="line">[zk: localhost:2181(CONNECTED) 21] ls /services/cloud-provider-payment</span><br><span class="line">[]</span><br><span class="line">[zk: localhost:2181(CONNECTED) 22]</span><br></pre></td></tr></table></figure></li></ul></li></ol><h4 id="3-2-3-服务消费者"><a href="#3-2-3-服务消费者" class="headerlink" title="3.2.3 服务消费者"></a>3.2.3 服务消费者</h4><ol><li><p>新建<code>cloud-consumerzk-order80</code></p></li><li><p>POM<br>同zookeeper服务端配置(8004)相同</p></li><li><p>YML<br>同zookeeper服务端配置(8004)相同</p></li><li><p>主启动<br>同zookeeper服务端配置(8004)相同</p></li><li><p>业务类</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.controller;</span><br><span class="line"></span><br><span class="line">import lombok.extern.slf4j.Slf4j;</span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line">import org.springframework.web.bind.annotation.GetMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.RestController;</span><br><span class="line">import org.springframework.web.client.RestTemplate;</span><br><span class="line"></span><br><span class="line">import javax.annotation.Resource;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 控制层</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-19-09-16</span><br><span class="line"> */</span><br><span class="line">@RestController</span><br><span class="line">@Slf4j</span><br><span class="line">public class ConsumerController {</span><br><span class="line"></span><br><span class="line"> private static final String INVOKE_URL = "http://cloud-provider-payment";</span><br><span class="line"> @Autowired</span><br><span class="line"> private RestTemplate restTemplate;</span><br><span class="line"></span><br><span class="line"> @GetMapping("/consumer/payment/zk")</span><br><span class="line"> public String paymentInfo(){</span><br><span class="line"> String result = restTemplate.getForObject(INVOKE_URL + "/payment/zk", String.class);</span><br><span class="line"> return result;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>启动8004注册进zookeeper</p></li><li><p>验证测试:<a href="http://localhost:8004/payment/zk" target="_blank" rel="noopener">http://localhost:8004/payment/zk</a></p></li><li><p>访问测试地址:<a href="http://localhost/consumer/payment/zk" target="_blank" rel="noopener">http://localhost/consumer/payment/zk</a></p></li></ol><h2 id="4-Consul服务注册与发现"><a href="#4-Consul服务注册与发现" class="headerlink" title="4. Consul服务注册与发现"></a>4. Consul服务注册与发现</h2><h3 id="4-1-Consul简介"><a href="#4-1-Consul简介" class="headerlink" title="4.1 Consul简介"></a>4.1 Consul简介</h3><ol><li><p>是什么:<a href="https://www.consul.io/intro/index.html" target="_blank" rel="noopener">https://www.consul.io/intro/index.html</a><br>Consul是一种服务网格解决方案,提供具有服务发现,配置和分段功能的全功能控制平面。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建完整的服务网格。Consul需要一个数据平面,并支持代理和本机集成模型。Consul附带了一个简单的内置代理,因此一切都可以直接使用,还支持Envoy等第三方代理集成。</p></li><li><p>能干嘛</p><ul><li><p>服务发现:Consul的客户端可以注册服务,例如 api或mysql,其他客户端可以使用Consul来发现给定服务的提供者。使用DNS或HTTP,应用程序可以轻松找到它们依赖的服务。</p></li><li><p>运行状况检查:领事客户端可以提供任何数量的运行状况检查,这些检查可以与给定服务(“ Web服务器返回200 OK”)或与本地节点(“内存利用率低于90%”)相关联。操作员可以使用此信息来监视群集的运行状况,服务发现组件可以使用此信息将流量路由到运行状况不佳的主机之外。</p></li><li><p>KV商店:应用程序可以将Consul的分层键/值存储用于多种目的,包括动态配置,功能标记,协调,领导者选举等。简单的HTTP API使其易于使用。</p></li><li><p>安全的服务通信:领事可以为服务生成并分发TLS证书,以建立相互TLS连接。 意图 可用于定义允许哪些服务进行通信。可以使用可以实时更改的意图轻松管理服务分段,而不必使用复杂的网络拓扑和静态防火墙规则。</p></li><li><p>多数据中心:Consul开箱即用地支持多个数据中心。这意味着Consul的用户不必担心会构建其他抽象层以扩展到多个区域。</p></li></ul></li><li><p>去哪下:<a href="https://www.consul.io/downloads.html" target="_blank" rel="noopener">https://www.consul.io/downloads.html</a></p></li><li><p>怎么玩:<a href="https://www.springcloud.cc/spring-cloud-consul.html" target="_blank" rel="noopener">https://www.springcloud.cc/spring-cloud-consul.html</a></p></li></ol><h3 id="4-2-安装并运行Consul"><a href="#4-2-安装并运行Consul" class="headerlink" title="4.2 安装并运行Consul"></a>4.2 安装并运行Consul</h3><ol><li>官网安装说明:<a href="https://learn.hashicorp.com/consul/getting-started/install.html" target="_blank" rel="noopener">https://learn.hashicorp.com/consul/getting-started/install.html</a></li><li>下载完成后只有一个consul.exe文件,硬盘路径下双击运行,查看版本信息</li><li>使用开发模式启动</li></ol><hr><ol><li>将下载的exe文件双击即可安装</li><li>在 exe ==文件的目录==下打开黑窗口</li><li>输入 consul –version 检测是否安装成功</li><li>启动服务:consul agent -dev</li><li>通过 <a href="http://localhost:8500/" target="_blank" rel="noopener">http://localhost:8500/</a> 访问web界面<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghvw7x5oo0j31fz0u0qba.jpg" alt=""></li></ol><h3 id="4-3-服务提供者"><a href="#4-3-服务提供者" class="headerlink" title="4.3 服务提供者"></a>4.3 服务提供者</h3><ol><li><p>新建Module支付服务provider8006<code>cloud-providerconsul-payment8006</code></p></li><li><p>POM</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <parent></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </parent></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <artifactId>cloud-providerconsul-payment8006</artifactId></span><br><span class="line"></span><br><span class="line"> <dependencies></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-consul-discovery --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-consul-discovery</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <artifactId>cloud-api-commons</artifactId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-web</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-actuator</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-devtools</artifactId></span><br><span class="line"> <scope>runtime</scope></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.projectlombok</groupId></span><br><span class="line"> <artifactId>lombok</artifactId></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-test</artifactId></span><br><span class="line"> <scope>test</scope></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></li><li><p>YML</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 8006</span><br><span class="line">spring:</span><br><span class="line"> application:</span><br><span class="line"> name: consul-provider-payment</span><br><span class="line"> cloud:</span><br><span class="line"> consul:</span><br><span class="line"> discovery:</span><br><span class="line"> service-name: ${spring.application.name}</span><br><span class="line"> host: 111.229.203.5</span><br><span class="line"> port: 8500</span><br></pre></td></tr></table></figure></li><li><p>主启动类</p></li><li><p>业务类Controller</p></li><li><p>验证测试:<a href="http://localhost:8006/payment/consul" target="_blank" rel="noopener">http://localhost:8006/payment/consul</a></p></li></ol><h3 id="4-4-服务消费者"><a href="#4-4-服务消费者" class="headerlink" title="4.4 服务消费者"></a>4.4 服务消费者</h3><ol><li><p>pom</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <parent></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </parent></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <artifactId>cloud-consumerconsul-order80</artifactId></span><br><span class="line"></span><br><span class="line"> <dependencies></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-consul-discovery --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-consul-discovery</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <artifactId>cloud-api-commons</artifactId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-web</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-actuator</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-devtools</artifactId></span><br><span class="line"> <scope>runtime</scope></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.projectlombok</groupId></span><br><span class="line"> <artifactId>lombok</artifactId></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-test</artifactId></span><br><span class="line"> <scope>test</scope></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></li><li><p>yml</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 80</span><br><span class="line">spring:</span><br><span class="line"> application:</span><br><span class="line"> name: cloud-consumer-order</span><br><span class="line"> cloud:</span><br><span class="line"> consul:</span><br><span class="line"> host: localhost</span><br><span class="line"> port: 8500</span><br><span class="line"> discovery:</span><br><span class="line"> service-name: ${spring.application.name}</span><br></pre></td></tr></table></figure></li></ol><h3 id="4-5-三个注册中心异同点"><a href="#4-5-三个注册中心异同点" class="headerlink" title="4.5 三个注册中心异同点"></a>4.5 三个注册中心异同点</h3><ol><li>CAP<ul><li>C:Consistency(强一致性)</li><li>A:Availability(可用性)</li><li>P:Partition tolerance(分区容错)</li><li>CAP理论关注粒度是数据,而不是整体系统设计的策略<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghvx3gkg37j30mv07qtcq.jpg" alt=""></li></ul></li><li>经典CAP图<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghvx2ezkkmj30pw0jbgrb.jpg" alt=""></li></ol><h2 id="5-Ribbon负载均衡服务调用"><a href="#5-Ribbon负载均衡服务调用" class="headerlink" title="5. Ribbon负载均衡服务调用"></a>5. Ribbon负载均衡服务调用</h2><h3 id="5-1-概述"><a href="#5-1-概述" class="headerlink" title="5.1 概述"></a>5.1 概述</h3><ol><li><p>是什么<br>Spring Cloud Ribbon 是基于 Netflix Ribbon 实现的一套==客户端负载均衡的工具==。<br>简单的说,Ribbonn是Netflix的开源项目,主要功能 是提供==客户端的软件负载均衡算法和服务调用。==Ribbon客户端组件提供一系列完善的配置项,如连接超时,重试等。就是在配置文件中列出 Loa Balancer后面所有机器,Ribbon会自动帮助你基于某种规则 (如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。</p></li><li><p>官网资料:<a href="https://github.com/Netflix/ribbon/wiki/Getting-Started" target="_blank" rel="noopener">https://github.com/Netflix/ribbon/wiki/Getting-Started</a></p></li><li><p>能干嘛</p><ul><li>LB(负载均衡)<ul><li>负载均衡(Load Balance)是什么<br>将用户的请求平摊的分配到多个服务上,从而达到HA(高可用),常见的负载均衡有 Nginx,LVS,硬件 F5等。</li><li>Ribbon 本地负载均衡客户端 VS Nginx 服务端负载均衡<br>Nginx 是服务器 负载均衡,客户端所有请求都会交给 nginx,然后由 nginx实现请求转发。即负载均衡是由服务端实现的。<br>Ribbon 是本地负载均衡,在微服务调用接口时,在注册中心上获取注册信息服务列表 之后缓存在JVM本地,从而实现本地RPC远程服务调用技术</li></ul></li><li>前面我们讲解过了80通过轮询负载访问8001/8002</li><li>一句话<br>负载均衡+RestTemplate 调用</li></ul></li></ol><h3 id="5-2-Ribbon负载均衡演示"><a href="#5-2-Ribbon负载均衡演示" class="headerlink" title="5.2 Ribbon负载均衡演示"></a>5.2 Ribbon负载均衡演示</h3><ol><li><p>架构说明<br>Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eurake结合之事其中一个实例<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghwd6wnewvj31680k2k4t.jpg" alt=""></p><ul><li>Ribbon工作时有两步<ol><li>第一步先选择 EurekaServer,优先选择统一区域负载较少的 server</li><li>第二部再根据用户指定的策略,从server取到的服务注册列表中选择一个地址。其中 Riibon 提供了多种策略(轮询,随机,根据响应时间加权)。</li></ol></li></ul></li><li><p>POM<br>不需要引入</p></li><li><p>RestTemplate的使用</p><ul><li><p>getForObject方法/getForEntity方法<br><code>getForObject</code>返回对象为响应体中数据转化成的对象,基本上可以理解为json<br><code>getForEntity</code>返回对象为ResponseEntity对象,包含响应中的一些重要信息,比如响应头、响应状态码、响应体</p></li><li><p>postForObject/postForEntity</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">@GetMapping("/consumer/payment/forentity/{id}")</span><br><span class="line"> public CommonResult<Payment> getPayment1(@PathVariable("id") Long id){</span><br><span class="line"> ResponseEntity<CommonResult> entity = restTemplate.getForEntity(PAYMENT_URL + "/payment/get/" + id, CommonResult.class);</span><br><span class="line"> if(entity.getStatusCode().is2xxSuccessful()){</span><br><span class="line"> return entity.getBody();</span><br><span class="line"> }else{</span><br><span class="line"> return new CommonResult(444,"操作失败");</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure></li><li><p>GET请求方法</p></li><li><p>POST请求方法</p></li></ul></li></ol><h3 id="5-3-Ribbon核心组件IRule"><a href="#5-3-Ribbon核心组件IRule" class="headerlink" title="5.3 Ribbon核心组件IRule"></a>5.3 Ribbon核心组件IRule</h3><ol><li><p>IRule:根据特定算法从服务列表中选取一个要访问的服务</p><ol><li>RoundRobinRule 轮询</li><li>RandomRule 随机</li><li>RetryRule 先按照RoundRobinRule的 策略获取服务,如果获取服务失败则在指定时间里进行重试,获取可用服务</li><li>WeightedResponseTimeRule 对RoundRobinRule的扩展,响应速度越快,实例选择权重越大 ,越容易被选择</li><li>BestAvailableRule 会先过滤掉由于多次访问故障而处于断路器 跳闸状态的服务,然后选择一个并发一个最小的服务</li><li>BestAvaibilityFilteringRule 先过滤掉故障实例,再选择并发量较小的实例</li><li>ZoneAvoidanceRule 默认规则,符合server所在区域的性能和server的可用性选择服务器</li></ol></li><li><p>如何替换</p><ul><li><p>修改<code>cloud-consumer-order80</code></p></li><li><p>注意配置细节<br>IRule配置类不能放在@ComponentSan 的包及子包下,因为默认的扫描会变成全局负载均衡都按照这样的规则。</p></li><li><p>新建package:<code>com.atguigu.myrule</code></p></li><li><p>上面包下新建MySelfRule规则类</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.myrule;</span><br><span class="line"></span><br><span class="line">import com.netflix.loadbalancer.IRule;</span><br><span class="line">import com.netflix.loadbalancer.RandomRule;</span><br><span class="line">import org.springframework.context.annotation.Bean;</span><br><span class="line">import org.springframework.context.annotation.Configuration;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 规则类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-20-09-12</span><br><span class="line"> */</span><br><span class="line">@Configuration</span><br><span class="line">public class MyselfRule {</span><br><span class="line"> @Bean</span><br><span class="line"> public IRule myRule(){</span><br><span class="line"> //使用随机的负载均衡</span><br><span class="line"> return new RandomRule();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><ul><li><p>主启动类添加@RibbonClient</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud;</span><br><span class="line"></span><br><span class="line">import com.atguigu.myrule.MyselfRule;</span><br><span class="line">import javafx.application.Application;</span><br><span class="line">import org.springframework.boot.SpringApplication;</span><br><span class="line">import org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line">import org.springframework.cloud.netflix.eureka.EnableEurekaClient;</span><br><span class="line">import org.springframework.cloud.netflix.ribbon.RibbonClient;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 订单类的启动器</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-16-19-52</span><br><span class="line"> */</span><br><span class="line">@SpringBootApplication</span><br><span class="line">@EnableEurekaClient</span><br><span class="line">// 选择要接收的服务和配置类</span><br><span class="line">@RibbonClient(name="cloud-payment-sesrvice",configuration = MyselfRule.class)</span><br><span class="line">public class OrderMain80 {</span><br><span class="line"> public static void main(String[] args) {</span><br><span class="line"> SpringApplication.run(OrderMain80.class,args);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghx0jo4qjfj31ii0k6hdt.jpg" alt=""></p></li></ul></li><li><p>测试</p></li></ul></li></ol><h3 id="5-4-Ribbon负载均衡算法"><a href="#5-4-Ribbon负载均衡算法" class="headerlink" title="5.4 Ribbon负载均衡算法"></a>5.4 Ribbon负载均衡算法</h3><ol><li>原理<br>负载均衡算法:rest接口第几次请求数 % 服务器集群=实际调用服务器位置下标,每次服务重启后rest接口计数从1开始<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghx1mdw1bpj315q0hu165.jpg" alt=""><br>总台数:2台</li></ol><p>请求数 调用下标<br>1 1%2=1<br>2 2%2=0<br>3 3%2=1<br>4 4%2=0</p><ol start="2"><li><p>RoundRobinRule源码</p></li><li><p>手写<br>具体详细的请看脑图笔记…</p><h2 id="6-OpenFeign服务接口调用"><a href="#6-OpenFeign服务接口调用" class="headerlink" title="6. OpenFeign服务接口调用"></a>6. OpenFeign服务接口调用</h2><h3 id="6-1-概述"><a href="#6-1-概述" class="headerlink" title="6.1 概述"></a>6.1 概述</h3></li><li><p>OpenFeign是什么<br>Feign是声明性Web服务客户端。它使编写Web服务客户端更加容易。要使用Feign,请创建一个接口并对其进行注释。它具有可插入的注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud添加了对Spring MVC注释的支持,并支持使用HttpMessageConvertersSpring Web中默认使用的注释。Spring Cloud集成了Ribbon和Eureka以及Spring Cloud LoadBalancer,以在使用Feign时提供负载平衡的http客户端。<br><a href="https://github.com/spring-cloud/spring-cloud-openfeign" target="_blank" rel="noopener">https://github.com/spring-cloud/spring-cloud-openfeign</a></p></li><li><p>能干嘛</p><ul><li>使编写Java Http客户端更加容易<br>使用 RestTemplate+Ribbon 时,利用 RestTemplate 对http 请求的封装处理,形成一套模板化的调用方法,但是在实际中,由于对服务的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务的调用。所以Feign在此基础上做了进一步封装,由他来帮助我们定义和实现服务接口的定义。在==Feign的实现下我们只需要创建一个接口并使用注解来配置它(以前是Dao接口上标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可)==。自动封装服务调用客户端的开发量。</li><li>Feign集成了Ribbon<br>利用Ribbon维护了Payment的服务列表信息,并且实现了轮询实现客户端的负载均衡。而与Ribbon不同的是,==feign只需要定义服务绑定接口且以声明式的方法==,优雅而简单的实现服务调用</li></ul></li><li><p>Fegin和OpenFeign两者区别<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghx3ke4l7aj318y0bcdw0.jpg" alt=""></p></li></ol><h3 id="6-2-OpenFeign使用步骤"><a href="#6-2-OpenFeign使用步骤" class="headerlink" title="6.2 OpenFeign使用步骤"></a>6.2 OpenFeign使用步骤</h3><ol><li><p>接口+注解:<code>微服务调用的接口+@FeignClient</code></p></li><li><p>新建<code>cloud-consumer-feign-order80</code><br>Fegin用在消费端</p></li><li><p>POM</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <parent></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </parent></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <artifactId>cloud-consumer-feign-order80</artifactId></span><br><span class="line"></span><br><span class="line"> <dependencies></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-openfeign</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <artifactId>cloud-api-commons</artifactId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-web</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-actuator</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-devtools</artifactId></span><br><span class="line"> <scope>runtime</scope></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.projectlombok</groupId></span><br><span class="line"> <artifactId>lombok</artifactId></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-test</artifactId></span><br><span class="line"> <scope>test</scope></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></li><li><p>YML</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 80</span><br><span class="line">eureka:</span><br><span class="line"> client:</span><br><span class="line"> register-with-eureka: false</span><br><span class="line"> service-url:</span><br><span class="line"> defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/</span><br></pre></td></tr></table></figure></li><li><p>主启动类</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud;</span><br><span class="line"></span><br><span class="line">import org.springframework.boot.SpringApplication;</span><br><span class="line">import org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line">import org.springframework.cloud.client.discovery.EnableDiscoveryClient;</span><br><span class="line">import org.springframework.cloud.openfeign.EnableFeignClients;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 主启动类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-20-11-24</span><br><span class="line"> */</span><br><span class="line">@SpringBootApplication</span><br><span class="line">@EnableDiscoveryClient</span><br><span class="line">//激活fengin并使用</span><br><span class="line">@EnableFeignClients</span><br><span class="line">public class OrderfeignMain80 {</span><br><span class="line"> public static void main(String[] args) {</span><br><span class="line"> SpringApplication.run(OrderfeignMain80.class,args);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>业务类</p><ul><li><p>业务逻辑接口+@FeignClient配置调用provider服务<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghx57vtvwwj317u0pcnpd.jpg" alt=""></p></li><li><p>新建<code>PaymentFeignService</code>接口并新政注解<code>@FeignClient</code></p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.service;</span><br><span class="line"></span><br><span class="line">import com.atguigu.springcloud.entities.CommonResult;</span><br><span class="line">import com.atguigu.springcloud.entities.Payment;</span><br><span class="line">import org.springframework.cloud.openfeign.FeignClient;</span><br><span class="line">import org.springframework.stereotype.Component;</span><br><span class="line">import org.springframework.web.bind.annotation.GetMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.PathVariable;</span><br><span class="line"></span><br><span class="line">@Component</span><br><span class="line">/**</span><br><span class="line"> * name:找哪个微服务</span><br><span class="line"> */</span><br><span class="line"> // 将业务提供者的名写进去</span><br><span class="line">@FeignClient(name="cloud-payment-service")</span><br><span class="line">public interface PaymentFeignService {</span><br><span class="line">// 将业务提供者的controller路径和方法复制粘贴进来</span><br><span class="line"> @GetMapping(value = "/payment/get/{id}")</span><br><span class="line"> public CommonResult getPaymentById(@PathVariable("id") Long id);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>控制层Controller</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.controller;</span><br><span class="line"></span><br><span class="line">import com.atguigu.springcloud.entities.CommonResult;</span><br><span class="line">import com.atguigu.springcloud.entities.Payment;</span><br><span class="line">import com.atguigu.springcloud.service.PaymentFeignService;</span><br><span class="line">import lombok.extern.slf4j.Slf4j;</span><br><span class="line">import org.springframework.web.bind.annotation.GetMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.PathVariable;</span><br><span class="line">import org.springframework.web.bind.annotation.RestController;</span><br><span class="line"></span><br><span class="line">import javax.annotation.Resource;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 控制层</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-20-11-36</span><br><span class="line"> */</span><br><span class="line">@RestController</span><br><span class="line">@Slf4j</span><br><span class="line">public class OrderFeignController {</span><br><span class="line"> @Resource</span><br><span class="line"> private PaymentFeignService paymentFeignService;</span><br><span class="line"></span><br><span class="line"> @GetMapping("/consumer/payment/get/{id}")</span><br><span class="line"> public CommonResult<Payment> getPaymentById(@PathVariable("id")Long id){</span><br><span class="line"> return paymentFeignService.getPaymentById(id);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul></li><li><p>测试</p><ul><li>先启动2个Eureka集群7001/7002</li><li>在启动2个微服务8001/8002</li><li>启动OpenFegin启动</li><li><a href="http://localhost/consumer/payment/get/1" target="_blank" rel="noopener">http://localhost/consumer/payment/get/1</a></li><li>Feign自带负载均衡配置项</li></ul></li><li><p>小总结<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghx59t9ee8j319i0ia4gu.jpg" alt=""></p></li></ol><h3 id="6-3-OpenFeign超时控制"><a href="#6-3-OpenFeign超时控制" class="headerlink" title="6.3 OpenFeign超时控制"></a>6.3 OpenFeign超时控制</h3><ol><li><p>超时设置,故意设置超时演示出错情况</p><ul><li><p>服务提供方8001故意写暂停程序</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">@GetMapping("/payment/feign/timeout")</span><br><span class="line"> public String paymentFeignTimeout(){</span><br><span class="line"> try {</span><br><span class="line"> TimeUnit.SECONDS.sleep(3);</span><br><span class="line"> } catch (InterruptedException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> return serverPort;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure></li><li><p>服务消费方80添加超时方法PaymentFeginService<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghx9rjcybnj31580k47wh.jpg" alt=""></p></li><li><p>服务消费方80添加超时方法OrderFeginController<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghx9ry0vavj30wg084k13.jpg" alt=""></p></li><li><p>测试</p><ul><li><a href="http://localhost/consumer/payment/feign/timeout" target="_blank" rel="noopener">http://localhost/consumer/payment/feign/timeout</a></li><li>错误页面:<strong><em>==这里需要只启动修改过的服务==</em></strong><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghx8tpp26fj31bb0u0tl6.jpg" alt=""></li></ul></li></ul></li><li><p>OpenFeign默认等待一秒钟,超期后报错</p></li><li><p>是什么<br>默认Feign客户端只等待一秒钟,但是服务端处理需要超过1秒钟,导致Feign客户端不想等待了,直接返回报错。为了避免这样的情况,有时候我们需要设置客户端的超时控制。</p></li><li><p>YML文件里需要开启OpenFeign客户端超时控制</p></li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 80</span><br><span class="line">eureka:</span><br><span class="line"> client:</span><br><span class="line"> register-with-eureka: false</span><br><span class="line"> service-url:</span><br><span class="line"> defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/</span><br><span class="line"># 添加一下的配置</span><br><span class="line"># 设置feign客户端超时时间(openfign默认支持ribbon)</span><br><span class="line">ribbon:</span><br><span class="line"> # 指得失建立链接所用的时间,适用于网络状况正常的情况下。两端链接所用的时间</span><br><span class="line"> ReadTimeout: 5000</span><br><span class="line"> # 指的是建立链接后从服务器读取到可用资源所用的时间</span><br><span class="line"> ConnectTimeout: 5000</span><br></pre></td></tr></table></figure><h3 id="6-4-OpenFeign日志打印功能"><a href="#6-4-OpenFeign日志打印功能" class="headerlink" title="6.4 OpenFeign日志打印功能"></a>6.4 OpenFeign日志打印功能</h3><ol><li><p>日志打印功能</p></li><li><p>是什么<br>Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中Http请求的细节。说白了就是==对Feign接口调用情况进行监控和输出==</p></li><li><p>日志级别</p><ul><li>NONE:默认不显示日志</li><li>BASIC:仅记录请求方法,URL,响应状态及执行时间</li><li>HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息</li><li>FULL:除了HEADERS中定义的信息外,还有请求和响应的正文及元数据</li></ul></li><li><p>配置日志bean</p><pre><code><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.config;</span><br><span class="line"></span><br><span class="line">import feign.Logger;</span><br><span class="line">import org.springframework.context.annotation.Bean;</span><br><span class="line">import org.springframework.context.annotation.Configuration;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: feign的配置类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-20-14-52</span><br><span class="line"> */</span><br><span class="line">@Configuration</span><br><span class="line">public class FeignLog {</span><br><span class="line"> @Bean</span><br><span class="line"> Logger.Level feignLoggerlevel(){</span><br><span class="line"> return Logger.Level.FULL;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></code></pre></li><li><p>YML文件里需要开启日期的Feign客户端</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 80</span><br><span class="line">eureka:</span><br><span class="line"> client:</span><br><span class="line"> register-with-eureka: false</span><br><span class="line"> service-url:</span><br><span class="line"> defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/</span><br><span class="line"># 设置feign客户端超时时间(openfign默认支持ribbon)</span><br><span class="line">ribbon:</span><br><span class="line"> # 指得失建立链接所用的时间,适用于网络状况正常的情况下。两端链接所用的时间</span><br><span class="line"> ReadTimeout: 5000</span><br><span class="line"> # 指的是建立链接后从服务器读取到可用资源所用的时间</span><br><span class="line"> ConnectTimeout: 5000</span><br><span class="line">logging:</span><br><span class="line"> level:</span><br><span class="line"> #feign日志以什么级别监控哪个接口</span><br><span class="line"> com.atguigu.springcloud.service.PaymentFeginService: debug</span><br></pre></td></tr></table></figure></li><li><p>后台日志查看</p></li></ol><h2 id="7-Hystrix断路器"><a href="#7-Hystrix断路器" class="headerlink" title="7. Hystrix断路器"></a>7. Hystrix断路器</h2><h3 id="7-1-概述"><a href="#7-1-概述" class="headerlink" title="7.1 概述"></a>7.1 概述</h3><ol><li>分布式系统面临的问题<br>复杂分布式系统中的应用程序有数十个依赖关系,每个依赖关系在某些时候不可避免的失败。<br>多个微服务之间调用时,假设 A 调B和C,B和C又调其他微服务,就是所谓的扇出。当扇出的链路上某个微服务响应时间过长或不可用对A的调用就会占用越来越多的资源,进而引起系统崩溃 ,所谓的雪崩效应。</li><li>是什么<br>Hystrix 是处理分布式系统的延迟和容错的开源库,保证一个依赖出现问题时不会导致整体服务失败,避免级联故障,以提高分布式系统弹性。<br>断路器本身是一种开关装置,当某个服务单元发生故障后,通过断路器的故障监控,向调用方返回一个符合预期的可处理的备选响应,而不是长时间的等待或抛出调用方法无法处理的异常 。</li><li>能干嘛<ul><li>服务降级</li><li>服务熔断</li><li>接近实时的监控</li></ul></li><li>官网资料:<a href="https://github.com/Netflix/Hystrix/wiki/How-To-Use" target="_blank" rel="noopener">https://github.com/Netflix/Hystrix/wiki/How-To-Use</a></li><li>Hystrix官宣,停更进维:<a href="https://github.com/Netflix/Hystrix" target="_blank" rel="noopener">https://github.com/Netflix/Hystrix</a><ul><li>被动修复bugs</li><li>不再接受合并请求</li><li>不再发布新版本</li></ul></li></ol><h3 id="7-2-Hystrix重要概念"><a href="#7-2-Hystrix重要概念" class="headerlink" title="7.2 Hystrix重要概念"></a>7.2 Hystrix重要概念</h3><ol><li>服务降级<br>服务器忙,请稍后重试,不让客户端等待并立即返回一个友好的提示。fallback<br> 哪些情况会导致服务降级? <ul><li>程序运行异常</li><li>超时</li><li>服务熔断触发服务降级</li><li>线程池/信号量打满</li></ul></li><li>服务熔断<ul><li>类比保险丝达到最大服务访问时,直接拒绝访问,拉闸限电,然后调用服务降级的方法返回友好提示。</li><li>服务降级->进而熔断->恢复调用链路</li></ul></li><li>服务限流<ul><li>秒杀高并发等操作,严禁一窝蜂过来拥挤,一秒N个有序进行</li></ul></li></ol><h3 id="7-3-hystrix案例"><a href="#7-3-hystrix案例" class="headerlink" title="7.3 hystrix案例"></a>7.3 hystrix案例</h3><ol><li><p>构建</p><ul><li><p>新建<code>cloud-provider-hystrix-payment8001</code></p></li><li><p>POM</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <parent></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </parent></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <artifactId>cloud-provider-hystrix-payment8001</artifactId></span><br><span class="line"></span><br><span class="line"> <dependencies></span><br><span class="line"> <!--新增hystrix--></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <artifactId>cloud-api-commons</artifactId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-web</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-actuator</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-devtools</artifactId></span><br><span class="line"> <scope>runtime</scope></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.projectlombok</groupId></span><br><span class="line"> <artifactId>lombok</artifactId></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-test</artifactId></span><br><span class="line"> <scope>test</scope></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></li><li><p>YML</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 8001</span><br><span class="line">spring:</span><br><span class="line"> application:</span><br><span class="line"> name: cloud-provider-hystrix-payment</span><br><span class="line"></span><br><span class="line">eureka:</span><br><span class="line"> client:</span><br><span class="line"> service-url:</span><br><span class="line"> defaultZone: http://localhost:7001/eureka</span><br><span class="line"> register-with-eureka: true</span><br><span class="line"> fetch-registry: true</span><br></pre></td></tr></table></figure></li><li><p>主启动</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud;</span><br><span class="line"></span><br><span class="line">import org.springframework.boot.SpringApplication;</span><br><span class="line">import org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line">import org.springframework.cloud.client.discovery.EnableDiscoveryClient;</span><br><span class="line">import org.springframework.cloud.netflix.eureka.EnableEurekaClient;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 主启动类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-20-20-51</span><br><span class="line"> */</span><br><span class="line">@SpringBootApplication</span><br><span class="line">@EnableDiscoveryClient</span><br><span class="line">@EnableEurekaClient</span><br><span class="line">public class PaymentHystrixMain8001 {</span><br><span class="line"> public static void main(String[] args) {</span><br><span class="line"> SpringApplication.run(PaymentHystrixMain8001.class,args);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>业务类</p><ul><li><p>service</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.service;</span><br><span class="line"></span><br><span class="line">import ch.qos.logback.core.util.TimeUtil;</span><br><span class="line">import org.springframework.stereotype.Service;</span><br><span class="line"></span><br><span class="line">import java.util.concurrent.TimeUnit;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 业务类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-20-21-17</span><br><span class="line"> */</span><br><span class="line">@Service</span><br><span class="line">public class PaymentService {</span><br><span class="line"> //正常访问肯定OK的方法</span><br><span class="line"> public String paymentInfo_ok(Integer id){</span><br><span class="line"> return "线程池:"+Thread.currentThread().getName()+" paymentInfo_ok,id"+id+"\t"+"哈哈😄";</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> public String paymentInfo_timeout(Integer id){</span><br><span class="line"> try {</span><br><span class="line"> TimeUnit.SECONDS.sleep(3);</span><br><span class="line"> } catch (InterruptedException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> return "线程池:"+Thread.currentThread().getName()+" paymentInfo_timeout,id"+id+"\t"+"耗时3秒钟";</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>controller</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.controller;</span><br><span class="line"></span><br><span class="line">import com.atguigu.springcloud.service.PaymentService;</span><br><span class="line">import lombok.extern.slf4j.Slf4j;</span><br><span class="line">import org.springframework.beans.factory.annotation.Value;</span><br><span class="line">import org.springframework.web.bind.annotation.GetMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.PathVariable;</span><br><span class="line">import org.springframework.web.bind.annotation.RestController;</span><br><span class="line"></span><br><span class="line">import javax.annotation.Resource;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: kongzhiceng</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-20-21-22</span><br><span class="line"> */</span><br><span class="line">@RestController</span><br><span class="line">@Slf4j</span><br><span class="line">public class PaymentController {</span><br><span class="line"> @Resource</span><br><span class="line"> private PaymentService paymentService;</span><br><span class="line"> @Value("${server.port}")</span><br><span class="line"> private String serverPort;</span><br><span class="line"></span><br><span class="line"> @GetMapping("/payment/hystrix/ok/{id}")</span><br><span class="line"> public String paymentInfo_ok(@PathVariable("id") Integer id){</span><br><span class="line"> String result = paymentService.paymentInfo_ok(id);</span><br><span class="line"> log.info("****result"+result);</span><br><span class="line"> return result;</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"> @GetMapping("/payment/hystrix/timeout/{id}")</span><br><span class="line"> public String paymentInfo_timeout(@PathVariable("id") Integer id){</span><br><span class="line"> String result = paymentService.paymentInfo_timeout(id);</span><br><span class="line"> log.info("****result"+result);</span><br><span class="line"> return result;</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul></li></ul></li></ol><ul><li><p>正常测试</p><ul><li>启动eureka7001</li><li>启动cloud-provider-hystrix-payment8001</li><li>访问:<a href="http://localhost:8001/payment/hystrix/ok/31" target="_blank" rel="noopener">http://localhost:8001/payment/hystrix/ok/31</a></li><li>每次调用耗费5秒钟:<a href="http://localhost:8001/payment/hystrix/timeout/31" target="_blank" rel="noopener">http://localhost:8001/payment/hystrix/timeout/31</a></li><li>上述module均OK:以上述为根基平台,从正确->错误->降级熔断->恢复<ol><li>高并发测试</li></ol><ul><li>上述在非高并发情形下,还能勉强满足 but…..</li><li>Jmeter压测测试</li></ul></li><li>开启Jmeter,来20000个并发压死8001,20000个请求都去访问paymentInfo_TimeOut服务</li><li>再来一个访问:<a href="http://localhost:8001/payment/hystrix/ok/31、http://localhost:8001/payment/hystrix/timeout/31" target="_blank" rel="noopener">http://localhost:8001/payment/hystrix/ok/31、http://localhost:8001/payment/hystrix/timeout/31</a></li><li>看演示结果:两个都在自己转圈圈</li><li>为什么会被卡死:tomcat的默认的工作线程数被打满了,没有多余的线程来分解压力和处理。<ul><li>Jmeter压测结论<br>上面还是服务提供者8001自己测试,假如此时外部的消费者80也来访问,那消费者只能干等,最终导致消费端80不满意,服务端8001直接被拖死</li><li>看热闹不嫌弃事大,80新建加入</li></ul></li></ul><ol><li><p>新建<code>cloud-consumer-feign-hystrix-order80</code></p></li><li><p>POM</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <parent></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </parent></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <artifactId>cloud-consumer-feign-hystrix-order80</artifactId></span><br><span class="line"></span><br><span class="line"> <dependencies></span><br><span class="line"> <!--新增hystrix--></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-openfeign</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <artifactId>cloud-api-commons</artifactId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-web</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-actuator</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-devtools</artifactId></span><br><span class="line"> <scope>runtime</scope></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.projectlombok</groupId></span><br><span class="line"> <artifactId>lombok</artifactId></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-test</artifactId></span><br><span class="line"> <scope>test</scope></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></li><li><p>YML</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 80</span><br><span class="line"></span><br><span class="line">eureka:</span><br><span class="line"> client:</span><br><span class="line"> register-with-eureka: false</span><br><span class="line"> service-url:</span><br><span class="line"> defaultZone: http://localhost:7001/eureka/</span><br></pre></td></tr></table></figure></li><li><p>主启动</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud;</span><br><span class="line"></span><br><span class="line">import org.springframework.boot.SpringApplication;</span><br><span class="line">import org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line">import org.springframework.cloud.netflix.eureka.EnableEurekaClient;</span><br><span class="line">import org.springframework.cloud.openfeign.EnableFeignClients;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 主启动类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-20-22-25</span><br><span class="line"> */</span><br><span class="line">@SpringBootApplication</span><br><span class="line">@EnableEurekaClient</span><br><span class="line">@EnableFeignClients</span><br><span class="line">public class OrderHystrixMain80 {</span><br><span class="line"> public static void main(String[] args) {</span><br><span class="line"> SpringApplication.run(OrderHystrixMain80.class</span><br><span class="line"> ,args);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>业务类</p><ul><li><p>service</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.service;</span><br><span class="line"></span><br><span class="line">import org.springframework.cloud.openfeign.FeignClient;</span><br><span class="line">import org.springframework.stereotype.Component;</span><br><span class="line">import org.springframework.web.bind.annotation.GetMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.PathVariable;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 服务类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-20-22-29</span><br><span class="line"> */</span><br><span class="line">@Component</span><br><span class="line">@FeignClient(name = "CLOUD-PROVIDER-HYSTRIX-PAYMENT")</span><br><span class="line">public interface PaymentHystrixService {</span><br><span class="line"></span><br><span class="line"> @GetMapping("/payment/hystrix/ok/{id}")</span><br><span class="line"> public String paymentInfo_ok(@PathVariable("id") Integer id);</span><br><span class="line"> @GetMapping("/payment/hystrix/timeout/{id}")</span><br><span class="line"> public String paymentInfo_timeout(@PathVariable("id") Integer id);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>controller</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"> package com.atguigu.springcloud.controller;</span><br><span class="line"> </span><br><span class="line"> import com.atguigu.springcloud.service.PaymentHystrixService;</span><br><span class="line"> import lombok.extern.slf4j.Slf4j;</span><br><span class="line"> import org.springframework.web.bind.annotation.GetMapping;</span><br><span class="line"> import org.springframework.web.bind.annotation.PathVariable;</span><br><span class="line"> import org.springframework.web.bind.annotation.RestController;</span><br><span class="line"> </span><br><span class="line"> import javax.annotation.Resource;</span><br><span class="line"> </span><br><span class="line"> /**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: kongzhiceng</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-20-22-42</span><br><span class="line"> */</span><br><span class="line"> @RestController</span><br><span class="line"> @Slf4j</span><br><span class="line"> public class PaymentHystirxController {</span><br><span class="line"> </span><br><span class="line"> @Resource</span><br><span class="line"> private PaymentHystrixService paymentHystrixService;</span><br><span class="line"> @GetMapping("/consumer/payment/hystrix/ok/{id}")</span><br><span class="line"> public String paymentInfo_ok(@PathVariable("id") Integer id){</span><br><span class="line"> return paymentHystrixService.paymentInfo_ok(id);</span><br><span class="line"> }</span><br><span class="line"> @GetMapping("/consumer/payment/hystrix/timeout/{id}")</span><br><span class="line"> public String paymentInfo_timeout(@PathVariable("id") Integer id){</span><br><span class="line"> return paymentHystrixService.paymentInfo_timeout(id);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul></li><li><p>正常测试:<a href="http://localhost/consumer/payment/hystrix/ok/31" target="_blank" rel="noopener">http://localhost/consumer/payment/hystrix/ok/31</a></p></li><li><p>高并发测试</p><ul><li>2W个线程压8001</li><li>消费端80微服务再去访问正常的OK微服务8001地址</li><li><a href="http://localhost/consumer/payment/hystrix/timeout/31" target="_blank" rel="noopener">http://localhost/consumer/payment/hystrix/timeout/31</a></li><li>消费者80:要么转圈圈等待,要么消费端报超时错误<ol><li>故障现象和导致原因<br>8001同一层次的其他接口服务被困死,因为tomcat线程里面的工作线程已经被挤占完毕,0此时调用8001,客户端访问响应缓慢,转圈圈</li><li>上诉结论<br>正因为有上述故障或不佳表现,才有我们的降级/容错/限流等技术诞生</li><li>如何解决,解决的要求</li></ol><ul><li>超时导致服务器变慢(转圈:超时不再等待</li><li>出错(宕机或程序运行出错):出错要有兜底</li><li>解决</li></ul></li></ul></li></ol><ul><li>对方服务(8001)超时了,调用者(80)不能一直卡死等待,必须有服务降级</li><li>对方服务(8001)down机了,调用者(80)不能一直卡死等待,必须有服务降级</li><li>对方服务(8001)OK,调用者(80)自己出故障或有自我要求(自己的等待时间小于服务提供者),自己处理降级</li></ul></li></ul><h4 id="7-3-1-服务降级"><a href="#7-3-1-服务降级" class="headerlink" title="7.3.1 服务降级"></a>7.3.1 服务降级</h4><h5 id="7-3-1-1-降级配置"><a href="#7-3-1-1-降级配置" class="headerlink" title="7.3.1.1. 降级配置"></a>7.3.1.1. 降级配置</h5><p><code>@HystrixCommand</code></p><h5 id="7-3-1-2-8001先从自身找问题"><a href="#7-3-1-2-8001先从自身找问题" class="headerlink" title="7.3.1.2. 8001先从自身找问题"></a>7.3.1.2. 8001先从自身找问题</h5><p>设置自身调用超时时间的峰值,峰值内可以正常运行,超过了需要有兜底的方法处理,作服务降级fallback</p><h5 id="7-3-1-3-8001fallback"><a href="#7-3-1-3-8001fallback" class="headerlink" title="7.3.1.3. 8001fallback"></a>7.3.1.3. 8001fallback</h5><ol><li><p>业务类启用<br><code>@HystrixCommand</code>报异常后如何处理<br>一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法。<br>==代码示例:==</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"> </span><br><span class="line">/**</span><br><span class="line"> * fallbackmetod:系统异常或者超时后的兜底方案</span><br><span class="line"> * commandProperties -> HystrixProperty -> execution.isolation.thread.timeoutInMilliseconds :系统超时的时间</span><br><span class="line"> * @param id</span><br><span class="line"> * @return</span><br><span class="line"> */</span><br><span class="line"> @HystrixCommand(fallbackMethod = "paymentInfo_timeoutHandler",commandProperties = {</span><br><span class="line"> @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value = "3000")</span><br><span class="line"> })</span><br><span class="line"> public String paymentInfo_timeout(Integer id){</span><br><span class="line"> try {</span><br><span class="line"> TimeUnit.SECONDS.sleep(5);</span><br><span class="line"> } catch (InterruptedException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> return "线程池:"+Thread.currentThread().getName()+" paymentInfo_timeout,id"+id+"\t"+"耗时3秒钟";</span><br><span class="line"> }</span><br><span class="line"> public String paymentInfo_timeoutHandler(Integer id){</span><br><span class="line"> return "线程池:"+Thread.currentThread().getName()+" paymentInfo_timeoutHandler,id"+id;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghy8j2pqjej31xr0u01kz.jpg" alt=""></p></li><li><p>主启动类激活:添加新注解<code>@EnableCircuitBreaker</code></p></li></ol><h5 id="7-3-1-4-80fallback"><a href="#7-3-1-4-80fallback" class="headerlink" title="7.3.1.4. 80fallback"></a>7.3.1.4. 80fallback</h5><ol><li><p>80订单微服务,也可以更好的保护自己,自己也依样画葫芦进行客户端降级保护</p></li><li><p>题外话,切记<br>我们自己配置过的热部署方式对java代码的改动明显,但对@HystrixCommand内属性的修改建议重启微服务</p></li><li><p>YML<br>在80的客户端yml文件中添加如下代码配置</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">feign:</span><br><span class="line"> hystrix:</span><br><span class="line"> enabled: true #如果处理自身的容错就开启。开启方式与生产端不一样。</span><br></pre></td></tr></table></figure><p> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghy9coq979j319o0jye81.jpg" alt=""></p></li><li><p>主启动<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghy9d5z0vmj31e20nqqv5.jpg" alt=""></p></li><li><p>业务类</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">@HystrixCommand(fallbackMethod = "paymentTimeoutFallcackMethod",commandProperties ={</span><br><span class="line"> @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")</span><br><span class="line"> })</span><br><span class="line"> @GetMapping("/consumer/payment/hystrix/timeout/{id}")</span><br><span class="line"> public String paymentInfo_timeout(@PathVariable("id") Integer id){</span><br><span class="line"> return paymentHystrixService.paymentInfo_timeout(id);</span><br><span class="line"> }</span><br><span class="line"> public String paymentTimeoutFallcackMethod(@PathVariable("id") Integer id){</span><br><span class="line"> return "消费者客户端80的服务报错了";</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghy9ec2kokj31ok0pg7wi.jpg" alt=""></p></li></ol><h5 id="7-3-1-5-目前问题"><a href="#7-3-1-5-目前问题" class="headerlink" title="7.3.1.5. 目前问题"></a>7.3.1.5. 目前问题</h5><ol><li>每个业务方法对应一个兜底的方法,代码膨胀</li><li>统一和自定义的分开</li></ol><h5 id="7-3-1-6-解决问题"><a href="#7-3-1-6-解决问题" class="headerlink" title="7.3.1.6. 解决问题"></a>7.3.1.6. 解决问题</h5><ol><li><p>每个方法配置一个???膨胀</p><ul><li><p>feign接口系列</p></li><li><p>@DefaultProperties(defaultFallback = “”)<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghy9mfyh6jj318m0k2qfa.jpg" alt=""><br>说明:<br>1:1 每个方法配置一个服务降级的方法,技术上可以,实际上操作是不可实现的<br>1:N 除了个别重要核心业务有专属,其它普通的可以通过<code>@DefaultProperties(defaultFallback = "")</code>统一跳转到统一处理结果页面<br>通用的和独享的各自分开,避免了代码膨胀,合理减少了代码量。</p></li><li><p>controller配置</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.controller;</span><br><span class="line"></span><br><span class="line">import com.atguigu.springcloud.service.PaymentHystrixService;</span><br><span class="line">import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;</span><br><span class="line">import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;</span><br><span class="line">import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;</span><br><span class="line">import lombok.extern.slf4j.Slf4j;</span><br><span class="line">import org.springframework.web.bind.annotation.GetMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.PathVariable;</span><br><span class="line">import org.springframework.web.bind.annotation.RestController;</span><br><span class="line"></span><br><span class="line">import javax.annotation.Resource;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: kongzhiceng</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-20-22-42</span><br><span class="line"> */</span><br><span class="line">@RestController</span><br><span class="line">@Slf4j</span><br><span class="line">@DefaultProperties(defaultFallback = "payment_Global_FallbaxkMethod")</span><br><span class="line">public class PaymentHystirxController {</span><br><span class="line"></span><br><span class="line"> @Resource</span><br><span class="line"> private PaymentHystrixService paymentHystrixService;</span><br><span class="line"></span><br><span class="line"> @GetMapping("/consumer/payment/hystrix/ok/{id}")</span><br><span class="line"> public String paymentInfo_ok(@PathVariable("id") Integer id){</span><br><span class="line"> return paymentHystrixService.paymentInfo_ok(id);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> /*@HystrixCommand(fallbackMethod = "paymentTimeoutFallcackMethod",commandProperties ={</span><br><span class="line"> @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1500")</span><br><span class="line"> })*/</span><br><span class="line"> @HystrixCommand</span><br><span class="line"> @GetMapping("/consumer/payment/hystrix/timeout/{id}")</span><br><span class="line"> public String paymentInfo_timeout(@PathVariable("id") Integer id){</span><br><span class="line"> return paymentHystrixService.paymentInfo_timeout(id);</span><br><span class="line"> }</span><br><span class="line"> public String paymentTimeoutFallcackMethod(@PathVariable("id") Integer id){</span><br><span class="line"> return "消费者客户端80的服务报错了";</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> //下面这个是全局的fallback方法</span><br><span class="line"> public String payment_Global_FallbaxkMethod(){</span><br><span class="line"> return "Global异常处理信息,请稍后再是....";</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghy9xa99clj31fw0u0b2c.jpg" alt=""></p></li></ul></li><li><p>和业务逻辑混在一起???混乱</p><ul><li><p>服务降级,客户端去调用服务端,碰上服务端宕机或关闭</p></li><li><p>本次案例服务降级处理是在客户端80实现完成的,与服务端8001没有关系,只需要为Feign客户端定义的接口添加一个服务降级处理的实现类即可实现解耦</p></li><li><p>未来我们要面对的异常:运行、超时、宕机</p></li><li><p>再看我们的业务类PaymentController</p></li><li><p>修改cloud-consumer-feign-hystrix-order80</p></li><li><p>根据cloud-consumer-feign-hystrix-order80已经有的PaymentHystrixService接口,重新新建一个类(PaymentFallbackService)实现该接口,统一为接口里面的方法进行异常处理</p></li><li><p>PaymentFallbackService类实现PaymentFeignClientService接口 </p></li><li><p>YML </p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">feign:</span><br><span class="line"> hystrix:</span><br><span class="line"> enabled: true #如果处理自身的容错就开启。开启方式与生产端不一样。</span><br></pre></td></tr></table></figure></li><li><p>PaymentFeignClientService接口</p><pre><code><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud.service;</span><br><span class="line"></span><br><span class="line">import org.springframework.cloud.openfeign.FeignClient;</span><br><span class="line">import org.springframework.stereotype.Component;</span><br><span class="line">import org.springframework.web.bind.annotation.GetMapping;</span><br><span class="line">import org.springframework.web.bind.annotation.PathVariable;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: 服务类</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-20-22-29</span><br><span class="line"> */</span><br><span class="line">@Component</span><br><span class="line">@FeignClient(name = "CLOUD-PROVIDER-HYSTRIX-PAYMENT" ,fallback = PaymentFallbackHystrixService.class)</span><br><span class="line">public interface PaymentHystrixService {</span><br><span class="line"></span><br><span class="line"> @GetMapping("/payment/hystrix/ok/{id}")</span><br><span class="line"> public String paymentInfo_ok(@PathVariable("id") Integer id);</span><br><span class="line"> @GetMapping("/payment/hystrix/timeout/{id}")</span><br><span class="line"> public String paymentInfo_timeout(@PathVariable("id") Integer id);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></code></pre><p> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghyds9vj9zj31js0mqqv5.jpg" alt=""></p></li><li><p>测试</p><ul><li>单个eureka先启动7001</li><li>PaymentHystrixMain8001启动</li><li>正常访问测试:<a href="http://localhost/consumer/payment/hystrix/ok/31" target="_blank" rel="noopener">http://localhost/consumer/payment/hystrix/ok/31</a></li><li>故意关闭微服务8001</li><li>客户端自己调用提升:此时服务端provider已经down了,但是我们做了服务降级处理,让客户端在服务端不可用时也会获得提示信息而不会挂起耗死服务器</li></ul></li></ul></li></ol><h4 id="7-3-2-服务熔断"><a href="#7-3-2-服务熔断" class="headerlink" title="7.3.2 服务熔断"></a>7.3.2 服务熔断</h4><ol><li><p>断路器<br>一句话就是家里的保险丝</p></li><li><p>熔断是什么<br><a href="https://martinfowler.com/bliki/CircuitBreaker.html" target="_blank" rel="noopener">https://martinfowler.com/bliki/CircuitBreaker.html</a><br>类比保险丝,达到最大访问后直接拒绝访问,拉闸限电,然后调用服务降级。当检测==到该节点微服务调用正常后,恢复调用链路。==<br>当失败的调用达到一定阈值,缺省是5s内20次调用失败,就会启动熔断机制。熔断机制的注解是,@HystrixCommand</p></li><li><p>实操</p><ul><li><p>修改cloud-provider-hystrix-payment8001</p></li><li><p>PaymentService(为什么配置这些参数)</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 服务熔断</span><br><span class="line"> */</span><br><span class="line"> @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {</span><br><span class="line"> @HystrixProperty(name="circuitBreaker.enabled",value = "true"),//是否开启断路器</span><br><span class="line"> @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value = "10"),//请求次数</span><br><span class="line"> @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value = "10000"),//时间范围</span><br><span class="line"> @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value = "60"),//失败率达到多少次后跳闸</span><br><span class="line"> })</span><br><span class="line"> //// 加起来就是在10s内的10次请求中如果失败超过6次进入服务熔断</span><br><span class="line"> public String paymentCircuitBreaker(@PathVariable("id") Integer id){</span><br><span class="line"> if(id < 0){</span><br><span class="line"> throw new RuntimeException("*****id 不能为负数");</span><br><span class="line"> }</span><br><span class="line"> String serialNumber = IdUtil.simpleUUID();</span><br><span class="line"> return Thread.currentThread().getName()+" \t 调用成功,流水号"+serialNumber;</span><br><span class="line"> }</span><br><span class="line"> public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){</span><br><span class="line"> return "id不能为附属,请稍后在是";</span><br><span class="line"> }</span><br></pre></td></tr></table></figure></li></ul></li></ol><pre><code> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">@GetMapping("/payment/circuit/{id}")</span><br><span class="line"> public String paumentCircuitBreaker(@PathVariable("id") Integer id){</span><br><span class="line"> String result = paymentService.paymentCircuitBreaker(id);</span><br><span class="line"> log.info("*****info"+result);</span><br><span class="line"> return result;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>* 测试 * 自测cloud-provider-hystrix-payment8001 * 正确:http://localhost:8001/payment/circuit/31 * 错误:http://localhost:8001/payment/circuit/-31 * 一次正确一次错误trytry * 重点测试:多次错误,然后慢慢正确,发现刚开始不满足条件,就算是正确的访问地址也不能进行访问,需要慢慢的恢复链路 * 结果:一直输入id为负数,达到失败率后即使输入id为正数也进入错误页面。</code></pre><ol start="4"><li><p>原理(小结)</p><ul><li>断路器在什么情况下开始起作用<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghyfe2vjddj318s0k6tup.jpg" alt=""><br>设计三个参数:时间窗,请求总阈值,错误百分比阈值</li></ul><ol><li>快照时间窗:默认为最近的10s</li><li>请求总数阈值:必须满足请求总阈值才有资格熔断。默认为20。意味着在10s内,如果命令调用次数不足20次,即使所有请求都超时或其他原因失败断路器都不会打开</li><li>错误百分比阈值:在快照时间窗内请求总数超过阈值,且错误次数占总请求次数的比值大于阈值,断路器将会打开</li></ol><ul><li>断路器开启或者关闭的条件<ul><li>当满足一定阀值的时候(默认10秒内超过20个请求次数)</li><li>当失败率达到一定的时候(默认10秒内超过50%请求失败)</li><li>到达以上阀值,断路器将会开启</li><li>当开启的时候,所有请求都不会进行转发</li><li>一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4和5</li></ul></li><li>断路器打开之后<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghyfh27eksj31980cg145.jpg" alt=""></li><li>all配置:详细的看官网</li></ul></li></ol><h4 id="7-3-3-服务限流"><a href="#7-3-3-服务限流" class="headerlink" title="7.3.3 服务限流"></a>7.3.3 服务限流</h4><p>后面高级篇讲解alibaba的Sentinel说明</p><h3 id="7-4-hystrix工作流程"><a href="#7-4-hystrix工作流程" class="headerlink" title="7.4 hystrix工作流程"></a>7.4 hystrix工作流程</h3><p><a href="https://github.com/Netflix/Hystrix/wiki/How-it-Works" target="_blank" rel="noopener">https://github.com/Netflix/Hystrix/wiki/How-it-Works</a></p><h3 id="7-5-服务监控hystrixDashboard"><a href="#7-5-服务监控hystrixDashboard" class="headerlink" title="7.5 服务监控hystrixDashboard"></a>7.5 服务监控hystrixDashboard</h3><ul><li><p>概述</p></li><li><p>仪表盘9001</p><ul><li><p>新建cloud-consumer-hystrix-dashboard9001<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghygoe9t00j319m08a111.jpg" alt=""></p></li><li><p>POM</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <parent></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </parent></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <artifactId>cloud-consumer-hystrix-dashboard9001</artifactId></span><br><span class="line"></span><br><span class="line"> <dependencies></span><br><span class="line"> <!--新增hystrix dashboard--></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-actuator</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-devtools</artifactId></span><br><span class="line"> <scope>runtime</scope></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.projectlombok</groupId></span><br><span class="line"> <artifactId>lombok</artifactId></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-test</artifactId></span><br><span class="line"> <scope>test</scope></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></li><li><p>YML<br><code>server.port:9001</code></p></li><li><p>HystrixDashboardMain9001+新注解@EnableHystrixDashboard</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.springcloud;</span><br><span class="line"></span><br><span class="line">import org.springframework.boot.SpringApplication;</span><br><span class="line">import org.springframework.boot.autoconfigure.SpringBootApplication;</span><br><span class="line">import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * @program: cloud2020</span><br><span class="line"> * @description: qidonglei</span><br><span class="line"> * @author: Mr.Wang</span><br><span class="line"> * @create: 2020-08-21-15-37</span><br><span class="line"> */</span><br><span class="line">@SpringBootApplication</span><br><span class="line">@EnableHystrixDashboard</span><br><span class="line">public class HystrixDashboardMain9001 {</span><br><span class="line"> public static void main(String[] args) {</span><br><span class="line"> SpringApplication.run(HystrixDashboardMain9001.class,args);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>所有Provider微服务提供类(8001/8002/8003)都需要监控依赖配</p></li><li><p>启动cloud-consumer-hystrix-dashboard9001该微服务后续将监控微服务8001<br> <a href="http://localhost:9001/hystrix" target="_blank" rel="noopener">http://localhost:9001/hystrix</a></p></li></ul></li><li><p>断路器演示</p><ul><li><p>修改cloud-provider-hystrix-payment8001<br>注意:新版本Hystrix需要在主启动类MainAppHystrix8001中指定监控路径<br>Unable to connect to Command Metric Stream<br>404</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">@Bean</span><br><span class="line"> public ServletRegistrationBean getServlet(){</span><br><span class="line"> HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();</span><br><span class="line"> ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);</span><br><span class="line"> registrationBean.setLoadOnStartup(1);</span><br><span class="line"> registrationBean.addUrlMappings("/hystrix.stream");</span><br><span class="line"> registrationBean.setName("HystrixMetricsStreamServlet");</span><br><span class="line"> return registrationBean;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure></li><li><p>监控测试</p><ol><li>启动1个eureka或者3个eureka集群均可</li><li>观察监控窗口<ul><li>9001监控8001:填写监控地址:<a href="http://localhost:8001/hystrix.stream" target="_blank" rel="noopener">http://localhost:8001/hystrix.stream</a><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghyhmfgdejj31pw0u0nau.jpg" alt=""></li><li>测试地址<ul><li><a href="http://localhost:8001/payment/circuit/31,http://localhost:8001/payment/circuit/-31" target="_blank" rel="noopener">http://localhost:8001/payment/circuit/31,http://localhost:8001/payment/circuit/-31</a></li><li>结果:测试通过</li><li>先访问正确地址,再访问错误地址,再正确地址,会发现图示断路器都是慢慢放开的:先是成功后是失败</li></ul></li><li>如何看<ul><li>7色<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghyhwhmruej31de0pqal6.jpg" alt=""></li><li>1圈<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghyhx2vfjnj319q08c7au.jpg" alt=""></li><li>1线:访问趋势</li><li>整图说明<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghyhxzb7d0j31900ji16m.jpg" alt=""></li><li>正图说明2<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghyhygi7zvj31aa0imk9g.jpg" alt=""></li></ul></li><li>搞懂一个才能看懂复杂的</li></ul></li></ol></li></ul></li></ul><h2 id="8-zuul路由网关(没讲)"><a href="#8-zuul路由网关(没讲)" class="headerlink" title="8. zuul路由网关(没讲)"></a>8. zuul路由网关(没讲)</h2><h2 id="9-Gateway新一代网关"><a href="#9-Gateway新一代网关" class="headerlink" title="9. Gateway新一代网关"></a>9. Gateway新一代网关</h2><h3 id="9-1-概述简介"><a href="#9-1-概述简介" class="headerlink" title="9.1 概述简介"></a>9.1 概述简介</h3><ol><li>官网<ul><li>上一代zuul 1.x:<a href="https://github.com/Netflix/zuul/wiki" target="_blank" rel="noopener">https://github.com/Netflix/zuul/wiki</a></li><li>当前gateway:<a href="https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/" target="_blank" rel="noopener">https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/</a></li></ul></li><li>是什么<br>Spring Cloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架</li><li>能干嘛<ul><li>反向代理</li><li>鉴权</li><li>流量控制</li><li>熔断</li><li>日志监控</li></ul></li><li>微服务架构中网关在哪里<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gi1nmie3cwj31560jigrc.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gi1nn2t1rhj30qm0ibqcq.jpg" alt=""></li><li>有了zuul怎么又出来gateway<br>spring cloud gateway具有如下的特性<ul><li>基于Spring Framework5 ,Project Reactor和Spring boot 2.0进行构建的</li><li>动态路由:能够匹配任何请求属性</li><li>可以对路由指定Preidcate(断言)和Filter(过滤器)</li><li>集成Hystrix的断路器功能</li><li>集成Spring Cloud 服务发现功能</li><li>易于编写的Predicate(断言)和Filter(过滤器)</li><li>请求限流功能</li><li>支持路径重写</li></ul></li></ol><h3 id="9-2-三大核心概念"><a href="#9-2-三大核心概念" class="headerlink" title="9.2 三大核心概念"></a>9.2 三大核心概念</h3><ol><li>Route(路由)<br>路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由</li><li>Predicate(断言)<br>参考的是java8的java.util.function.Predicate开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由</li><li>Filter(过滤)<br>指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。</li><li>总体<br>web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后进行一些精细化控制。predicate就是我们的匹配条件;而filter,就可以理解为一个无所不能的拦截器,有了这两个元素,在加上目标uri就可以实现一个具体的路由了<h3 id="9-3-Gateway工作流程"><a href="#9-3-Gateway工作流程" class="headerlink" title="9.3 Gateway工作流程"></a>9.3 Gateway工作流程</h3>客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序通过特定于请求的过滤器链来运行请求。筛选器由虚线分隔的原因是,筛选器可以在发送代理请求之前和之后运行逻辑。所有“前置”过滤器逻辑均被执行。然后发出代理请求。发出代理请求后,将运行“后”过滤器逻辑。<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gi1ob6owtrj30cb0gjdfw.jpg" alt=""></li></ol><h3 id="9-4-入门配置"><a href="#9-4-入门配置" class="headerlink" title="9.4 入门配置"></a>9.4 入门配置</h3><ol><li><p>新建module:<code>cloud-gateway-gateway9527</code></p></li><li><p>POM文件</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <parent></span><br><span class="line"> <artifactId>cloud2020</artifactId></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </parent></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"></span><br><span class="line"> <artifactId>cloud-gateway-gateway9527</artifactId></span><br><span class="line"></span><br><span class="line"> <dependencies></span><br><span class="line"> <!--新增gateway--></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-gateway</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.atguigu.springcloud</groupId></span><br><span class="line"> <artifactId>cloud-api-commons</artifactId></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.cloud</groupId></span><br><span class="line"> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-devtools</artifactId></span><br><span class="line"> <scope>runtime</scope></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.projectlombok</groupId></span><br><span class="line"> <artifactId>lombok</artifactId></span><br><span class="line"> <optional>true</optional></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.boot</groupId></span><br><span class="line"> <artifactId>spring-boot-starter-test</artifactId></span><br><span class="line"> <scope>test</scope></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"></span><br><span class="line"></project></span><br></pre></td></tr></table></figure><p> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gib5uwic7wj31cs0u07wj.jpg" alt=""></p></li><li><p>YML配置</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 9527</span><br><span class="line"></span><br><span class="line">spring:</span><br><span class="line"> application:</span><br><span class="line"> name: cloud-gateway</span><br><span class="line"> eureka:</span><br><span class="line"> instance:</span><br><span class="line"> hostname: cloud-gateway-service</span><br><span class="line"> client:</span><br><span class="line"> service-url:</span><br><span class="line"> register-with-eureka: true</span><br><span class="line"> fetch-registry: true</span><br><span class="line"> defaultZone: http://localhost:7001/eureka</span><br></pre></td></tr></table></figure></li><li><p>业务类:无</p></li><li><p>主启动类:同前几个步骤中的主启动类</p></li><li><p>9527网关如何做路由映射</p><ul><li>cloud-provider-payment8001看看controller的访问地址:get/lib</li><li>我们目前不想暴露8001端口,希望在8001外面套一层9527</li></ul></li><li><p>YML新增网关配置</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">server:</span><br><span class="line"> port: 9527</span><br><span class="line"></span><br><span class="line">spring:</span><br><span class="line"> application:</span><br><span class="line"> name: cloud-gateway</span><br><span class="line"> cloud:</span><br><span class="line"> gateway:</span><br><span class="line"> routes:</span><br><span class="line"> - id: payment_routh # 路由的ID没有固定规则,但是要求统一,建议配合服务名</span><br><span class="line"> uri: http://localhost:8001 #匹配后提供服务的路由地址</span><br><span class="line"> predicates:</span><br><span class="line"> - Path=/payment/get/** #断言,路由匹配进行路由</span><br><span class="line"> - id: payment_routh2</span><br><span class="line"> uri: http://localhost:8001</span><br><span class="line"> predicates:</span><br><span class="line"> - Path=/payment/lb/**</span><br><span class="line"></span><br><span class="line">eureka:</span><br><span class="line"> instance:</span><br><span class="line"> hostname: cloud-gateway-service</span><br><span class="line"> client:</span><br><span class="line"> service-url:</span><br><span class="line"> register-with-eureka: true</span><br><span class="line"> fetch-registry: true</span><br><span class="line"> defaultZone: http://localhost:7001/eureka</span><br></pre></td></tr></table></figure><p> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gib5z5mab2j315z0u07wj.jpg" alt=""></p></li><li><p>测试</p><ul><li>启动7001</li><li>启动8001:<code>cloud-provider-payment8001</code></li><li>启动9527网关</li><li>访问说明<ul><li>添加网关前:<a href="http://localhost:8001/payment/get/31" target="_blank" rel="noopener">http://localhost:8001/payment/get/31</a></li><li>添加网关后:<a href="http://localhost:9527/payment/get/31" target="_blank" rel="noopener">http://localhost:9527/payment/get/31</a></li></ul></li></ul></li><li><p>YML配置说明-gateway网关路由两种配置方式</p><ul><li>在yml文件中的配置<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gib6j3wn7cj31ey0osdzr.jpg" alt=""></li><li>代码中注入<code>RouteLocator</code>的Bean<ul><li>官网案例<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gib6pq9zqfj30n60ey43r.jpg" alt=""></li><li><a href="http://news.baidu.com/guoji" target="_blank" rel="noopener">百度国内新闻网址,需要外网</a></li><li>自己写一个<ul><li>百度新闻</li><li>业务需求:通过9527网关访问到外网的百度新闻地址</li><li>编码<br>1)cloud-gateway-gateway9527<br>2) 业务实现</li></ul></li></ul></li></ul></li></ol><h3 id="9-5-通过微服务名实现动态路由"><a href="#9-5-通过微服务名实现动态路由" class="headerlink" title="9.5 通过微服务名实现动态路由"></a>9.5 通过微服务名实现动态路由</h3><h3 id="9-6-Predicate的使用"><a href="#9-6-Predicate的使用" class="headerlink" title="9.6 Predicate的使用"></a>9.6 Predicate的使用</h3><h3 id="9-7-Filter的使用"><a href="#9-7-Filter的使用" class="headerlink" title="9.7 Filter的使用"></a>9.7 Filter的使用</h3><h2 id="10-SpringCloud-config分布式配置中心"><a href="#10-SpringCloud-config分布式配置中心" class="headerlink" title="10. SpringCloud config分布式配置中心"></a>10. SpringCloud config分布式配置中心</h2><h3 id="10-1-概述"><a href="#10-1-概述" class="headerlink" title="10.1 概述"></a>10.1 概述</h3><h3 id="10-2-Config服务端配置与测试"><a href="#10-2-Config服务端配置与测试" class="headerlink" title="10.2 Config服务端配置与测试"></a>10.2 Config服务端配置与测试</h3><h3 id="10-3-Config客户端配置与测试"><a href="#10-3-Config客户端配置与测试" class="headerlink" title="10.3 Config客户端配置与测试"></a>10.3 Config客户端配置与测试</h3><h3 id="10-4-Config客户端之动态刷新"><a href="#10-4-Config客户端之动态刷新" class="headerlink" title="10.4 Config客户端之动态刷新"></a>10.4 Config客户端之动态刷新</h3><h2 id="11-SpringCloud-Bus-消息总线"><a href="#11-SpringCloud-Bus-消息总线" class="headerlink" title="11. SpringCloud Bus 消息总线"></a>11. SpringCloud Bus 消息总线</h2><h3 id="11-1-概述"><a href="#11-1-概述" class="headerlink" title="11.1 概述"></a>11.1 概述</h3><h3 id="11-2-RabbitMQ环境配置"><a href="#11-2-RabbitMQ环境配置" class="headerlink" title="11.2 RabbitMQ环境配置"></a>11.2 RabbitMQ环境配置</h3><h3 id="11-3-SpringCloud-Bus动态刷新全局广播"><a href="#11-3-SpringCloud-Bus动态刷新全局广播" class="headerlink" title="11.3 SpringCloud Bus动态刷新全局广播"></a>11.3 SpringCloud Bus动态刷新全局广播</h3><h3 id="11-4-SpringCloud-Bus动态刷新定点通知"><a href="#11-4-SpringCloud-Bus动态刷新定点通知" class="headerlink" title="11.4 SpringCloud Bus动态刷新定点通知"></a>11.4 SpringCloud Bus动态刷新定点通知</h3><h2 id="12-SpringCloud-Stream消息驱动"><a href="#12-SpringCloud-Stream消息驱动" class="headerlink" title="12. SpringCloud Stream消息驱动"></a>12. SpringCloud Stream消息驱动</h2><h3 id="12-1-消息驱动概述"><a href="#12-1-消息驱动概述" class="headerlink" title="12.1 消息驱动概述"></a>12.1 消息驱动概述</h3><h3 id="12-2-案例说明"><a href="#12-2-案例说明" class="headerlink" title="12.2 案例说明"></a>12.2 案例说明</h3><h3 id="12-3-消息驱动之生产者"><a href="#12-3-消息驱动之生产者" class="headerlink" title="12.3 消息驱动之生产者"></a>12.3 消息驱动之生产者</h3><h3 id="12-4-消息驱动之消费者"><a href="#12-4-消息驱动之消费者" class="headerlink" title="12.4 消息驱动之消费者"></a>12.4 消息驱动之消费者</h3><h3 id="12-5-分组消费与持久化"><a href="#12-5-分组消费与持久化" class="headerlink" title="12.5 分组消费与持久化"></a>12.5 分组消费与持久化</h3><h2 id="13-SpringCloud-Sleuth分布式请求链路追踪"><a href="#13-SpringCloud-Sleuth分布式请求链路追踪" class="headerlink" title="13. SpringCloud Sleuth分布式请求链路追踪"></a>13. SpringCloud Sleuth分布式请求链路追踪</h2><h3 id="13-1-概述"><a href="#13-1-概述" class="headerlink" title="13.1 概述"></a>13.1 概述</h3><h3 id="13-2-搭建链路监控步骤"><a href="#13-2-搭建链路监控步骤" class="headerlink" title="13.2 搭建链路监控步骤"></a>13.2 搭建链路监控步骤</h3><h2 id="14-SpringCloud-Alibaba入门简介"><a href="#14-SpringCloud-Alibaba入门简介" class="headerlink" title="14. SpringCloud Alibaba入门简介"></a>14. SpringCloud Alibaba入门简介</h2><h3 id="14-1-why会出现SpringCloud-alibaba"><a href="#14-1-why会出现SpringCloud-alibaba" class="headerlink" title="14.1 why会出现SpringCloud alibaba"></a>14.1 why会出现SpringCloud alibaba</h3><h3 id="14-2-SpringCloud-alibaba带来了什么?"><a href="#14-2-SpringCloud-alibaba带来了什么?" class="headerlink" title="14.2 SpringCloud alibaba带来了什么?"></a>14.2 SpringCloud alibaba带来了什么?</h3><h3 id="14-3-SpringCloud-alibaba学习资料获取"><a href="#14-3-SpringCloud-alibaba学习资料获取" class="headerlink" title="14.3 SpringCloud alibaba学习资料获取"></a>14.3 SpringCloud alibaba学习资料获取</h3><h2 id="15-SpringCloud-Alibaba-Nacos服务注册和配置中心"><a href="#15-SpringCloud-Alibaba-Nacos服务注册和配置中心" class="headerlink" title="15. SpringCloud Alibaba Nacos服务注册和配置中心"></a>15. SpringCloud Alibaba Nacos服务注册和配置中心</h2><h3 id="15-1-Nacos简介"><a href="#15-1-Nacos简介" class="headerlink" title="15.1 Nacos简介"></a>15.1 Nacos简介</h3><h3 id="15-2-安装并运行Nacos"><a href="#15-2-安装并运行Nacos" class="headerlink" title="15.2 安装并运行Nacos"></a>15.2 安装并运行Nacos</h3><h3 id="15-3-Nacos作为服务注册中心演示"><a href="#15-3-Nacos作为服务注册中心演示" class="headerlink" title="15.3 Nacos作为服务注册中心演示"></a>15.3 Nacos作为服务注册中心演示</h3><h3 id="15-4-Nacos作为服务配置中心演示"><a href="#15-4-Nacos作为服务配置中心演示" class="headerlink" title="15.4 Nacos作为服务配置中心演示"></a>15.4 Nacos作为服务配置中心演示</h3><h3 id="15-5-Nacos集群和持久化配置(重要)"><a href="#15-5-Nacos集群和持久化配置(重要)" class="headerlink" title="15.5 Nacos集群和持久化配置(重要)"></a>15.5 Nacos集群和持久化配置(重要)</h3><h2 id="16-SpringCloud-Alibaba-Sentinel实现熔断与限流"><a href="#16-SpringCloud-Alibaba-Sentinel实现熔断与限流" class="headerlink" title="16. SpringCloud Alibaba Sentinel实现熔断与限流"></a>16. SpringCloud Alibaba Sentinel实现熔断与限流</h2><h3 id="16-1-Sentinel"><a href="#16-1-Sentinel" class="headerlink" title="16.1 Sentinel"></a>16.1 Sentinel</h3><h3 id="16-2-安装Sentinel控制台"><a href="#16-2-安装Sentinel控制台" class="headerlink" title="16.2 安装Sentinel控制台"></a>16.2 安装Sentinel控制台</h3><h3 id="16-3-初始化演示工程"><a href="#16-3-初始化演示工程" class="headerlink" title="16.3 初始化演示工程"></a>16.3 初始化演示工程</h3><h3 id="16-4-流控规则"><a href="#16-4-流控规则" class="headerlink" title="16.4 流控规则"></a>16.4 流控规则</h3><h3 id="16-5-降级规则"><a href="#16-5-降级规则" class="headerlink" title="16.5 降级规则"></a>16.5 降级规则</h3><h3 id="16-6-热点key限流"><a href="#16-6-热点key限流" class="headerlink" title="16.6 热点key限流"></a>16.6 热点key限流</h3><h3 id="16-7-系统规则"><a href="#16-7-系统规则" class="headerlink" title="16.7 系统规则"></a>16.7 系统规则</h3><h3 id="16-8-SentinelResource"><a href="#16-8-SentinelResource" class="headerlink" title="16.8 @SentinelResource"></a>16.8 @SentinelResource</h3><h3 id="16-9-服务熔断功能"><a href="#16-9-服务熔断功能" class="headerlink" title="16.9 服务熔断功能"></a>16.9 服务熔断功能</h3><h3 id="16-10-规则持久化"><a href="#16-10-规则持久化" class="headerlink" title="16.10 规则持久化"></a>16.10 规则持久化</h3><h2 id="17-SpringCloud-Alibaba-Seata处理分布式事务"><a href="#17-SpringCloud-Alibaba-Seata处理分布式事务" class="headerlink" title="17. SpringCloud Alibaba Seata处理分布式事务"></a>17. SpringCloud Alibaba Seata处理分布式事务</h2><h3 id="17-1-分布式事务问题"><a href="#17-1-分布式事务问题" class="headerlink" title="17.1 分布式事务问题"></a>17.1 分布式事务问题</h3><h3 id="17-2-Seata简介"><a href="#17-2-Seata简介" class="headerlink" title="17.2 Seata简介"></a>17.2 Seata简介</h3><h3 id="17-3-Seata-Server安装"><a href="#17-3-Seata-Server安装" class="headerlink" title="17.3 Seata-Server安装"></a>17.3 Seata-Server安装</h3><h3 id="17-4-订单-库存-账户业务数据库准备"><a href="#17-4-订单-库存-账户业务数据库准备" class="headerlink" title="17.4 订单/库存/账户业务数据库准备"></a>17.4 订单/库存/账户业务数据库准备</h3><h3 id="17-5-订单-库存-账户业务微服务准备"><a href="#17-5-订单-库存-账户业务微服务准备" class="headerlink" title="17.5 订单/库存/账户业务微服务准备"></a>17.5 订单/库存/账户业务微服务准备</h3><h3 id="17-6-Test"><a href="#17-6-Test" class="headerlink" title="17.6 Test"></a>17.6 Test</h3><h3 id="17-7-Seata之原理简介"><a href="#17-7-Seata之原理简介" class="headerlink" title="17.7 Seata之原理简介"></a>17.7 Seata之原理简介</h3>]]></content>
<summary type="html">
<h1 id="SpringCloud微服务"><a href="#SpringCloud微服务" class="headerlink" title="SpringCloud微服务"></a>SpringCloud微服务</h1><h2 id="1-微服务架构编码构建"><a h
</summary>
</entry>
<entry>
<title>Centos7下静默安装Oracle 11g</title>
<link href="http://lwblog.xyz/posts/undefined.html"/>
<id>http://lwblog.xyz/posts/undefined.html</id>
<published>2020-08-23T09:38:23.000Z</published>
<updated>2020-08-23T09:39:36.586Z</updated>
<content type="html"><![CDATA[<p>[TOC]</p><h1 id="Centos7下静默安装Oracle-11g-无图形化界面"><a href="#Centos7下静默安装Oracle-11g-无图形化界面" class="headerlink" title="Centos7下静默安装Oracle 11g(无图形化界面)"></a>Centos7下静默安装Oracle 11g(无图形化界面)</h1><h2 id="说明"><a href="#说明" class="headerlink" title="说明:"></a>说明:</h2><ul><li>因为使用的是静默安装,所以我们不需要安装Linux的图形界面,只需要对Linux进行最小化安装即可</li></ul><h2 id="前提准备"><a href="#前提准备" class="headerlink" title="前提准备"></a>前提准备</h2><h3 id="1-Centos7-的系统环境"><a href="#1-Centos7-的系统环境" class="headerlink" title="1. Centos7 的系统环境"></a>1. Centos7 的系统环境</h3><ul><li>系统版本:CentOS Linux release 7.6.1810 (Core) </li><li>腾讯云系统</li><li>内核版本:</li><li>系统配置</li><li>交换空间</li></ul><p>因为腾讯云的原因,默认是不提供swap分区的,这里需要自己手动添加一下。在别的系统上可以视情况而定。如果没有swap的分区的,在安装数据库的时候会出现报错。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">dd if=/dev/zero of=/swap bs=1024 count=2048000</span><br><span class="line">mkswap /swap</span><br><span class="line">chmod 600 /swap</span><br><span class="line">swapon /swap</span><br><span class="line">echo "/swap swap swap default 0 0">>/etc/fstab #设置成自动挂载</span><br></pre></td></tr></table></figure><h3 id="2-配置hostname"><a href="#2-配置hostname" class="headerlink" title="2.配置hostname"></a>2.配置hostname</h3><p>此步骤不是必须滴</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">hostnamectl set-hostname oracledb</span><br><span class="line">echo "127.0.0.1 oracledb" >>/etc/hosts</span><br></pre></td></tr></table></figure><h3 id="3-关闭selinux"><a href="#3-关闭selinux" class="headerlink" title="3.关闭selinux"></a>3.关闭selinux</h3><p>此步骤可以视情况而定,本次案例安装的时候执行了此命令</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config </span><br><span class="line">setenforce 0</span><br></pre></td></tr></table></figure><h2 id="2-下载Oracle"><a href="#2-下载Oracle" class="headerlink" title="2. 下载Oracle"></a>2. 下载Oracle</h2><p><a href="https://www.oracle.com/database/technologies/oracle-database-software-downloads.html" target="_blank" rel="noopener">官网下载地址</a><br>根据自己的服务器,下载相应的软件,我的系统是centos7 64位的,所以下载是Linux x86-64的,下载完成后的两个文件如下:</p><ul><li>linux.x64_11gR2_database_1of2.zip</li><li>linux.x64_11gR2_database_2of2.zip<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gi0rgdg0jhj31ek0u0wnn.jpg" alt=""></li><li><strong>说明:*</strong><br>Oracle系统下载的时候请下载Linux x86-64位的系统,请不要下载zlinux,zlinux是IBM的操作系统的一bai个版本。zLinux就是在baiIBM大机上装Linux,目前主要有RedHat与SUSE for z</li></ul><h2 id="3-检查软件依赖环境"><a href="#3-检查软件依赖环境" class="headerlink" title="3.检查软件依赖环境"></a>3.检查软件依赖环境</h2><p><span style="color:red">注意:从Oracle 11g 11.2.0.2版本开始,在Linux x86_64上安装时,只需要安装64位的软件包,但是,对于11.2.0.2之前的任何Oracle database 11g,下表中列出的32位和64位的安装包都必须安装</span></p><p>需要安装的依赖包(版本号只能大于规定的版本,不能小于)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">binutils-2.23.52.0.1-12.el7.x86_64 </span><br><span class="line">compat-libcap1-1.10-3.el7.x86_64 </span><br><span class="line">compat-libstdc++-33-3.2.3-71.el7.i686</span><br><span class="line">compat-libstdc++-33-3.2.3-71.el7.x86_64</span><br><span class="line">gcc-4.8.2-3.el7.x86_64 </span><br><span class="line">gcc-c++-4.8.2-3.el7.x86_64 </span><br><span class="line">glibc-2.17-36.el7.i686 </span><br><span class="line">glibc-2.17-36.el7.x86_64 </span><br><span class="line">glibc-devel-2.17-36.el7.i686 </span><br><span class="line">glibc-devel-2.17-36.el7.x86_64 </span><br><span class="line">ksh</span><br><span class="line">libaio-0.3.109-9.el7.i686 </span><br><span class="line">libaio-0.3.109-9.el7.x86_64 </span><br><span class="line">libaio-devel-0.3.109-9.el7.i686 </span><br><span class="line">libaio-devel-0.3.109-9.el7.x86_64 </span><br><span class="line">libgcc-4.8.2-3.el7.i686 </span><br><span class="line">libgcc-4.8.2-3.el7.x86_64 </span><br><span class="line">libstdc++-4.8.2-3.el7.i686 </span><br><span class="line">libstdc++-4.8.2-3.el7.x86_64 </span><br><span class="line">libstdc++-devel-4.8.2-3.el7.i686 </span><br><span class="line">libstdc++-devel-4.8.2-3.el7.x86_64 </span><br><span class="line">libXi-1.7.2-1.el7.i686 </span><br><span class="line">libXi-1.7.2-1.el7.x86_64 </span><br><span class="line">libXtst-1.2.2-1.el7.i686 </span><br><span class="line">libXtst-1.2.2-1.el7.x86_64 </span><br><span class="line">make-3.82-19.el7.x86_64 </span><br><span class="line">sysstat-10.1.5-1.el7.x86_64</span><br><span class="line">unixODBC-2.3.1-6.el7.i686</span><br><span class="line">unixODBC-2.3.1-6.el7.x86_64</span><br><span class="line">unixODBC-devel-2.3.1-6.el7.i686</span><br><span class="line">unixODBC-devel-2.3.1-6.el7.x86_64</span><br></pre></td></tr></table></figure><p>安装命令</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum -y install binutils compat-libcap1 compat-libstdc++-33 gcc gcc-c++ glibc glibc-devel ksh libaio libaio-devel libgcc libstdc++ libstdc++-devel libXi libXtst make sysstat unixODBC unixODBC-devel</span><br></pre></td></tr></table></figure><p>安装完成后,检查依赖是否安装成功</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">rpm -q binutils compat-libcap1 compat-libstdc++-33 gcc gcc-c++ glibc glibc-devel ksh libaio libaio-devel libgcc libstdc++ libstdc++-devel libXi libXtst make sysstat unixODBC unixODBC-devel | grep "not installed"</span><br></pre></td></tr></table></figure><p><strong>注:本次安装使用的是腾讯云的centos服务器,腾讯云的yum源已经有了。如果您使用的是其他环境,缺少那个依赖包,就手动下载安装即可。</strong></p><h2 id="4-创建所需的操作系统组和用户"><a href="#4-创建所需的操作系统组和用户" class="headerlink" title="4. 创建所需的操作系统组和用户"></a>4. 创建所需的操作系统组和用户</h2><p>如果要安装Oracle数据库,则需要以下本地操作系统组和用户:</p><ul><li>Oracle inventory组(通常为 oinstall)</li><li>OSDBA组 (通常为 dba)</li><li>OSOPER组 (通常为 oper)</li><li>Oracle软件所有者(通常为 oracle)</li></ul><p>添加命令</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">groupadd oinstall</span><br><span class="line">groupadd dba</span><br><span class="line">groupadd oper</span><br><span class="line">useradd -g oinstall -G dba,oper oracle</span><br></pre></td></tr></table></figure><p>添加完成后,查看oracle用户</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">id oracle</span><br></pre></td></tr></table></figure><p>修改oracle用户密码</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">passwd oracle</span><br></pre></td></tr></table></figure><h2 id="5-配置内核参数和资源限制"><a href="#5-配置内核参数和资源限制" class="headerlink" title="5. 配置内核参数和资源限制"></a>5. 配置内核参数和资源限制</h2><ol><li>在<code>/etc/sysctl.conf</code>添加如下的参数,如果系统中某个参数高于下面的参数的值。保留较大的值,下面的数值之事官方要求的最小值。可以根据系统调整数值。以优化系统性能。具体参数说明请详见[内核参数说明](# 6.内核参数说明)</li></ol><pre><code><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/sysctl.conf</span><br><span class="line"></span><br><span class="line">fs.aio-max-nr = 1048576</span><br><span class="line">fs.file-max = 6815744</span><br><span class="line">kernel.shmall = 2097152</span><br><span class="line">kernel.shmmax = 536870912</span><br><span class="line">kernel.shmmni = 4096</span><br><span class="line">kernel.sem = 250 32000 100 128</span><br><span class="line">net.ipv4.ip_local_port_range = 9000 65500</span><br><span class="line">net.core.rmem_default = 262144</span><br><span class="line">net.core.rmem_max = 4194304</span><br><span class="line">net.core.wmem_default = 262144</span><br><span class="line">net.core.wmem_max = 1048576</span><br></pre></td></tr></table></figure></code></pre><ol><li><p>使内核参数生效</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sysctl -p 或者执行:/sbin/sysctl -p</span><br></pre></td></tr></table></figure></li><li><p>在<code>/etc/security/limits.conf</code>中添加如下参数</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/security/limits.conf</span><br><span class="line"></span><br><span class="line">oracle soft nproc 2047</span><br><span class="line">oracle hard nproc 16384</span><br><span class="line">oracle soft nofile 1024</span><br><span class="line">oracle hard nofile 65536</span><br><span class="line">oracle soft stack 10240</span><br></pre></td></tr></table></figure></li><li><p>在<code>/etc/pam.d/login</code>文件中,添加下面内容</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">session required /lib64/security/pam_limits.so</span><br><span class="line">session required pam_limits.so</span><br></pre></td></tr></table></figure></li><li><p><code>/etc/profile</code>文件中添加如下内容</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">if [ $USER = "oracle" ]; then</span><br><span class="line"> if [ $SHELL = "/bin/ksh" ]; then</span><br><span class="line"> ulimit -p 16384</span><br><span class="line"> ulimit -n 65536</span><br><span class="line"> else</span><br><span class="line"> ulimit -u 16384 -n 65536</span><br><span class="line"> fi</span><br><span class="line">fi</span><br></pre></td></tr></table></figure></li><li><p>使用<code>/etc/profile</code>文件生效</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">source /etc/profile</span><br></pre></td></tr></table></figure></li><li><p>禁用使用Transparent HugePages(启用Transparent HugePages,可能会导致造成内存在运行时的延迟分配,Oracle官方建议使用标准的HugePages)</p><ul><li><p>查看是否启用 如果显示 [always]说明启用了</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cat /sys/kernel/mm/transparent_hugepage/enabled</span><br></pre></td></tr></table></figure></li><li><p>禁用Transparent HugePages,在/etc/grub.conf添加如下内容</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">echo never > /sys/kernel/mm/transparent_hugepage/enabled</span><br></pre></td></tr></table></figure></li><li><p>重启系统以使更改成为永久更改:<code>reboot</code></p></li></ul></li></ol><h2 id="6-内核参数说明"><a href="#6-内核参数说明" class="headerlink" title="6.内核参数说明"></a>6.内核参数说明</h2><ul><li><code>fs.aio-max-nr</code>:同时可以拥有的的异步IO请求数目。1048576 即 1024*1024 也就是 1024K 个</li><li><code>fs.file-max</code>:系统允许打开的文件数。</li><li><code>kernel.shmall</code>:设置共享内存总页数。这个值太小有可能导致数据库启动报错,计算公式为:内存(G)* 1024 <em>1024</em>*1024/4096,4096为getconfPAGE_SIZE得到分页大小</li><li><code>kernel.shmmax</code>:Linux进程可以分配的单独共享内存段的最大值。一般设置为内存总大小的一半。这个值的设置应该大于SGA_MAX_TARGET或MEMORY_MAX_TARGET的值,因此对于安装Oracle数据库的系统,shmmax的值应该比内存的二分之一大一些。</li><li><code>kernel.shmmni</code>:设置系统级最大共享内存段数量。推荐最小值为4096</li><li><code>kernel.sem</code>:从左到右分别为SEMMSL、SEMMNS、SEMOPM和SEMMNI。<ul><li><code>SEMMSL</code>:设置每个信号灯组中信号灯最大数量,推荐的最小值是250。对于系统中存在大量并发连接的系统,推荐将这个值设置为PROCESSES初始化参数加10</li><li><code>SEMMNS</code>:设置系统中信号灯的最大数量。操作系统在分配信号灯时不会超过LEAST(SEMMNS,SEMMSL<em>SEMMNI)。事实上,如果SEMMNS的值超过了SEMMSL</em>SEMMNI是非法的,因此推荐SEMMNS的值就设置为SEMMSL<em>SEMMNI。Oracle推荐SEMMNS的设置不小于32000,假如数据库的PROCESSES参数设置为600,则SEMMNS的设置应为:SQL> select (600+10)</em>142 from dual;(600+10)*142/86620</li><li><code>SEMOPM</code>:设置每次系统调用可以同时执行的最大信号灯操作的数量。由于一个信号灯组最多拥有SEMMSL个信号灯,因此有推荐将SEMOPM设置为SEMMSL的值。Oracle验证的10.2和11.1的SEMOPM的配置为100。</li><li><code>SEMMNI</code>:设置系统中信号灯组的最大数量。Oracle10g和11g的推荐值为142</li></ul></li><li><code>net.ipv4.ip_local_port_range</code>:ip_local_port_range表示端口的范围,为指定的内容</li><li><code>net.core.rmem_default</code>:表示接收套接字缓冲区大小的缺省值(以字节为单位)。</li><li><code>net.core.rmem_max</code>:表示接收套接字缓冲区大小的最大值(以字节为单位)</li><li><code>net.core.wmem_default</code>:表示发送套接字缓冲区大小的缺省值(以字节为单位)</li><li><code>net.core.wmem_max</code>:表示发送套接字缓冲区大小的最大值(以字节为单位)</li></ul><h2 id="7-创建oracle安装目录"><a href="#7-创建oracle安装目录" class="headerlink" title="7. 创建oracle安装目录"></a>7. 创建oracle安装目录</h2><p>如下目录,可以根据自己的实际情况可做修改。我这里使用的是<code>/u01</code>作为根目录的,这样在以后的配置的时候感觉会省很多的事情。主要也是为了与公司产品数据库安装的时候配置路径保持一致。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">mkdir -p /u01/app/oracle </span><br><span class="line">mkdir -p /u01/app/oraInventory</span><br><span class="line">chown -R oracle:oinstall /u01/</span><br><span class="line">chown -R oracle:oinstall /u01/app/oracle</span><br><span class="line">chown -R oracle:oinstall /u01/app/oraInventory</span><br><span class="line">chmod -R 775 /u01/</span><br></pre></td></tr></table></figure><p>部分路径说明</p><ul><li>./app/oracle/product/11.2.0 :数据库系统安装目录</li><li>./app/oracle/backup:数据备份目录</li><li>./app/oracle/oraInventory:清单目录</li></ul><h2 id="8-配置oracle用户环境变量"><a href="#8-配置oracle用户环境变量" class="headerlink" title="8. 配置oracle用户环境变量"></a>8. 配置oracle用户环境变量</h2><p>在文件<code>~/.bash_profile</code>里添加下面的内容(具体值根据实际情况修改)<br>切换到oracle用户:<code>su - oracle</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">TMP=/tmp; export TMP</span><br><span class="line">TMPDIR=$TMP; export TMPDIR</span><br><span class="line">ORACLE_UNQNAME=ecology; export ORACLE_UNQNAME</span><br><span class="line">ORACLE_BASE=/u01/app/oracle; export ORACLE_BASE</span><br><span class="line">ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1; export ORACLE_HOME</span><br><span class="line">ORACLE_SID=ecology; export ORACLE_SID</span><br><span class="line">PATH=$PATH:/u01/app/oracle/product/11.2.0/db_1/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin; export PATH</span><br><span class="line">LD_LIBRARY_PATH=/lib:/lib:/usr/lib:$ORACLE_HOME/lib; exoprt LD_LIBRARY_PATH</span><br></pre></td></tr></table></figure><h2 id="9-重启一下系统"><a href="#9-重启一下系统" class="headerlink" title="9. 重启一下系统"></a>9. 重启一下系统</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">reboot</span><br></pre></td></tr></table></figure><h2 id="10-解压下载好的两个Oracle数据库"><a href="#10-解压下载好的两个Oracle数据库" class="headerlink" title="10. 解压下载好的两个Oracle数据库"></a>10. 解压下载好的两个Oracle数据库</h2><p><span style="color:red"><strong>解压的顺序需要注意一下,先解压一,然后在解压二</strong></span><br>将上传到系统的oracle安装包解压到上边新建的<code>/u01</code>路径下</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">unzip -q linux.x64_11gR2_database_1of2.zip -d /u01</span><br><span class="line">unzip -q linux.x64_11gR2_database_2of2.zip -d /u01</span><br></pre></td></tr></table></figure><p>创建一个新的文件夹,将解压后的应答文件放到新建的文件夹中,或者是在原路径下copy一份文件,最好是不要在原文件上修改</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">mkdir -p /data/etc</span><br><span class="line"># 复制响应文件</span><br><span class="line">cp /u01/database/response/* /data/etc/</span><br><span class="line">#设置响应文件权限</span><br><span class="line">su - root</span><br><span class="line">chmod 700 /data/etc/*.rsp</span><br></pre></td></tr></table></figure><p>复制到<code>/data/etc</code>目录下的文件作用</p><ul><li>db_install.rsp:安装应答</li><li>dbca.rsp:创建数据库应答</li><li>netca.rsp:建立监听、本地服务名等网络设置应答</li><li>特别是组件配置事后请用如右语句查询核实(select comp_id, comp_name, version, status from dba_registry)</li></ul><p>在<code>/data/etc/db_install.rsp</code>修改以下变量的值<br><span style="color:red">在配置对应的文件前,请先阅读 11.<code>db_install.rsp</code>应答文件参数说明 </span></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">cd /data/etc/</span><br><span class="line">vim db_install.rsp</span><br><span class="line"></span><br><span class="line">oracle.install.option=INSTALL_DB_SWONLY</span><br><span class="line">ORACLE_HOSTNAME=xiaofeifei#用hostname命令查看</span><br><span class="line">UNIX_GROUP_NAME=oinstall</span><br><span class="line">INVENTORY_LOCATION=/u01/app/oracle/inventory</span><br><span class="line">SELECTED_LANGUAGES=en,zh_CN</span><br><span class="line">ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1</span><br><span class="line">ORACLE_BASE=/u01/app/oracle</span><br><span class="line">oracle.install.db.InstallEdition=EE</span><br><span class="line">oracle.install.db.DBA_GROUP=dba</span><br><span class="line">oracle.install.db.OPER_GROUP=dba</span><br><span class="line">DECLINE_SECURITY_UPDATES=true</span><br></pre></td></tr></table></figure><h2 id="11-db-install-rsp应答文件参数说明"><a href="#11-db-install-rsp应答文件参数说明" class="headerlink" title="11.db_install.rsp应答文件参数说明"></a>11.<code>db_install.rsp</code>应答文件参数说明</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line">oracle.install.responseFileVersion=/oracle/install/rspfmt_dbinstall_response_schema_v11_2_0//标注响应文件版本.注解文件版本,这个版本必须和要#安装的数据库版本相同,安装检验无法通过,不能更改 </span><br><span class="line"> oracle.install.option=INSTALL_DB_SWONLY #INSTALL_DB_SWONLY:只装数据库软件;INSTALL_DB_AND_CONFIG:安装数据库软件并建库;UPGRADE_DB:升级数据库</span><br><span class="line"> ORACLE_HOSTNAME=主机名 #指定操作系统主机名,通过hostname 命令获得</span><br><span class="line"> UNIX_GROUP_NAME=oinstall//指定oracle inventory目录的所有者</span><br><span class="line"> INVENTORY_LOCATION=/u01/app/oraInventory指定产品清单oracle inventory目录的路径,win平台下可以生路</span><br><span class="line"> SELECTED_LANGUAGES=en,zh_CN//指定语言,可以选择多个,用逗号隔开。选择en, zh_CN(英文和简体中文)</span><br><span class="line"> ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_home1//设置ORALCE_HOME的路径</span><br><span class="line"> ORACLE_BASE=/u01/app/oracle//指定ORALCE_BASE的路径</span><br><span class="line"> oracle.install.db.InstallEdition=EE//安装数据库软件的版本,EE:企业版;SE:标准版;SEONE:标准版1</span><br><span class="line"> oracle.install.db.EEOptionsSelection=true//手动指定企业安装组件 选true对安装大小影响不大所以选true</span><br><span class="line"> oracle.install.db.optionalComponents=oracle.rdbms.partitioning:11.2.0.4.0,oracle.oraolap:11.2.0.4.0,oracle.rdbms.dm:11.2.0.4.0,oracle.rdbms.dv:11.2.0.4.0,oracle.rdbms.lbac:11.2.0.4.0,oracle.rdbms.rat:11.2.0.4.0//如果上面选true,这些就是手动指定的组件</span><br><span class="line"> oracle.install.db.DBA_GROUP=dba//指定拥有DBA用户组,通常会是dba组</span><br><span class="line"> oracle.install.db.OPER_GROUP=oper//指定oper用户组</span><br><span class="line"> oracle.install.db.CLUSTER_NODES=//指定所有的节点</span><br><span class="line"> oracle.install.db.isRACOneInstall=false//是否是RACO方式安装</span><br><span class="line"> oracle.install.db.racOneServiceName=</span><br><span class="line"> oracle.install.db.config.starterdb.type=//选择数据库的用途,一般用途/事物处理,数据仓库</span><br><span class="line"> oracle.install.db.config.starterdb.globalDBName=指定GlobalName</span><br><span class="line"> oracle.install.db.config.starterdb.SID=//你指定的SID</span><br><span class="line"> oracle.install.db.config.starterdb.characterSet=AL32UTF8//设置数据库编码</span><br><span class="line"> oracle.install.db.config.starterdb.memoryOption=true//11g的新特性自动内存管理,也就是SGA_TARGET和PAG_AGGREGATE_TARGET都,不用设置了,Oracle会自动调配两部分大小,这个要选true</span><br><span class="line"> oracle.install.db.config.starterdb.memoryLimit=上面是true的情况下,指定Oracle自动管理内存的大小,这里不用填或者填写物理内存的40%左右等等自定义;</span><br><span class="line"> oracle.install.db.config.starterdb.installExampleSchemas=false是否载入模板示例</span><br><span class="line"> oracle.install.db.config.starterdb.enableSecuritySettings=true 是否启用安全设置</span><br><span class="line"> oracle.install.db.config.starterdb.password.ALL=123456所有用户名的密码</span><br><span class="line"> oracle.install.db.config.starterdb.password.SYS=</span><br><span class="line"> oracle.install.db.config.starterdb.password.SYSTEM=</span><br><span class="line"> oracle.install.db.config.starterdb.password.SYSMAN=</span><br><span class="line"> oracle.install.db.config.starterdb.password.DBSNMP=</span><br><span class="line"> oracle.install.db.config.starterdb.control=DB_CONTROL数据库本地管理工具DB_CONTROL,远程集中管理工具GRID_CONTROL</span><br><span class="line"> oracle.install.db.config.starterdb.gridcontrol.gridControlServiceURL=GRID_CONTROL需要设定grid control的远程路径URL</span><br><span class="line"> oracle.install.db.config.starterdb.automatedBackup.enable=false设置自动备份</span><br><span class="line"> oracle.install.db.config.starterdb.automatedBackup.osuid=.自动备份会启动一个job,指定启动JOB的系统用户ID</span><br><span class="line"> oracle.install.db.config.starterdb.automatedBackup.ospwd=自动备份会开启一个job,需要指定OSUser的密码</span><br><span class="line"> oracle.install.db.config.starterdb.storageType=要求指定使用的文件系统存放数据库文件还是ASM</span><br><span class="line"> oracle.install.db.config.starterdb.fileSystemStorage.dataLocation=使用文件系统存放数据库文件才需要指定数据文件、控制文件、Redo log的存放目录</span><br><span class="line"> oracle.install.db.config.starterdb.fileSystemStorage.recoveryLocation=使用文件系统存放数据库文件才需要指定备份恢复目录</span><br><span class="line"> oracle.install.db.config.asm.diskGroup=使用ASM存放数据库文件才需要指定存放的磁盘组</span><br><span class="line"> oracle.install.db.config.asm.ASMSNMPPassword=使用ASM存放数据库文件才需要指定ASM实例密码</span><br><span class="line"> MYORACLESUPPORT_USERNAME=指定metalink账户用户名</span><br><span class="line"> MYORACLESUPPORT_PASSWORD=指定metalink账户密码</span><br><span class="line"> SECURITY_UPDATES_VIA_MYORACLESUPPORT=用户是否可以设置metalink密码</span><br><span class="line"> DECLINE_SECURITY_UPDATES=true是否设置安全更新,</span><br><span class="line"> PROXY_HOST=代理服务器名</span><br><span class="line"> PROXY_PORT=代理服务器端口</span><br><span class="line"> PROXY_USER=代理服务器用户名</span><br><span class="line"> PROXY_PWD=代理服务器密码</span><br><span class="line"> PROXY_REALM=</span><br><span class="line"> COLLECTOR_SUPPORTHUB_URL=</span><br><span class="line"> oracle.installer.autoupdates.option=SKIP_UPDATES 自动更新</span><br><span class="line"> oracle.installer.autoupdates.downloadUpdatesLoc=自动更新下载目录</span><br><span class="line"> AUTOUPDATES_MYORACLESUPPORT_USERNAME=自动更新的用户名</span><br><span class="line"> AUTOUPDATES_MYORACLESUPPORT_PASSWORD=自动更新的密码</span><br></pre></td></tr></table></figure><h2 id="12-开始安装"><a href="#12-开始安装" class="headerlink" title="12. 开始安装"></a>12. 开始安装</h2><p>开始安装的命令:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">su - oracle</span><br><span class="line">cd /u01/database</span><br><span class="line">./runInstaller -silent -responseFile /data/etc/db_install.rsp -ignorePrereq</span><br></pre></td></tr></table></figure><p>安装期间可以使用<code>tail</code>命令监看oracle的安装日志</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">#日志文件名称根据自己的实际执行时间变更,这里的日志文件会在界面上打出,直接粘贴复制就OK</span><br><span class="line">tail -f /data/app/oracle/inventory/logs/installActions2019-01-02_06-03-30PM.log</span><br></pre></td></tr></table></figure><p>安装完成后有如下的提示,如果有类似的提示,说明安装完成</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">You can find the log of this install session at:</span><br><span class="line"> /u01/app/oracle/inventory/logs/installActions2020-08-23_12-42-59AM.log</span><br><span class="line">The following configuration scripts need to be executed as the "root" user. </span><br><span class="line"> #!/bin/sh </span><br><span class="line"> #Root scripts to run</span><br><span class="line"></span><br><span class="line">/u01/app/oracle/inventory/orainstRoot.sh</span><br><span class="line">/u01/app/oracle/product/11.2.0/db_1/root.sh</span><br><span class="line">To execute the configuration scripts:</span><br><span class="line"> 1. Open a terminal window </span><br><span class="line"> 2. Log in as "root" </span><br><span class="line"> 3. Run the scripts </span><br><span class="line"> 4. Return to this window and hit "Enter" key to continue </span><br><span class="line"></span><br><span class="line">Successfully Setup Software.</span><br></pre></td></tr></table></figure><p>日志部分内容说明<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gi0tm4nn0aj314o0j6k29.jpg" alt=""></p><h2 id="13-使用root用户执行对应的脚本"><a href="#13-使用root用户执行对应的脚本" class="headerlink" title="13. 使用root用户执行对应的脚本"></a>13. 使用<code>root</code>用户执行对应的脚本</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">su - root</span><br><span class="line">sh /u01/app/oracle/inventory/orainstRoot.sh</span><br><span class="line">sh /u01/app/oracle/product/11.2.0/db_1/root.sh</span><br></pre></td></tr></table></figure><h2 id="14-配置监听程序"><a href="#14-配置监听程序" class="headerlink" title="14. 配置监听程序"></a>14. 配置监听程序</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">su - oracle</span><br><span class="line">netca /silent /responsefile /data/etc/netca.rsp</span><br></pre></td></tr></table></figure><p>注意:这里使用的命令是:<code>netca /silent /responsefile /data/etc/netca.rsp</code><br>而不是使用的<code>netca -silent -responseFile /home/oracle/database/response/netca.rsp</code>否则会报出如下的错误</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">****DISPLAY environment variable not set!</span><br><span class="line"> Oracle Net Configuration Assistant is a GUI tool</span><br><span class="line"> which requires that DISPLAY specify a location</span><br><span class="line"> where GUI tools can display.</span><br><span class="line"> Set and export DISPLAY, then re-run.</span><br></pre></td></tr></table></figure><p>如果使用的是xmanage的连接工具,可以使用如下的命令进行设置(这个没有进行测试过)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">解决方法:export DISPLAY=192.168.8.146:0.0</span><br><span class="line">export DISPLAY=自己的ip:0.0</span><br><span class="line">也有说的是把0.0改成1.0具体情况需要可以进行百度,网上有好多的处理方法</span><br></pre></td></tr></table></figure><p>查看监听端口:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">netstat -tnpl | grep 1521</span><br><span class="line">[oracle@xiaofeifei database]$ netstat -tnpl | grep 1521</span><br><span class="line"></span><br><span class="line">tcp6 0 0 :::1521 :::* LISTEN 8943/tnslsnr</span><br></pre></td></tr></table></figure><h2 id="15-静默创建数据库"><a href="#15-静默创建数据库" class="headerlink" title="15. 静默创建数据库"></a>15. 静默创建数据库</h2><ol><li><p>编辑应答文件<code>/data/etc/dbca.rsp</code>,部分参数说明请详见 [16.静默创建数据库部分参数说明](# 16. 静默创建数据库部分参数说明)</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">GDBNAME = "ecology"</span><br><span class="line">SID = "ecology"</span><br><span class="line">SYSPASSWORD = "192612"</span><br><span class="line">SYSTEMPASSWORD = "192612"</span><br><span class="line">CHARACTERSET = "AL32UTF8"</span><br><span class="line">INSTANCENAME = "ecology"</span><br><span class="line">TOTALMEMORY = "800"</span><br><span class="line">DB_UNIQUE_NAME = "ecology"</span><br></pre></td></tr></table></figure></li><li><p>执行静默建库</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">su - oracle</span><br><span class="line">dbca -silent -responseFile /data/etc/dbca.rsp</span><br></pre></td></tr></table></figure></li><li><p>执行过程如下</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">[oracle@xiaofeifei database]$ dbca -silent -responseFile /data/etc/dbca.rsp</span><br><span class="line">Copying database files </span><br><span class="line">1% complete </span><br><span class="line">3% complete </span><br><span class="line">11% complete </span><br><span class="line">18% complete </span><br><span class="line">26% complete </span><br><span class="line">37% complete </span><br><span class="line">Creating and starting Oracle instance </span><br><span class="line">40% complete </span><br><span class="line">45% complete </span><br><span class="line">50% complete</span><br><span class="line">55% complete</span><br><span class="line">56% complete</span><br><span class="line">60% complete</span><br><span class="line">62% complete</span><br><span class="line">Completing Database Creation</span><br><span class="line">66% complete</span><br><span class="line">70% complete</span><br><span class="line">73% complete</span><br><span class="line">85% complete</span><br><span class="line">96% complete</span><br><span class="line">100% complete</span><br><span class="line">Look at the log file "/u01/app/oracle/cfgtoollogs/dbca/ecology/ecology.log" for further details.</span><br></pre></td></tr></table></figure></li><li><p>查看进程</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ps -ef | grep ora_ | grep -v grep</span><br></pre></td></tr></table></figure></li><li><p>查看监听状态</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">lsnrctl status</span><br></pre></td></tr></table></figure></li></ol><h2 id="16-静默创建数据库部分参数说明"><a href="#16-静默创建数据库部分参数说明" class="headerlink" title="16. 静默创建数据库部分参数说明"></a>16. 静默创建数据库部分参数说明</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">RESPONSEFILE_VERSION = "11.2.0" #不能更改</span><br><span class="line"> OPERATION_TYPE = "createDatabase" #不变 默认即可</span><br><span class="line"> GDBNAME = "orcl" #数据库的名字,随便怎么改,不影响,自定义 比如"oracle11g.com"</span><br><span class="line"> SID = "orcl" #对应的实例名字instance_name,随便怎么改,不影响,自定义 比如"oracle11g.com"</span><br><span class="line"> TEMPLATENAME = "General_Purpose.dbc" #不变 默认即可 建库用的模板文件</span><br><span class="line"> SYSPASSWORD = "oracle" #SYS管理员密码 自定义</span><br><span class="line"> SYSTEMPASSWORD = "oracle" #SYSTEM管理员密码 自定义</span><br><span class="line"> DATAFILEDESTINATION = /data/app/oracle/oradata #数据文件存放目录 可自定义如/data目录但用户和组要是oracle:oinstall即mkdir /data ; chown -R oracle:oinstall /data ; chmod -R 775 /data; 当然此项默认是$ORACLE_BASE/oradata 此项本来是注释掉的,而$ORACLE_BASE/oradata就是/data/app/oracle/oradata,故此项可不用动,即保持注释掉即也可;</span><br><span class="line"> RECOVERYAREADESTINATION=/data/app/oracle/flash_recovery_area #恢复数据存放目录 闪回区 可自定义</span><br><span class="line"> CHARACTERSET = "AL32UTF8" #字符集,重要!!! 建库后一般不能更改,所以建库前要确定清楚,选AL32UTF8比较合适;</span><br><span class="line"> NATIONALCHARACTERSET= "AL16UTF16" #最好还是保持默认的"AL16UTF16",这里我选的UTF8可能出现了后面的PLSQL中文乱码;</span><br><span class="line"> #MEMORYPERCENTAGE = "40" #服务器物理内存分配给oracle的内存比例,这里先不选</span><br><span class="line"> #TOTALMEMORY = "3500" # //物理内存的60%左右,分配给oracle的总内存3500MB,可自行设定 或者注释不选因为oracle会自行管理;</span><br><span class="line"> #-----------------------*** End of CREATEDATABASE section ***------------------------</span><br><span class="line"> SOURCEDB = "myhost:1521:orcl" #End of CREATEDATABASE sectio后面的很多没有注释掉的选项不用管。</span><br></pre></td></tr></table></figure><h2 id="17-至此数据库就安装成功了,下面我们登陆下数据库"><a href="#17-至此数据库就安装成功了,下面我们登陆下数据库" class="headerlink" title="17. 至此数据库就安装成功了,下面我们登陆下数据库"></a>17. 至此数据库就安装成功了,下面我们登陆下数据库</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">su - oracle</span><br><span class="line">sqlplus / as sysdba</span><br><span class="line">select status from v$instance;</span><br></pre></td></tr></table></figure><p>执行<code>select</code>时,会出现以下情况</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SQL> select status from v$instance;</span><br><span class="line">select status from v$instance</span><br><span class="line">*</span><br><span class="line">ERROR at line 1:</span><br><span class="line">ORA-01034: ORACLE not available</span><br><span class="line">Process ID: 0</span><br><span class="line">Session ID: 0 Serial number: 0</span><br></pre></td></tr></table></figure><p>解决方式:<br>输入<code>startup</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">#startup的输出提示:</span><br><span class="line">SQL> statup</span><br><span class="line">SP2-0042: unknown command "statup" - rest of line ignored.</span><br><span class="line">SQL> startup</span><br><span class="line">#如果是在/u01的路径下则不会出现以下问题</span><br><span class="line">#ORA-01078: failure in processing system parameters</span><br><span class="line">#LRM-00109: could not open parameter file '/data/app/oracle/product/11.2.0/dbs/initORCL.ora'</span><br></pre></td></tr></table></figure><p>激活scott用户:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">alter user scott account unlock;</span><br><span class="line">alter user scott identified by tiger;</span><br><span class="line">select username,account_status from dba_users;</span><br></pre></td></tr></table></figure><h2 id="18-设置Oracle开机启动"><a href="#18-设置Oracle开机启动" class="headerlink" title="18. 设置Oracle开机启动"></a>18. 设置Oracle开机启动</h2><p><span style="color:red"><strong><em>这个步骤还未进行操作….</em></strong></span></p><h2 id="19-结合业务系统配置ecology数据库"><a href="#19-结合业务系统配置ecology数据库" class="headerlink" title="19. 结合业务系统配置ecology数据库"></a>19. 结合业务系统配置ecology数据库</h2><ol><li><p>创建Ecology数据库用户前的检查工作,首选需要确认监听是否正常</p><ul><li><p>切换到oracle用户下:<code>su - oracle</code></p></li><li><p>启动监听:<code>lsnrctl start</code></p></li><li><p>查看监听状态:<code>lsnrctl status</code></p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">[oracle@xiaofeifei database]$ lsnrctl status</span><br><span class="line">LSNRCTL for Linux: Version 11.2.0.1.0 - Production on 23-AUG-2020 16:49:31 </span><br><span class="line">Copyright (c) 1991, 2009, Oracle. All rights reserved. </span><br><span class="line">Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)))</span><br><span class="line">STATUS of the LISTENER</span><br><span class="line">Alias LISTENER</span><br><span class="line">Version TNSLSNR for Linux: Version 11.2.0.1.0 - Production</span><br><span class="line">Start Date 23-AUG-2020 11:02:27</span><br><span class="line">Uptime 0 days 5 hr. 47 min. 4 sec</span><br><span class="line">Trace Level off</span><br><span class="line">Security ON: Local OS Authentication</span><br><span class="line">SNMP OFF</span><br><span class="line">Listener Parameter File /u01/app/oracle/product/11.2.0/db_1/network/admin/listener.ora</span><br><span class="line">Listener Log File /u01/app/oracle/diag/tnslsnr/xiaofeifei/listener/alert/log.xml</span><br><span class="line">Listening Endpoints Summary...</span><br><span class="line"> (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=EXTPROC1521)))</span><br><span class="line"> (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=xiaofeifei)(PORT=1521)))</span><br><span class="line">Services Summary...</span><br><span class="line">Service "ecology" has 1 instance(s).</span><br><span class="line"> Instance "ecology", status READY, has 1 handler(s) for this service...</span><br><span class="line">Service "ecologyXDB" has 1 instance(s).</span><br><span class="line"> Instance "ecology", status READY, has 1 handler(s) for this service...</span><br><span class="line">The command completed successfully</span><br></pre></td></tr></table></figure></li><li><p>使用sysdba登录后,查看数据库状态(READ WRITE 为正常读写状态)</p></li><li><p>命令:<code>select open_mode from v$database;</code></p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">SQL> select open_mode from v$database;</span><br><span class="line">OPEN_MODE</span><br><span class="line">READ WRITE</span><br></pre></td></tr></table></figure><p> <img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gi0uit4zvzj31da0oogoq.jpg" alt=""></p></li><li><p>查看数据库数据文件存放目录。命令为:<code>select name from v$datafile;</code></p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">SQL> select name from v$datafile;</span><br><span class="line"></span><br><span class="line">NAME</span><br><span class="line"></span><br><span class="line">/u01/app/oracle/oradata/ecology/system01.dbf</span><br><span class="line">/u01/app/oracle/oradata/ecology/sysaux01.dbf</span><br><span class="line">/u01/app/oracle/oradata/ecology/undotbs01.dbf</span><br><span class="line">/u01/app/oracle/oradata/ecology/users01.dbf</span><br><span class="line">/u01/app/oracle/oradata/ecology/ecology.dbf</span><br></pre></td></tr></table></figure><p> <img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gi0uk1jac2j31580qa41x.jpg" alt=""></p></li></ul></li><li><p>创建OA数据库使用用户和表空间,并赋予用户权限</p><ul><li><p>创建OA 程序使用的表空间,表空间名为ECOLOGY,存储路径为/u01/app/oracle/oradata/ecology/ecology.dbf(此处存储路径是根据上面查询数据库数据文件存放目录确定的)。相关命令</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">create tablespace ecology datafile '/u01/app/oracle/oradata/ecology/ecology.dbf' size 2000M</span><br><span class="line">AutoExtend On Next 10M</span><br><span class="line">segment space management auto;</span><br></pre></td></tr></table></figure></li><li><p>创建用户,并关联用户使用的表空间和临时表空间,相关命令</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CREATE USER ecology IDENTIFIED BY ecology DEFAULT TABLESPACE ecology TEMPORARY TABLESPACE Temp;</span><br></pre></td></tr></table></figure></li><li><p>赋予OA 数据库用户权限(金融等行业客户无法给予DBA 权限),相关命令为:</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">grant connect,resource to ecology;</span><br><span class="line">alter user ecology quota unlimited on ecology;</span><br><span class="line">grant create view to ecology;</span><br><span class="line">grant DATAPUMP_EXP_FULL_DATABASE ,DATAPUMP_IMP_FULL_DATABASE to ecology;</span><br></pre></td></tr></table></figure></li><li><p>需要使用sysdba 用户执行,避免初始化时出现报错。相关命令为</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">alter system set "_allow_level_without_connect_by" = true;</span><br></pre></td></tr></table></figure></li><li><p>(对于上述第三步操作说明)需要修改此参数主要是因为我们脚本中有些递归查询和上下级的查询使用了level 关<br>键字,此语法在Oracle9i 版本中默认兼容支持,在10g 及之后的版本中需要修改上面的参<br>数之后才能支持。</p></li></ul></li></ol>]]></content>
<summary type="html">
<p>[TOC]</p>
<h1 id="Centos7下静默安装Oracle-11g-无图形化界面"><a href="#Centos7下静默安装Oracle-11g-无图形化界面" class="headerlink" title="Centos7下静默安装Oracle 11
</summary>
<category term="oracle" scheme="http://lwblog.xyz/tags/oracle/"/>
</entry>
<entry>
<title>MySQL学习笔记二</title>
<link href="http://lwblog.xyz/posts/671486fb.html"/>
<id>http://lwblog.xyz/posts/671486fb.html</id>
<published>2020-08-17T01:04:45.000Z</published>
<updated>2020-08-17T01:07:00.875Z</updated>
<content type="html"><![CDATA[<h1 id="MySQL学习笔记二"><a href="#MySQL学习笔记二" class="headerlink" title="MySQL学习笔记二"></a>MySQL学习笔记二</h1><h2 id="1-分组查询"><a href="#1-分组查询" class="headerlink" title="1.分组查询"></a>1.分组查询</h2><h3 id="1-1-添加分组签筛选"><a href="#1-1-添加分组签筛选" class="headerlink" title="1.1 添加分组签筛选"></a>1.1 添加分组签筛选</h3><p>作为条件的字段都来自于原始表单,可以将筛选条件放在where子句的后边</p><h3 id="1-2-添加分组后筛选"><a href="#1-2-添加分组后筛选" class="headerlink" title="1.2 添加分组后筛选"></a>1.2 添加分组后筛选</h3><p>案例:查询那个部门的员工个数>2<br>作为条件的字段不是来自于原始的表单,需要使用<code>having</code>的关键字来筛选,需要放在<code>group by</code>关键字后边</p><h3 id="1-3-函数分组"><a href="#1-3-函数分组" class="headerlink" title="1.3 函数分组"></a>1.3 函数分组</h3><p><code>group by</code>子句后边还支持按照表达式或者函数进行分组<br>案例:按照员工姓名长度分组,查询每一组员工的个数,筛选员工个数>5的有哪些</p><h3 id="1-4-按多个字段分组"><a href="#1-4-按多个字段分组" class="headerlink" title="1.4 按多个字段分组"></a>1.4 按多个字段分组</h3><p>案例:每个部门,每个工种的员工的平均工资</p><h3 id="1-5-添加排序"><a href="#1-5-添加排序" class="headerlink" title="1.5 添加排序"></a>1.5 添加排序</h3><p>分组查询也可以支持排序</p><h2 id="2-连接查询"><a href="#2-连接查询" class="headerlink" title="2. 连接查询"></a>2. 连接查询</h2><p>查询的字段来自于多个表单,需要用到连接查询</p><h3 id="2-1-笛卡尔乘积"><a href="#2-1-笛卡尔乘积" class="headerlink" title="2.1 笛卡尔乘积"></a>2.1 笛卡尔乘积</h3><p>现象:表1有m行,表2有n行,结果=m*n行<br>避免:添加有效的连接条件</p><h3 id="2-2-连接查询分类"><a href="#2-2-连接查询分类" class="headerlink" title="2.2 连接查询分类"></a>2.2 连接查询分类</h3><p>按照年代分类:sql92标准、sql99标准<br>按照功能分类:内连接、外连接、交叉连接</p><h3 id="2-3-等值连接介绍"><a href="#2-3-等值连接介绍" class="headerlink" title="2.3 等值连接介绍"></a>2.3 等值连接介绍</h3><p><strong><em>如果给表起了别名,就不能用原来的表名称去限定字段的</em></strong><br>特点:</p><ol><li>多表等值连接的结果为多表的交集部分</li><li>n表连接,至少需要n-1个连接条件</li><li>多表连接的顺序没有要求</li><li>一般需要为表起别名</li><li>可以搭配前面介绍的所有的字句使用<br>案例:查询女神和对应男神的名称</li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">select beauty.`name`,boys.boyNamefrom boys,beauty where beauty.boyfriend_id = boys.id</span><br></pre></td></tr></table></figure><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gh8ysht42tj30v00a2q5q.jpg" alt=""></p><h3 id="2-4-非等值连接"><a href="#2-4-非等值连接" class="headerlink" title="2.4 非等值连接"></a>2.4 非等值连接</h3><p>案例:查询员工工资和工资级别</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">SELECT salary,grade_level</span><br><span class="line">FROM employees e,job_grades g</span><br><span class="line">WHERE salary BETWEEN g.`lowest_sal` AND g.`highest_sal`</span><br><span class="line">AND g.`grade_level`='A';</span><br></pre></td></tr></table></figure><h3 id="2-5-自连接"><a href="#2-5-自连接" class="headerlink" title="2.5 自连接"></a>2.5 自连接</h3><p>自己连接自己<br>案例:查询员工名称和上级员工名称</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">SELECT e.employee_id,e.last_name,m.employee_id,m.last_name</span><br><span class="line">FROM employees e,employees m</span><br><span class="line">WHERE e.`manager_id`=m.`employee_id`;</span><br></pre></td></tr></table></figure><h2 id="3-sql99语法"><a href="#3-sql99语法" class="headerlink" title="3. sql99语法"></a>3. sql99语法</h2><h3 id="3-1-语法介绍"><a href="#3-1-语法介绍" class="headerlink" title="3.1 语法介绍"></a>3.1 语法介绍</h3><p>1999年新推出的sql标准<br>语法</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">select 查询列表</span><br><span class="line">from 表1 【连接类型】</span><br><span class="line">join 表2 别名 on 连接条件</span><br><span class="line">【where 筛选条件】</span><br><span class="line">【group by 分组】</span><br><span class="line">【having 筛选条件】</span><br><span class="line">【order by 排序列表】</span><br></pre></td></tr></table></figure><h3 id="3-2-等值连接"><a href="#3-2-等值连接" class="headerlink" title="3.2 等值连接"></a>3.2 等值连接</h3><p><strong><em>表的位置是可以进行互换的</em></strong><br>语法:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">select 查询列表</span><br><span class="line">from 表1 别名</span><br><span class="line">inner join 表2 别名 on 连接条件</span><br></pre></td></tr></table></figure><p>案例1:查询员工名称和部门名称</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">select last_name,department_name</span><br><span class="line">from employees e</span><br><span class="line">inner join departments d</span><br><span class="line">on e.department_id = d.department_id</span><br></pre></td></tr></table></figure><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gh90ilmfsvj312s0iedlk.jpg" alt=""></p><p>案例2:查询员工名、部门名、工种名,并按部门名降序(三表连接)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">-- 连接的表需要和前边有联系(有一定的联系)</span><br><span class="line">SELECT last_name,department_name,job_title</span><br><span class="line">FROM employees e</span><br><span class="line">INNER JOIN departments d ON e.`department_id`=d.`department_id`</span><br><span class="line">INNER JOIN jobs j ON e.`job_id` = j.`job_id`</span><br><span class="line">ORDER BY department_name DESC;</span><br></pre></td></tr></table></figure><h3 id="3-3-非等值连接"><a href="#3-3-非等值连接" class="headerlink" title="3.3 非等值连接"></a>3.3 非等值连接</h3><p>案例1:查询员工的工资级别</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">SELECT salary,grade_level</span><br><span class="line">FROM employees e</span><br><span class="line"> JOIN job_grades g</span><br><span class="line"> ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`;</span><br></pre></td></tr></table></figure><p>案例2:查询工资级别的个数>20的个数,并且按工资级别降序</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">SELECT COUNT(*),grade_level</span><br><span class="line">FROM employees e</span><br><span class="line"> JOIN job_grades g</span><br><span class="line"> ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`</span><br><span class="line"> GROUP BY grade_level</span><br><span class="line"> HAVING COUNT(*)>20</span><br></pre></td></tr></table></figure><h3 id="3-4-自连接"><a href="#3-4-自连接" class="headerlink" title="3.4 自连接"></a>3.4 自连接</h3><p>案例1:查询员工的名字、上级的名字</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">SELECT e.last_name,m.last_name</span><br><span class="line"> FROM employees e</span><br><span class="line"> JOIN employees m</span><br><span class="line"> ON e.`manager_id`= m.`employee_id`;</span><br></pre></td></tr></table></figure><p>案例2:查询姓名中包含字符k的员工的名字、上级的名字</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">SELECT e.last_name,m.last_name</span><br><span class="line">FROM employees e</span><br><span class="line">JOIN employees m</span><br><span class="line">ON e.`manager_id`= m.`employee_id`</span><br><span class="line">WHERE e.`last_name` LIKE '%k%';</span><br></pre></td></tr></table></figure><h3 id="3-5-左-右-外连接"><a href="#3-5-左-右-外连接" class="headerlink" title="3.5 左(右)外连接"></a>3.5 左(右)外连接</h3><p>应用场景:用于查询一个表中有,另一个表没有的记录<br>特点:</p><ol><li>外连接的查询结果为主表中的所有记录<ul><li>如果从表中有和它匹配的,则显示匹配的值</li><li>如果从表中没有和它匹配的,则显示null</li><li>外连接查询结果=内连接结果+主表中有而从表没有的记录</li></ul></li><li>左外连接,left join左边的是主表<ul><li>右外连接,right join右边的是主表</li></ul></li><li>左外和右外交换两个表的顺序,可以实现同样的效果</li><li>全外连接=内连接的结果+表1中有但表2没有的+表2中有但表1没有的</li></ol><p>案例1:查询哪个部门没有员工<br>左外:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">SELECT d.*,e.employee_id</span><br><span class="line"> FROM departments d</span><br><span class="line"> LEFT OUTER JOIN employees e</span><br><span class="line"> ON d.`department_id` = e.`department_id`</span><br><span class="line"> WHERE e.`employee_id` IS NULL;</span><br></pre></td></tr></table></figure><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gh912codxhj312q0jk7cp.jpg" alt=""></p><p>右外:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">SELECT d.*,e.employee_id</span><br><span class="line"> FROM employees e</span><br><span class="line"> RIGHT OUTER JOIN departments d</span><br><span class="line"> ON d.`department_id` = e.`department_id`</span><br><span class="line"> WHERE e.`employee_id` IS NULL;</span><br></pre></td></tr></table></figure><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gh916ckf3tj312m0j6tgz.jpg" alt=""></p><h3 id="3-6-全外连接"><a href="#3-6-全外连接" class="headerlink" title="3.6 全外连接"></a>3.6 全外连接</h3><p><strong><em>==mysql数据库不支持全外连接查询==</em></strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">USE girls;</span><br><span class="line"> SELECT b.*,bo.*</span><br><span class="line"> FROM beauty b</span><br><span class="line"> FULL OUTER JOIN boys bo</span><br><span class="line"> ON b.`boyfriend_id` = bo.id;</span><br></pre></td></tr></table></figure><h3 id="3-7-交叉连接"><a href="#3-7-交叉连接" class="headerlink" title="3.7 交叉连接"></a>3.7 交叉连接</h3><p>代表笛卡尔乘积</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">SELECT b.*,bo.*</span><br><span class="line"> FROM beauty b</span><br><span class="line"> CROSS JOIN boys bo;</span><br></pre></td></tr></table></figure><h2 id="4-子查询介绍"><a href="#4-子查询介绍" class="headerlink" title="4. 子查询介绍"></a>4. 子查询介绍</h2><p>含义:出现在其他语句中的select语句,称为子查询或内查询<br> 外部的查询语句,称为主查询或外查询<br>分类:</p><ol><li><p>按子查询出现的位置:</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">select后面:</span><br><span class="line">仅仅支持标量子查询</span><br><span class="line"></span><br><span class="line">from后面:</span><br><span class="line">支持表子查询</span><br><span class="line">where或having后面:★</span><br><span class="line">标量子查询(单行) √</span><br><span class="line">列子查询 (多行) √</span><br><span class="line"></span><br><span class="line">行子查询</span><br><span class="line"></span><br><span class="line">exists后面(相关子查询)</span><br><span class="line">表子查询</span><br></pre></td></tr></table></figure></li><li><p>按结果集的行列数不同:</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">标量子查询(结果集只有一行一列)</span><br><span class="line">列子查询(结果集只有一列多行)</span><br><span class="line">行子查询(结果集有一行多列)</span><br><span class="line">表子查询(结果集一般为多行多列)</span><br></pre></td></tr></table></figure><h3 id="4-1-where后面标量子查询"><a href="#4-1-where后面标量子查询" class="headerlink" title="4.1 where后面标量子查询"></a>4.1 where后面标量子查询</h3><p>位置是在<code>where</code>或者<code>having</code>的后面<br>1、标量子查询(单行子查询)<br>2、列子查询(多行子查询)<br>3、行子查询(多列多行)<br>特点:<br>①子查询放在小括号内<br>②子查询一般放在条件的右侧<br>③标量子查询,一般搭配着单行操作符使用:> < >= <= = <><br>列子查询,一般搭配着多行操作符使用:in、any/some、all<br>④子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果</p></li></ol><p>案例1:查询员工的信息,满足 salary>①结果(标量子查询)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">SELECT *</span><br><span class="line">FROM employees</span><br><span class="line">WHERE salary>(</span><br><span class="line"></span><br><span class="line">SELECT salary</span><br><span class="line">FROM employees</span><br><span class="line">WHERE last_name = 'Abel'</span><br><span class="line"></span><br><span class="line">);</span><br></pre></td></tr></table></figure><p>案例2:返回job_id与141号员工相同,salary比143号员工多的员工 姓名,job_id 和工资</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">SELECT last_name,job_id,salary</span><br><span class="line">FROM employees</span><br><span class="line">WHERE job_id = (</span><br><span class="line">SELECT job_id</span><br><span class="line">FROM employees</span><br><span class="line">WHERE employee_id = 141</span><br><span class="line">) AND salary>(</span><br><span class="line">SELECT salary</span><br><span class="line">FROM employees</span><br><span class="line">WHERE employee_id = 143</span><br><span class="line"></span><br><span class="line">);</span><br></pre></td></tr></table></figure><p>案例3:查询最低工资大于50号部门最低工资的部门id和其最低工资</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SELECT MIN(salary),department_id</span><br><span class="line">FROM employees</span><br><span class="line">GROUP BY department_id</span><br><span class="line">HAVING MIN(salary)>(</span><br><span class="line">SELECT MIN(salary)</span><br><span class="line">FROM employees</span><br><span class="line">WHERE department_id = 50</span><br></pre></td></tr></table></figure><h3 id="4-2-where后面的列子查询"><a href="#4-2-where后面的列子查询" class="headerlink" title="4.2 where后面的列子查询"></a>4.2 where后面的列子查询</h3><p>案例1:返回location_id是1400或1700的部门中的所有员工姓名</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SELECT last_name</span><br><span class="line">FROM employees</span><br><span class="line">WHERE department_id <>ALL(</span><br><span class="line">SELECT DISTINCT department_id</span><br><span class="line">FROM departments</span><br><span class="line">WHERE location_id IN(1400,1700)</span><br><span class="line">);</span><br></pre></td></tr></table></figure><p>案例2:返回其它工种中比job_id为‘IT_PROG’工种任一工资低的员工的员工号、姓名、job_id 以及salary</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">SELECT last_name,employee_id,job_id,salary</span><br><span class="line">FROM employees</span><br><span class="line">WHERE salary<ANY(</span><br><span class="line">SELECT DISTINCT salary</span><br><span class="line">FROM employees</span><br><span class="line">WHERE job_id = 'IT_PROG'</span><br><span class="line"></span><br><span class="line">) AND job_id<>'IT_PROG';</span><br><span class="line"></span><br><span class="line">#或</span><br><span class="line">SELECT last_name,employee_id,job_id,salary</span><br><span class="line">FROM employees</span><br><span class="line">WHERE salary<(</span><br><span class="line">SELECT MAX(salary)</span><br><span class="line">FROM employees</span><br><span class="line">WHERE job_id = 'IT_PROG'</span><br><span class="line"></span><br><span class="line">) AND job_id<>'IT_PROG';</span><br></pre></td></tr></table></figure><p>案例3:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工 的员工号、姓名、job_id 以及salary</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">SELECT last_name,employee_id,job_id,salary</span><br><span class="line">FROM employees</span><br><span class="line">WHERE salary<ALL(</span><br><span class="line">SELECT DISTINCT salary</span><br><span class="line">FROM employees</span><br><span class="line">WHERE job_id = 'IT_PROG'</span><br><span class="line"></span><br><span class="line">) AND job_id<>'IT_PROG';</span><br><span class="line"></span><br><span class="line">#或</span><br><span class="line"></span><br><span class="line">SELECT last_name,employee_id,job_id,salary</span><br><span class="line">FROM employees</span><br><span class="line">WHERE salary<(</span><br><span class="line">SELECT MIN( salary)</span><br><span class="line">FROM employees</span><br><span class="line">WHERE job_id = 'IT_PROG'</span><br><span class="line"></span><br><span class="line">) AND job_id<>'IT_PROG';</span><br></pre></td></tr></table></figure><h3 id="4-3-where后面的行子查询"><a href="#4-3-where后面的行子查询" class="headerlink" title="4.3 where后面的行子查询"></a>4.3 where后面的行子查询</h3><p>案例:查询员工编号最小并且工资最高的员工信息</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">SELECT *</span><br><span class="line">FROM employees</span><br><span class="line">WHERE employee_id=(</span><br><span class="line">SELECT MIN(employee_id)</span><br><span class="line">FROM employees</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">)AND salary=(</span><br><span class="line">SELECT MAX(salary)</span><br><span class="line">FROM employees</span><br><span class="line"></span><br><span class="line">);</span><br></pre></td></tr></table></figure><h3 id="4-4-select后面的子查询"><a href="#4-4-select后面的子查询" class="headerlink" title="4.4 select后面的子查询"></a>4.4 select后面的子查询</h3><p><strong><em>==仅仅支持标量子查询==</em></strong><br>案例:查询每个部门的员工个数</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">SELECT d.*,(</span><br><span class="line"></span><br><span class="line">SELECT COUNT(*)</span><br><span class="line">FROM employees e</span><br><span class="line">WHERE e.department_id = d.`department_id`</span><br><span class="line"> ) 个数</span><br><span class="line"> FROM departments d;</span><br></pre></td></tr></table></figure><p>案例2:查询员工号=102的部门名</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">SELECT (</span><br><span class="line">SELECT department_name,e.department_id</span><br><span class="line">FROM departments d</span><br><span class="line">INNER JOIN employees e</span><br><span class="line">ON d.department_id=e.department_id</span><br><span class="line">WHERE e.employee_id=102</span><br><span class="line"></span><br><span class="line">) 部门名;</span><br></pre></td></tr></table></figure><h3 id="4-5-from后面的子查询"><a href="#4-5-from后面的子查询" class="headerlink" title="4.5 from后面的子查询"></a>4.5 from后面的子查询</h3><p><strong><em>==将子查询结果充当一张表,要求必须起别名==</em></strong><br>案例:查询每个部门的平均工资的工资等级</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">SELECT ag_dep.*,g.`grade_level`</span><br><span class="line">FROM (</span><br><span class="line">SELECT AVG(salary) ag,department_id</span><br><span class="line">FROM employees</span><br><span class="line">GROUP BY department_id</span><br><span class="line">) ag_dep</span><br><span class="line">INNER JOIN job_grades g</span><br><span class="line">ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;</span><br></pre></td></tr></table></figure><h3 id="4-6-exists后面的子查询"><a href="#4-6-exists后面的子查询" class="headerlink" title="4.6 exists后面的子查询"></a>4.6 exists后面的子查询</h3><p>语法:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">exists(完整的查询语句)</span><br><span class="line">结果:1或0</span><br></pre></td></tr></table></figure><p>案例1:查询有员工的部门名</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">#in</span><br><span class="line">SELECT department_name</span><br><span class="line">FROM departments d</span><br><span class="line">WHERE d.`department_id` IN(</span><br><span class="line">SELECT department_id</span><br><span class="line">FROM employees</span><br><span class="line"></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">#exists</span><br><span class="line"></span><br><span class="line">SELECT department_name</span><br><span class="line">FROM departments d</span><br><span class="line">WHERE EXISTS(</span><br><span class="line">SELECT *</span><br><span class="line">FROM employees e</span><br><span class="line">WHERE d.`department_id`=e.`department_id`</span><br><span class="line">);</span><br></pre></td></tr></table></figure><p>案例2:查询没有女朋友的男神信息</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">#in</span><br><span class="line"></span><br><span class="line">SELECT bo.*</span><br><span class="line">FROM boys bo</span><br><span class="line">WHERE bo.id NOT IN(</span><br><span class="line">SELECT boyfriend_id</span><br><span class="line">FROM beauty</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">#exists</span><br><span class="line">SELECT bo.*</span><br><span class="line">FROM boys bo</span><br><span class="line">WHERE NOT EXISTS(</span><br><span class="line">SELECT boyfriend_id</span><br><span class="line">FROM beauty b</span><br><span class="line">WHERE bo.`id`=b.`boyfriend_id`</span><br><span class="line"></span><br><span class="line">);</span><br></pre></td></tr></table></figure><h2 id="5-分页查询"><a href="#5-分页查询" class="headerlink" title="5. 分页查询"></a>5. 分页查询</h2><p>应用场景:当要显示的数据,一页显示不全,需要分页提交sql请求<br>语法:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">select 查询列表</span><br><span class="line">from 表</span><br><span class="line">【join type join 表2</span><br><span class="line">on 连接条件</span><br><span class="line">where 筛选条件</span><br><span class="line">group by 分组字段</span><br><span class="line">having 分组后的筛选</span><br><span class="line">order by 排序的字段】</span><br><span class="line">limit 【offset,】size;</span><br><span class="line"></span><br><span class="line">offset要显示条目的起始索引(起始索引从0开始)</span><br><span class="line">size 要显示的条目个数</span><br></pre></td></tr></table></figure><p>特点:<br>①limit语句放在查询语句的最后<br> ②公式<br> 要显示的页数 page,每页的条目数size</p><pre><code>select 查询列表from 表limit (page-1)*size,size;</code></pre><h2 id="6-联合查询介绍"><a href="#6-联合查询介绍" class="headerlink" title="6.联合查询介绍"></a>6.联合查询介绍</h2><p>应用场景:要查询的结果来自多个表,且多个表没有直接的关系,但查询信息节本一样<br>union 联合 合并:将多条查询语句的结果合并成一个结果<br>案例:查询中国用户中男性的信息以及外国用户中年男性的用户信息</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">-- 去掉重复的</span><br><span class="line">SELECT * FROM employees WHERE email LIKE '%a%'</span><br><span class="line">UNION</span><br><span class="line">SELECT * FROM employees WHERE department_id>90;</span><br><span class="line"></span><br><span class="line">-- 包含重复项</span><br><span class="line">SELECT id,cname FROM t_ca WHERE csex='男'</span><br><span class="line">UNION ALL</span><br><span class="line">SELECT t_id,tname FROM t_ua WHERE tGender='male';</span><br></pre></td></tr></table></figure><h2 id="7-联合查询特点"><a href="#7-联合查询特点" class="headerlink" title="7.联合查询特点"></a>7.联合查询特点</h2><p>特点:★<br>1、要求多条查询语句的查询列数是一致的!<br>2、要求多条查询语句的查询的每一列的类型和顺序最好一致<br>3、union关键字默认去重,如果使用union all 可以包含重复项</p><h2 id="8-插入语句"><a href="#8-插入语句" class="headerlink" title="8. 插入语句"></a>8. 插入语句</h2><h3 id="8-1-插入语句方式一"><a href="#8-1-插入语句方式一" class="headerlink" title="8.1 插入语句方式一"></a>8.1 插入语句方式一</h3><h3 id="8-2-插入语句方式二"><a href="#8-2-插入语句方式二" class="headerlink" title="8.2 插入语句方式二"></a>8.2 插入语句方式二</h3><h2 id="9-修改表单记录"><a href="#9-修改表单记录" class="headerlink" title="9.修改表单记录"></a>9.修改表单记录</h2><h3 id="9-1-修改单表记录"><a href="#9-1-修改单表记录" class="headerlink" title="9.1 修改单表记录"></a>9.1 修改单表记录</h3><h3 id="9-2-修改多表记录"><a href="#9-2-修改多表记录" class="headerlink" title="9.2 修改多表记录"></a>9.2 修改多表记录</h3><p>语法:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">sql92语法:</span><br><span class="line">update 表1 别名,表2 别名</span><br><span class="line">set 列 = 值</span><br><span class="line">where 连接条件 and 筛选条件</span><br><span class="line"></span><br><span class="line">sql99语法:</span><br><span class="line">update 表1 别名</span><br><span class="line">inner|left|right join 表2 别名</span><br><span class="line">on 连接条件</span><br><span class="line">set 列 = 值</span><br><span class="line">where 筛选条件</span><br></pre></td></tr></table></figure><h2 id="10-删除语句介绍"><a href="#10-删除语句介绍" class="headerlink" title="10. 删除语句介绍"></a>10. 删除语句介绍</h2><h3 id="10-1-删除方式一"><a href="#10-1-删除方式一" class="headerlink" title="10.1 删除方式一"></a>10.1 删除方式一</h3><p>删除表单的整行记录,自增长列的值从断点开始<br>语法:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">delete from 表名 where 筛选条件</span><br></pre></td></tr></table></figure><h3 id="10-2-删除方式二"><a href="#10-2-删除方式二" class="headerlink" title="10.2 删除方式二"></a>10.2 删除方式二</h3><p>删除了整个表单的记录,不能添加where条件,自增长的值从1开始<br>语法:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">truncate table 表名</span><br></pre></td></tr></table></figure><h2 id="11-DDL语言介绍"><a href="#11-DDL语言介绍" class="headerlink" title="11. DDL语言介绍"></a>11. DDL语言介绍</h2><p>创建: create<br>修改: alter<br>删除: drop</p><h3 id="11-1-库的管理"><a href="#11-1-库的管理" class="headerlink" title="11.1 库的管理"></a>11.1 库的管理</h3><p>案例:创建库Books</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CREATE DATABASE IF NOT EXISTS books ;</span><br></pre></td></tr></table></figure><p>案例2:库的修改</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">RENAME DATABASE books TO 新库名;</span><br></pre></td></tr></table></figure><p>案例3:更改库的字符集</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ALTER DATABASE books CHARACTER SET gbk;</span><br></pre></td></tr></table></figure><p>案例4:库的删除</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">DROP DATABASE IF EXISTS books;</span><br></pre></td></tr></table></figure><h3 id="11-2-表的创建"><a href="#11-2-表的创建" class="headerlink" title="11.2 表的创建"></a>11.2 表的创建</h3><p>语法:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">create table 表名(</span><br><span class="line">列名 列的类型【(长度) 约束】,</span><br><span class="line">列名 列的类型【(长度) 约束】,</span><br><span class="line">列名 列的类型【(长度) 约束】,</span><br><span class="line">...</span><br><span class="line">列名 列的类型【(长度) 约束】</span><br><span class="line">)</span><br></pre></td></tr></table></figure><p>案例:创建表Book</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">CREATE TABLE book(</span><br><span class="line">id INT,#编号</span><br><span class="line">bName VARCHAR(20),#图书名</span><br><span class="line">price DOUBLE,#价格</span><br><span class="line">authorId INT,#作者编号</span><br><span class="line">publishDate DATETIME#出版日期</span><br><span class="line">);</span><br></pre></td></tr></table></figure><p>案例:创建表author</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">CREATE TABLE IF NOT EXISTS author(</span><br><span class="line">id INT,</span><br><span class="line">au_name VARCHAR(20),</span><br><span class="line">nation VARCHAR(10)</span><br><span class="line">)</span><br><span class="line">DESC author;</span><br></pre></td></tr></table></figure><h3 id="11-3-表的修改"><a href="#11-3-表的修改" class="headerlink" title="11.3 表的修改"></a>11.3 表的修改</h3><p>语法:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">alter table 表名 add|drop|modify|change column 列名 【列类型 约束】;</span><br></pre></td></tr></table></figure><p>案例</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">#①修改列名</span><br><span class="line">ALTER TABLE book CHANGE COLUMN publishdate pubDate DATETIME;</span><br><span class="line">#②修改列的类型或约束</span><br><span class="line">ALTER TABLE book MODIFY COLUMN pubdate TIMESTAMP;</span><br><span class="line">#③添加新列</span><br><span class="line">ALTER TABLE author ADD COLUMN annual DOUBLE; </span><br><span class="line">#④删除列</span><br><span class="line">ALTER TABLE book_author DROP COLUMN annual;</span><br><span class="line">#⑤修改表名</span><br><span class="line">ALTER TABLE author RENAME TO book_author;</span><br><span class="line">DESC book;</span><br></pre></td></tr></table></figure><h3 id="11-4-表的删除"><a href="#11-4-表的删除" class="headerlink" title="11.4 表的删除"></a>11.4 表的删除</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">DROP TABLE IF EXISTS book_author;</span><br><span class="line">SHOW TABLES;</span><br></pre></td></tr></table></figure><h3 id="11-5-表的复制"><a href="#11-5-表的复制" class="headerlink" title="11.5 表的复制"></a>11.5 表的复制</h3><p>案例:仅仅复制表的结构</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CREATE TABLE copy LIKE author;</span><br></pre></td></tr></table></figure><p>案例:复制表的结构+数据</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">CREATE TABLE copy2 </span><br><span class="line">SELECT * FROM author;</span><br></pre></td></tr></table></figure><p>案例:只复制部分数据</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">CREATE TABLE copy3</span><br><span class="line">SELECT id,au_name</span><br><span class="line">FROM author </span><br><span class="line">WHERE nation='中国';</span><br></pre></td></tr></table></figure><p>案例:仅仅复制某些字段</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">CREATE TABLE copy4 </span><br><span class="line">SELECT id,au_name</span><br><span class="line">FROM author</span><br><span class="line">WHERE 0;</span><br></pre></td></tr></table></figure><h2 id="12-数据类型介绍"><a href="#12-数据类型介绍" class="headerlink" title="12. 数据类型介绍"></a>12. 数据类型介绍</h2><p>常见的数据类型<br>数值型:<br> 整型<br> 小数:<br> 定点数<br> 浮点数<br>字符型:<br> 较短的文本:char、varchar<br> 较长的文本:text、blob(较长的二进制数据)</p><p>日期型:</p><h3 id="12-1-整型"><a href="#12-1-整型" class="headerlink" title="12.1 整型"></a>12.1 整型</h3><p>分类:<br>tinyint、smallint、mediumint、int/integer、bigint<br> 1 2 3 4 8</p><p>特点:<br>① 如果不设置无符号还是有符号,默认是有符号,如果想设置无符号,需要添加unsigned关键字<br>② 如果插入的数值超出了整型的范围,会报out of range异常,并且插入临界值<br>③ 如果不设置长度,会有默认的长度<br>长度代表了显示的最大宽度,如果不够会用0在左边填充,但必须搭配zerofill使用!</p><h3 id="12-2-浮点型"><a href="#12-2-浮点型" class="headerlink" title="12.2 浮点型"></a>12.2 浮点型</h3><p>分类:<br>1.浮点型<br>float(M,D)<br>double(M,D)<br>2.定点型<br>dec(M,D)<br>decimal(M,D)<br>特点:<br>①M:整数部位+小数部位 D:小数部位 如果超过范围,则插入临界值<br>②M和D都可以省略,如果是decimal,则M默认为10,D默认为0,如果是float和double,则会根据插入的数值的精度来决定精度<br>③定点型的精确度较高,如果要求插入数值的精度较高如货币运算等则考虑使用</p><h3 id="12-3-字符型"><a href="#12-3-字符型" class="headerlink" title="12.3 字符型"></a>12.3 字符型</h3><p>较短的文本:char、varchar<br>其他:<br>binary和varbinary用于保存较短的二进制<br>enum用于保存枚举<br>set用于保存集合<br>较长的文本:text、blob(较大的二进制)</p><h3 id="12-4-日期型"><a href="#12-4-日期型" class="headerlink" title="12.4 日期型"></a>12.4 日期型</h3><p>分类:<br>date只保存日期<br>time 只保存时间<br>year只保存年<br>datetime保存日期+时间<br>timestamp保存日期+时间</p><h2 id="13-常见约束介绍"><a href="#13-常见约束介绍" class="headerlink" title="13. 常见约束介绍"></a>13. 常见约束介绍</h2><p>not null:非空约束,用于保证该字段的值不能为空<br>DEFAULT:默认约束,用于保证该字段有默认值<br>PRIMARY KEY:主键约束,保证该字段的值具有唯一性,并且非空<br>UNIQUE:唯一约束,用于保证该字段的值具有唯一性,可以为空<br>CHECK:检查约束【mysql中不支持】<br>FOREIGN KEY:外键,用于限制两个表的关系,用于保证该字段的值必须来自于主表的关联列的值在从表添加外键约束,用于引用主表中某列的值</p><h3 id="13-1-创建表时添加列级约束"><a href="#13-1-创建表时添加列级约束" class="headerlink" title="13.1 创建表时添加列级约束"></a>13.1 创建表时添加列级约束</h3><p>直接在字段名和类型后面追加 约束类型即可。<br>只支持:默认、非空、主键、唯一</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">USE students;</span><br><span class="line">DROP TABLE stuinfo;</span><br><span class="line">CREATE TABLE stuinfo(</span><br><span class="line">id INT PRIMARY KEY,#主键</span><br><span class="line">stuName VARCHAR(20) NOT NULL UNIQUE,#非空</span><br><span class="line">gender CHAR(1) CHECK(gender='男' OR gender ='女'),#检查</span><br><span class="line">seat INT UNIQUE,#唯一</span><br><span class="line">age INT DEFAULT 18,#默认约束</span><br><span class="line">majorId INT REFERENCES major(id)#外键</span><br><span class="line">);</span><br></pre></td></tr></table></figure><h3 id="13-2-创建表时添加表级约束"><a href="#13-2-创建表时添加表级约束" class="headerlink" title="13.2 创建表时添加表级约束"></a>13.2 创建表时添加表级约束</h3><p>语法:在各个字段的最下面<br> 【constraint 约束名】 约束类型(字段名) </p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">DROP TABLE IF EXISTS stuinfo;</span><br><span class="line">CREATE TABLE stuinfo(</span><br><span class="line">id INT,</span><br><span class="line">stuname VARCHAR(20),</span><br><span class="line">gender CHAR(1),</span><br><span class="line">seat INT,</span><br><span class="line">age INT,</span><br><span class="line">majorid INT,</span><br><span class="line"></span><br><span class="line">CONSTRAINT pk PRIMARY KEY(id),#主键</span><br><span class="line">CONSTRAINT uq UNIQUE(seat),#唯一键</span><br><span class="line">CONSTRAINT ck CHECK(gender ='男' OR gender = '女'),#检查</span><br><span class="line">CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)#外键</span><br><span class="line"></span><br><span class="line">);</span><br><span class="line"></span><br><span class="line">#通用的写法:★</span><br><span class="line"></span><br><span class="line">CREATE TABLE IF NOT EXISTS stuinfo(</span><br><span class="line">id INT PRIMARY KEY,</span><br><span class="line">stuname VARCHAR(20),</span><br><span class="line">sex CHAR(1),</span><br><span class="line">age INT DEFAULT 18,</span><br><span class="line">seat INT UNIQUE,</span><br><span class="line">majorid INT,</span><br><span class="line">CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id)</span><br><span class="line"></span><br><span class="line">);</span><br></pre></td></tr></table></figure><h3 id="13-3-主键和唯一的区别"><a href="#13-3-主键和唯一的区别" class="headerlink" title="13.3 主键和唯一的区别"></a>13.3 主键和唯一的区别</h3><h3 id="13-4-外键的特点"><a href="#13-4-外键的特点" class="headerlink" title="13.4 外键的特点"></a>13.4 外键的特点</h3><h3 id="13-5-修改表时添加约束"><a href="#13-5-修改表时添加约束" class="headerlink" title="13.5 修改表时添加约束"></a>13.5 修改表时添加约束</h3><p>1、添加列级约束<br>alter table 表名 modify column 字段名 字段类型 新约束;<br>2、添加表级约束<br>alter table 表名 add 【constraint 约束名】 约束类型(字段名) 【外键的引用】;</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">#1.添加非空约束</span><br><span class="line">ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NOT NULL;</span><br><span class="line">#2.添加默认约束</span><br><span class="line">ALTER TABLE stuinfo MODIFY COLUMN age INT DEFAULT 18;</span><br><span class="line">#3.添加主键</span><br><span class="line">#①列级约束</span><br><span class="line">ALTER TABLE stuinfo MODIFY COLUMN id INT PRIMARY KEY;</span><br><span class="line">#②表级约束</span><br><span class="line">ALTER TABLE stuinfo ADD PRIMARY KEY(id);</span><br><span class="line">#4.添加唯一</span><br><span class="line">#①列级约束</span><br><span class="line">ALTER TABLE stuinfo MODIFY COLUMN seat INT UNIQUE;</span><br><span class="line">#②表级约束</span><br><span class="line">ALTER TABLE stuinfo ADD UNIQUE(seat);</span><br><span class="line">#5.添加外键</span><br><span class="line">ALTER TABLE stuinfo ADD CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id);</span><br></pre></td></tr></table></figure><h3 id="13-6-修改表时去掉约束"><a href="#13-6-修改表时去掉约束" class="headerlink" title="13.6 修改表时去掉约束"></a>13.6 修改表时去掉约束</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">#1.删除非空约束</span><br><span class="line">ALTER TABLE stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL;</span><br><span class="line">#2.删除默认约束</span><br><span class="line">ALTER TABLE stuinfo MODIFY COLUMN age INT ;</span><br><span class="line">#3.删除主键</span><br><span class="line">ALTER TABLE stuinfo DROP PRIMARY KEY;</span><br><span class="line">#4.删除唯一</span><br><span class="line">ALTER TABLE stuinfo DROP INDEX seat;</span><br><span class="line">#5.删除外键</span><br><span class="line">ALTER TABLE stuinfo DROP FOREIGN KEY fk_stuinfo_major;</span><br></pre></td></tr></table></figure><h2 id="14-标识列"><a href="#14-标识列" class="headerlink" title="14. 标识列"></a>14. 标识列</h2><p>又称为自增长列<br>含义:可以不用手动的插入值,系统提供默认的序列值</p><p>特点:<br>1、标识列必须和主键搭配吗?不一定,但要求是一个key<br>2、一个表可以有几个标识列?至多一个!<br>3、标识列的类型只能是数值型<br>4、标识列可以通过 SET auto_increment_increment=3;设置步长<br>可以通过 手动插入值,设置起始值</p><h2 id="15-事务介绍"><a href="#15-事务介绍" class="headerlink" title="15. 事务介绍"></a>15. 事务介绍</h2><p>Transaction Control Language 事务控制语言<br>一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行。<br>事务的特性:<br>ACID<br>原子性:一个事务不可再分割,要么都执行要么都不执行<br>一致性:一个事务执行会使数据从一个一致状态切换到另外一个一致状态<br>隔离性:一个事务的执行不受其他事务的干扰<br>持久性:一个事务一旦提交,则会永久的改变数据库的数据.</p><p>事务的创建<br>隐式事务:事务没有明显的开启和结束的标记<br>比如insert、update、delete语句</p><p>delete from 表 where id =1;</p><p>显式事务:事务具有明显的开启和结束的标记<br>前提:必须先设置自动提交功能为禁用</p><p>set autocommit=0;</p><p>步骤1:开启事务<br>set autocommit=0;<br>start transaction;可选的<br>步骤2:编写事务中的sql语句(select insert update delete)<br>语句1;<br>语句2;<br>…</p><p>步骤3:结束事务<br>commit;提交事务<br>rollback;回滚事务</p><p>savepoint 节点名;设置保存点</p><h3 id="15-1-事务的隔离"><a href="#15-1-事务的隔离" class="headerlink" title="15.1 事务的隔离"></a>15.1 事务的隔离</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gh9ymnhf8fj30h206gaal.jpg" alt=""> </p><h3 id="15-2-回滚"><a href="#15-2-回滚" class="headerlink" title="15.2 回滚"></a>15.2 回滚</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line">#1.演示事务的使用步骤</span><br><span class="line"></span><br><span class="line">#开启事务</span><br><span class="line">SET autocommit=0;</span><br><span class="line">START TRANSACTION;</span><br><span class="line">#编写一组事务的语句</span><br><span class="line">UPDATE account SET balance = 1000 WHERE username='张无忌';</span><br><span class="line">UPDATE account SET balance = 1000 WHERE username='赵敏';</span><br><span class="line"></span><br><span class="line">#结束事务</span><br><span class="line">ROLLBACK;</span><br><span class="line">#commit;</span><br><span class="line"></span><br><span class="line">SELECT * FROM account;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">#2.演示事务对于delete和truncate的处理的区别</span><br><span class="line"></span><br><span class="line">SET autocommit=0;</span><br><span class="line">START TRANSACTION;</span><br><span class="line"></span><br><span class="line">DELETE FROM account;</span><br><span class="line">ROLLBACK;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">#3.演示savepoint 的使用</span><br><span class="line">SET autocommit=0;</span><br><span class="line">START TRANSACTION;</span><br><span class="line">DELETE FROM account WHERE id=25;</span><br><span class="line">SAVEPOINT a;#设置保存点</span><br><span class="line">DELETE FROM account WHERE id=28;</span><br><span class="line">ROLLBACK TO a;#回滚到保存点</span><br></pre></td></tr></table></figure><h2 id="16-视图介绍"><a href="#16-视图介绍" class="headerlink" title="16. 视图介绍"></a>16. 视图介绍</h2><p>含义:虚拟表,和普通的表一样使用</p><h3 id="16-1-视图创建"><a href="#16-1-视图创建" class="headerlink" title="16.1 视图创建"></a>16.1 视图创建</h3><p>语法:<br>create view 视图名<br>as<br>查询语句;</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">CREATE VIEW myv1</span><br><span class="line">AS</span><br><span class="line">SELECT last_name,department_name,job_title</span><br><span class="line">FROM employees e</span><br><span class="line">JOIN departments d ON e.department_id = d.department_id</span><br><span class="line">JOIN jobs j ON j.job_id = e.job_id;</span><br></pre></td></tr></table></figure><h3 id="16-2-视图修改"><a href="#16-2-视图修改" class="headerlink" title="16.2 视图修改"></a>16.2 视图修改</h3><p>方式一:<br>create or replace view 视图名<br>as<br>查询语句;</p><p>方式二:<br>语法:<br>alter view 视图名<br>as<br>查询语句;</p><h3 id="16-3-视图查看和删除"><a href="#16-3-视图查看和删除" class="headerlink" title="16.3 视图查看和删除"></a>16.3 视图查看和删除</h3><p>删除视图:语法:drop view 视图名,视图名,…;<br>查看视图:DESC myv3;SHOW CREATE VIEW myv3;</p><h3 id="16-4-视图更新"><a href="#16-4-视图更新" class="headerlink" title="16.4 视图更新"></a>16.4 视图更新</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">CREATE OR REPLACE VIEW myv1</span><br><span class="line">AS</span><br><span class="line">SELECT last_name,email,salary*12*(1+IFNULL(commission_pct,0)) "annual salary"</span><br><span class="line">FROM employees;</span><br><span class="line"></span><br><span class="line">CREATE OR REPLACE VIEW myv1</span><br><span class="line">AS</span><br><span class="line">SELECT last_name,email</span><br><span class="line">FROM employees;</span><br></pre></td></tr></table></figure><p>具备以下特点的视图不允许更新:<br>1.含以下关键字的sql语句:分组函数、distinct、group by、having、union或者union all<br>2.常量视图<br>3.Select中包含子查询<br>4.join<br>5.from一个不能更新的视图<br>6.where子句的子查询引用了from子句中的表</p><h2 id="17-函数和存储过程"><a href="#17-函数和存储过程" class="headerlink" title="17. 函数和存储过程"></a>17. 函数和存储过程</h2><p>说明:变量由系统定义,不是用户定义,属于服务器层面<br>注意:全局变量需要添加global关键字,会话变量需要添加session关键字,如果不写,默认会话级别<br>使用步骤:<br>1、查看所有系统变量<br>show global|【session】variables;<br>2、查看满足条件的部分系统变量<br>show global|【session】 variables like ‘%char%’;<br>3、查看指定的系统变量的值<br>select @@global|【session】系统变量名;<br>4、为某个系统变量赋值<br>方式一:<br>set global|【session】系统变量名=值;<br>方式二:<br>set @@global|【session】系统变量名=值;</p><h3 id="17-1-全局变量"><a href="#17-1-全局变量" class="headerlink" title="17.1 全局变量"></a>17.1 全局变量</h3><p>作用域:针对于所有会话(连接)有效,但不能跨重启</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">#①查看所有全局变量</span><br><span class="line">SHOW GLOBAL VARIABLES;</span><br><span class="line">#②查看满足条件的部分系统变量</span><br><span class="line">SHOW GLOBAL VARIABLES LIKE '%char%';</span><br><span class="line">#③查看指定的系统变量的值</span><br><span class="line">SELECT @@global.autocommit;</span><br><span class="line">#④为某个系统变量赋值</span><br><span class="line">SET @@global.autocommit=0;</span><br><span class="line">SET GLOBAL autocommit=0;</span><br></pre></td></tr></table></figure><h3 id="17-2-会话变量"><a href="#17-2-会话变量" class="headerlink" title="17.2 会话变量"></a>17.2 会话变量</h3><p>作用域:针对于当前会话(连接)有效</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">#①查看所有会话变量</span><br><span class="line">SHOW SESSION VARIABLES;</span><br><span class="line">#②查看满足条件的部分会话变量</span><br><span class="line">SHOW SESSION VARIABLES LIKE '%char%';</span><br><span class="line">#③查看指定的会话变量的值</span><br><span class="line">SELECT @@autocommit;</span><br><span class="line">SELECT @@session.tx_isolation;</span><br><span class="line">#④为某个会话变量赋值</span><br><span class="line">SET @@session.tx_isolation='read-uncommitted';</span><br><span class="line">SET SESSION tx_isolation='read-committed';</span><br></pre></td></tr></table></figure><h3 id="17-3-自定义变量-用户变量"><a href="#17-3-自定义变量-用户变量" class="headerlink" title="17.3 自定义变量-用户变量"></a>17.3 自定义变量-用户变量</h3><p>说明:变量由用户自定义,而不是系统提供的<br>使用步骤:<br>1、声明<br>2、赋值<br>3、使用(查看、比较、运算等)<br>作用域:针对于当前会话(连接)有效,作用域同于会话变量</p><p>赋值操作符:=或:=<br>①声明并初始化<br>SET @变量名=值;<br>SET @变量名:=值;<br>SELECT @变量名:=值;</p><p>②赋值(更新变量的值)<br>方式一:<br> SET @变量名=值;<br> SET @变量名:=值;<br> SELECT @变量名:=值;<br>方式二:<br> SELECT 字段 INTO @变量名<br> FROM 表;<br>③使用(查看变量的值)<br>SELECT @变量名;</p><h3 id="17-4-自定义变量-局部变量"><a href="#17-4-自定义变量-局部变量" class="headerlink" title="17.4 自定义变量-局部变量"></a>17.4 自定义变量-局部变量</h3><p>作用域:仅仅在定义它的begin end块中有效<br>应用在 begin end中的第一句话</p><p>①声明<br>DECLARE 变量名 类型;<br>DECLARE 变量名 类型 【DEFAULT 值】;</p><p>②赋值(更新变量的值)<br>方式一:<br> SET 局部变量名=值;<br> SET 局部变量名:=值;<br> SELECT 局部变量名:=值;<br>方式二:<br> SELECT 字段 INTO 具备变量名<br> FROM 表;<br>③使用(查看变量的值)<br>SELECT 局部变量名;</p><p>案例:声明两个变量,求和并打印</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">#用户变量</span><br><span class="line">SET @m=1;</span><br><span class="line">SET @n=1;</span><br><span class="line">SET @sum=@m+@n;</span><br><span class="line">SELECT @sum;</span><br><span class="line"></span><br><span class="line">#局部变量</span><br><span class="line">DECLARE m INT DEFAULT 1;</span><br><span class="line">DECLARE n INT DEFAULT 1;</span><br><span class="line">DECLARE SUM INT;</span><br><span class="line">SET SUM=m+n;</span><br><span class="line">SELECT SUM;</span><br></pre></td></tr></table></figure><h3 id="17-5-存储过程介绍"><a href="#17-5-存储过程介绍" class="headerlink" title="17.5 存储过程介绍"></a>17.5 存储过程介绍</h3><p>含义:一组预先编译好的SQL语句的集合,理解成批处理语句<br>1、提高代码的重用性<br>2、简化操作<br>3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率</p><h3 id="17-6-存储过程语法"><a href="#17-6-存储过程语法" class="headerlink" title="17.6 存储过程语法"></a>17.6 存储过程语法</h3><ol><li>创建语法 <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">CREATE PROCEDURE 存储过程名(参数列表)</span><br><span class="line">BEGIN</span><br><span class="line"></span><br><span class="line">存储过程体(一组合法的SQL语句)</span><br><span class="line">END</span><br><span class="line"> ⚠️</span><br><span class="line"> 1.参数列表包含三部分: in stuname varchar(20)</span><br><span class="line"> 参数模式:</span><br><span class="line"> in:该参数可以作为输入,也就是该参数需要调用方传入值</span><br><span class="line"> out:该参数可以作为输出,也就是该参数可以作为返回值</span><br><span class="line"> inout:该参数既可以作为输入又可以作为输出,也就是该参数既需要传入值,又 可以返回值</span><br><span class="line"> 参数名:</span><br><span class="line"> 参数类型:</span><br><span class="line"> 2.如果存储过程体仅仅只有一句话,begin end可以省略</span><br><span class="line"> 3.存储过程体中的每条sql语句的结尾要求必须加分号</span><br><span class="line"> 4.存储过程的结尾可以使用 delimiter 重新设置</span><br><span class="line"> 语法:</span><br><span class="line"> delimiter 结束标记</span><br><span class="line"> 案例:</span><br><span class="line"> delimiter $</span><br></pre></td></tr></table></figure></li><li>调用方法<br> CALL 存储过程名(实参列表);</li></ol><h3 id="17-7-空参的存储过程"><a href="#17-7-空参的存储过程" class="headerlink" title="17.7 空参的存储过程"></a>17.7 空参的存储过程</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"># 定义存储过程</span><br><span class="line">delimiter $</span><br><span class="line">create PROCEDURE myp2()</span><br><span class="line">begin</span><br><span class="line">insert into admin(username,`password`) values('测试','12345');</span><br><span class="line">end $</span><br><span class="line"></span><br><span class="line">call myp2()$</span><br></pre></td></tr></table></figure><h3 id="17-8-带in模式的存储过程"><a href="#17-8-带in模式的存储过程" class="headerlink" title="17.8 带in模式的存储过程"></a>17.8 带in模式的存储过程</h3><p>案例1:创建存储过程实现 根据女神名,查询对应的男神信息</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">create PROCEDURE myp3(in beatyName VARCHAR(20))</span><br><span class="line">begin</span><br><span class="line">select be.*,bo.*</span><br><span class="line">from beauty be</span><br><span class="line">left join boys bo on be.boyfriend_id = bo.id</span><br><span class="line">where be.name = beatyName;</span><br><span class="line">end</span><br><span class="line"></span><br><span class="line">call myp3('柳岩')</span><br></pre></td></tr></table></figure><p>案例2 :创建存储过程实现,用户是否登录成功</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">create PROCEDURE myp4(in username VARCHAR(20),in password VARCHAR(20))</span><br><span class="line">begin</span><br><span class="line">DECLARE result VARCHAR(20) DEFAULT ''; # 声明并初始化</span><br><span class="line">select count(*) into result # 赋值</span><br><span class="line">from admin</span><br><span class="line">where admin.username = username</span><br><span class="line">and admin.password = password;</span><br><span class="line"></span><br><span class="line">select result; # 使用</span><br><span class="line">end</span><br><span class="line"></span><br><span class="line">call myp4('ceshi','123')</span><br></pre></td></tr></table></figure><h3 id="17-9-带out模式的存储过程"><a href="#17-9-带out模式的存储过程" class="headerlink" title="17.9 带out模式的存储过程"></a>17.9 带out模式的存储过程</h3><p>案例1:根据输入的女神名,返回对应的男神名</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">CREATE PROCEDURE myp6(IN beautyName VARCHAR(20),OUT boyName VARCHAR(20))</span><br><span class="line">BEGIN</span><br><span class="line">SELECT bo.boyname INTO boyname</span><br><span class="line">FROM boys bo</span><br><span class="line">RIGHT JOIN</span><br><span class="line">beauty b ON b.boyfriend_id = bo.id</span><br><span class="line">WHERE b.name=beautyName ;</span><br><span class="line"></span><br><span class="line">END $</span><br></pre></td></tr></table></figure><p>案例2:根据输入的女神名,返回对应的男神名和魅力值</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">create PROCEDURE myp8(in beatyName varchar(20),out boyName varchar(20),out usercp int)</span><br><span class="line">BEGIN</span><br><span class="line">select bo.boyName ,bo.userCP into boyName ,usercp</span><br><span class="line">from boys bo</span><br><span class="line">inner join beauty b on bo.id = b.boyfriend_id</span><br><span class="line">where b.name = beatyName;</span><br><span class="line">END</span><br><span class="line"></span><br><span class="line">call myp8('小昭',@bName,@cp)</span><br><span class="line"></span><br><span class="line">select @bName,@cp</span><br></pre></td></tr></table></figure><h3 id="17-10-带inout模式的存储过程"><a href="#17-10-带inout模式的存储过程" class="headerlink" title="17.10 带inout模式的存储过程"></a>17.10 带inout模式的存储过程</h3><p>案例1:传入a和b两个值,最终a和b都翻倍并返回</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">create PROCEDURE myp9(inout a int,inout b int)</span><br><span class="line">BEGIN</span><br><span class="line">set a = a * 2;</span><br><span class="line">set b =b * 2;</span><br><span class="line">END</span><br><span class="line"># 调用</span><br><span class="line">set @n=8;</span><br><span class="line">set @m=10;</span><br><span class="line">call myp9(@n,@m);</span><br><span class="line">select @m,@n</span><br></pre></td></tr></table></figure><h3 id="17-11-存储过程的删除"><a href="#17-11-存储过程的删除" class="headerlink" title="17.11 存储过程的删除"></a>17.11 存储过程的删除</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">语法:drop procedure 存储过程名</span><br><span class="line">DROP PROCEDURE p1;</span><br></pre></td></tr></table></figure><h3 id="17-12-存储过程查看"><a href="#17-12-存储过程查看" class="headerlink" title="17.12 存储过程查看"></a>17.12 存储过程查看</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">查看存储过程的信息</span><br><span class="line">SHOW CREATE PROCEDURE myp2;</span><br></pre></td></tr></table></figure><h2 id="18-函数的介绍"><a href="#18-函数的介绍" class="headerlink" title="18. 函数的介绍"></a>18. 函数的介绍</h2><p>含义:一组预先编译好的SQL语句的集合,理解成批处理语句<br>1、提高代码的重用性<br>2、简化操作<br>3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率</p><p>区别:</p><p>存储过程:可以有0个返回,也可以有多个返回,适合做批量插入、批量更新<br>函数:有且仅有1 个返回,适合做处理数据后返回一个结果</p><h3 id="18-1-函数的创建和调用语法"><a href="#18-1-函数的创建和调用语法" class="headerlink" title="18.1 函数的创建和调用语法"></a>18.1 函数的创建和调用语法</h3><ol><li><p>创建语法</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">CREATE FUNCTION 函数名(参数列表) RETURNS 返回类型</span><br><span class="line">BEGIN</span><br><span class="line">函数体</span><br><span class="line">END</span><br><span class="line"></span><br><span class="line">⚠️</span><br><span class="line">1.参数列表包括两部分:参数名和参数类型</span><br><span class="line">2.函数体:肯定会有return语句,如果没有会报错</span><br><span class="line"> 如果return语句没有放在函数体的最后也不报错,但不建议</span><br><span class="line">3.函数体中仅有一句话,则可以省略begin end</span><br><span class="line">4.使用 delimiter语句设置结束标记</span><br></pre></td></tr></table></figure></li><li><p>调用语法:SELECT 函数名(参数列表)</p></li><li><p>案例</p><ul><li><p>无参有返回</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"> #案例:返回公司的员工个数</span><br><span class="line"> create function myf1() returns int</span><br><span class="line">BEGIN</span><br><span class="line">DECLARE c int default 0;# 定义变量</span><br><span class="line">select count(*) into c# 为变量赋值</span><br><span class="line">from employees;</span><br><span class="line">return c;</span><br><span class="line">END</span><br><span class="line">select myf1();</span><br></pre></td></tr></table></figure><ul><li><p>有参有返回</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"> #案例1:根据员工名,返回它的工资</span><br><span class="line"> create function myf2(empName varchar(20)) returns double</span><br><span class="line">BEGIN</span><br><span class="line">set @sal=0; # 定义了一个用户变量</span><br><span class="line">select salary into @sal from employees where last_name = empName;</span><br><span class="line">return @sal;</span><br><span class="line">END</span><br><span class="line">select myf2('John');</span><br></pre></td></tr></table></figure></li></ul></li></ul></li></ol><h3 id="18-2-函数的查看和删除"><a href="#18-2-函数的查看和删除" class="headerlink" title="18.2 函数的查看和删除"></a>18.2 函数的查看和删除</h3><p>SHOW CREATE FUNCTION myf3;<br>DROP FUNCTION myf3;</p><h2 id="19-流程控制结构介绍"><a href="#19-流程控制结构介绍" class="headerlink" title="19. 流程控制结构介绍"></a>19. 流程控制结构介绍</h2><p>顺序结构:程序从上往下依次执行<br>分支结构:程序从两条或多条路径中选择一条去执行<br>循环结构:程序在满足一定条件的基础上,重复执行一段代码</p><h3 id="19-1-分支结构—if函数"><a href="#19-1-分支结构—if函数" class="headerlink" title="19.1 分支结构—if函数"></a>19.1 分支结构—if函数</h3><p>语法:if(条件,值1,值2)<br>功能:实现双分支<br>应用在begin end中或外面<br>执行顺序:如果表达式的条件成立,则if返回值1,否则返回值2</p><h3 id="19-2-分支结构—case结构"><a href="#19-2-分支结构—case结构" class="headerlink" title="19.2 分支结构—case结构"></a>19.2 分支结构—case结构</h3><p>语法:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">情况1:类似于switch语句,一般用于实现等值判断</span><br><span class="line">case 变量或表达式</span><br><span class="line">when 值1 then 语句1;</span><br><span class="line">when 值2 then 语句2;</span><br><span class="line">...</span><br><span class="line">else 语句n;</span><br><span class="line">end </span><br><span class="line"></span><br><span class="line">情况2:类似于多重if语句,一般用于实现区间判断</span><br><span class="line">case </span><br><span class="line">when 条件1 then 语句1;</span><br><span class="line">when 条件2 then 语句2;</span><br><span class="line">...</span><br><span class="line">else 语句n;</span><br><span class="line">end</span><br></pre></td></tr></table></figure><p>特点:应用在begin end 中或外面</p><ul><li>可以作为表达式,嵌套在其他语句中使用,可以放在任何地方,begin end中或外面</li><li>可以作为独立的语句去使用,只能放在begin end中</li><li>如果when中的值满足或条件成立,则执行对应的then后面的语句,并且结束case</li><li>如果都不满足则执行else中的语句或值</li><li>else可以省略,如果else省略了,并且所有where条件都不满足,则返回null</li></ul><p>案例:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">#案例1:创建函数,实现传入成绩,如果成绩>90,返回A,如果成绩>80,返回B,如果成绩>60,返回C,否则返回D</span><br><span class="line">create PROCEDURE test_case(in score int)</span><br><span class="line">BEGIN</span><br><span class="line">case </span><br><span class="line">when score >= 90 then SELECT 'A';</span><br><span class="line">when score >=80 then select 'B';</span><br><span class="line">when score >=70 then select 'C';</span><br><span class="line">else select 'D';</span><br><span class="line">end case;</span><br><span class="line">END</span><br><span class="line"></span><br><span class="line">call test_case(75)</span><br></pre></td></tr></table></figure><h3 id="19-3-分支结构—if结构"><a href="#19-3-分支结构—if结构" class="headerlink" title="19.3 分支结构—if结构"></a>19.3 分支结构—if结构</h3><p>语法:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">语法:</span><br><span class="line">if 条件1 then 语句1;</span><br><span class="line">elseif 条件2 then 语句2;</span><br><span class="line">....</span><br><span class="line">else 语句n;</span><br><span class="line">end if;</span><br><span class="line">功能:类似于多重if</span><br><span class="line"></span><br><span class="line">只能应用在begin end 中</span><br></pre></td></tr></table></figure><h3 id="19-4循环结构的介绍"><a href="#19-4循环结构的介绍" class="headerlink" title="19.4循环结构的介绍"></a>19.4循环结构的介绍</h3><p>分类:</p><ul><li>while:</li><li>loop:</li><li>repeat:</li></ul><p>循环控制:</p><ul><li>iterate类似于 continue,继续,结束本次循环,继续下一次</li><li>leave 类似于 break,跳出,结束当前所在的循环</li></ul><p>语法:</p><ul><li><p>while </p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"> 【标签:】while 循环条件 do</span><br><span class="line">循环体;</span><br><span class="line">end while【标签】;</span><br><span class="line">联想:</span><br><span class="line">while(循环条件){</span><br><span class="line">循环体;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>loop</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">标签:】loop</span><br><span class="line">循环体;</span><br><span class="line">end loop 【标签】;</span><br><span class="line"># 可以用来模拟简单的死循环</span><br></pre></td></tr></table></figure></li><li><p>repeat</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">【标签:】repeat</span><br><span class="line">循环体;</span><br><span class="line">until 结束循环的条件</span><br><span class="line">end repeat 【标签】;</span><br></pre></td></tr></table></figure><h3 id="19-5-循环结构演示"><a href="#19-5-循环结构演示" class="headerlink" title="19.5 循环结构演示"></a>19.5 循环结构演示</h3><p>案例:批量插入,根据次数插入到admin表中多条记录</p></li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">create PROCEDURE pro_while1(in insertcount int)</span><br><span class="line">BEGIN</span><br><span class="line">DECLARE i int DEFAULT 1;</span><br><span class="line">while i <= insertcount do</span><br><span class="line">insert into admin(username,password) values(CONCAT('ceshi',i),'6666');</span><br><span class="line">set i = i + 1;</span><br><span class="line">END WHILE;</span><br><span class="line">END</span><br><span class="line"></span><br><span class="line">call pro_while1(10);</span><br></pre></td></tr></table></figure><p>案例2:批量插入,根据次数插入到admin表中多条记录,如果次数>20则停止(添加leave语句)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">create PROCEDURE pro_while2(in insertcount int)</span><br><span class="line">BEGIN</span><br><span class="line">DECLARE i int DEFAULT 1;</span><br><span class="line">a:while i <= insertcount do</span><br><span class="line">insert into admin(username,password) values(CONCAT('xiaohua',i),'6666');</span><br><span class="line">if i>=20 then leave a;</span><br><span class="line">end if;</span><br><span class="line">set i = i + 1;</span><br><span class="line">END WHILE a;</span><br><span class="line">END</span><br><span class="line"></span><br><span class="line">call pro_while2(30);</span><br></pre></td></tr></table></figure><p>案例:批量插入,根据次数插入到admin表中多条记录,只插入偶数次(添加iterate语句)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">TRUNCATE TABLE admin$</span><br><span class="line">DROP PROCEDURE test_while1$</span><br><span class="line">CREATE PROCEDURE test_while1(IN insertCount INT)</span><br><span class="line">BEGIN</span><br><span class="line">DECLARE i INT DEFAULT 0;</span><br><span class="line">a:WHILE i<=insertCount DO</span><br><span class="line">SET i=i+1;</span><br><span class="line">IF MOD(i,2)!=0 THEN ITERATE a;</span><br><span class="line">END IF;</span><br><span class="line"></span><br><span class="line">INSERT INTO admin(username,`password`) VALUES(CONCAT('xiaohua',i),'0000');</span><br><span class="line"></span><br><span class="line">END WHILE a;</span><br><span class="line">END $</span><br><span class="line">CALL test_while1(100)$</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h1 id="MySQL学习笔记二"><a href="#MySQL学习笔记二" class="headerlink" title="MySQL学习笔记二"></a>MySQL学习笔记二</h1><h2 id="1-分组查询"><a href="#1-分组查询" class="
</summary>
</entry>
<entry>
<title>MySQL高级部分学习一</title>
<link href="http://lwblog.xyz/posts/f2612c14.html"/>
<id>http://lwblog.xyz/posts/f2612c14.html</id>
<published>2020-08-17T01:04:14.000Z</published>
<updated>2020-08-17T01:07:00.873Z</updated>
<content type="html"><![CDATA[<h1 id="MySQL高级部分学习一"><a href="#MySQL高级部分学习一" class="headerlink" title="MySQL高级部分学习一"></a>MySQL高级部分学习一</h1><h2 id="1-mysql的架构介绍"><a href="#1-mysql的架构介绍" class="headerlink" title="1. mysql的架构介绍"></a>1. mysql的架构介绍</h2><h3 id="1-1-mysql简介"><a href="#1-1-mysql简介" class="headerlink" title="1.1 mysql简介"></a>1.1 mysql简介</h3><h3 id="1-2-mysqlLinux版的安装"><a href="#1-2-mysqlLinux版的安装" class="headerlink" title="1.2 mysqlLinux版的安装"></a>1.2 mysqlLinux版的安装</h3><ol><li>检查当前系统是否安装过mysql:<code>rpm -qa|grep -i mysql</code></li><li>查看mysql安装时创建的mysql用户和mysql用户组:<code>cat /etc/password|grep mysql</code>、<code>cat /etc/group|grep mysql</code></li><li>mysql服务的启动和停止:<code>service mysql start</code>,查看是否启动成功:<code>ps -ef|grep mysql</code></li><li>root密码设置和设置开机随机启动:<code>chkconfig mysql on</code></li><li>mysql的安装位置:<code>/var/lib/mysql</code></li></ol><h3 id="1-3-MySQL的配置文件-my-cnf"><a href="#1-3-MySQL的配置文件-my-cnf" class="headerlink" title="1.3 MySQL的配置文件:my.cnf"></a>1.3 MySQL的配置文件:my.cnf</h3><p><del>1. client:客户端的配置</del></p><h3 id="1-4-Mysql逻辑架构介绍"><a href="#1-4-Mysql逻辑架构介绍" class="headerlink" title="1.4 Mysql逻辑架构介绍"></a>1.4 Mysql逻辑架构介绍</h3><h3 id="1-5-mysql存储引擎"><a href="#1-5-mysql存储引擎" class="headerlink" title="1.5 mysql存储引擎"></a>1.5 mysql存储引擎</h3><ol><li>查看mysql提供的存储引擎:<code>show engines;</code></li><li>查看mysql抢天默认的存储引擎:<code>show variables like '%storage_engine%';</code></li></ol><h2 id="2-索引优化分析"><a href="#2-索引优化分析" class="headerlink" title="2. 索引优化分析"></a>2. 索引优化分析</h2><h3 id="2-1-SQL性能下降原因"><a href="#2-1-SQL性能下降原因" class="headerlink" title="2.1 SQL性能下降原因"></a>2.1 SQL性能下降原因</h3><ol><li>索引失效</li><li>关联查询太多join(设计缺陷或不得已的需求)</li><li>服务器调优及各个参数设置(缓冲、线程数等)</li></ol><h3 id="2-2-SQL执行加载顺序"><a href="#2-2-SQL执行加载顺序" class="headerlink" title="2.2 SQL执行加载顺序"></a>2.2 SQL执行加载顺序</h3><p>from–on–join–where–group by–having–select–distinct–order by –limit<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghgxfq06gqj30i60ecwh3.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghgxh4irx6j312o0aw419.jpg" alt=""></p><h3 id="2-3-七种JOIN理论"><a href="#2-3-七种JOIN理论" class="headerlink" title="2.3 七种JOIN理论"></a>2.3 七种JOIN理论</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghgxiygg3sj30ze0haqew.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghgxqhppfbj30zm0aw477.jpg" alt=""></p><h3 id="2-4-七种JOIN的SQL编写"><a href="#2-4-七种JOIN的SQL编写" class="headerlink" title="2.4 七种JOIN的SQL编写"></a>2.4 七种JOIN的SQL编写</h3><h3 id="2-5-索引是什么"><a href="#2-5-索引是什么" class="headerlink" title="2.5 索引是什么"></a>2.5 索引是什么</h3><p>索引(index)是帮助mysql高效获取数据的数据结构。可以理解为<strong><em>“排好顺序快速查找数据结构”</em></strong></p><h3 id="2-6-索引优势劣势"><a href="#2-6-索引优势劣势" class="headerlink" title="2.6 索引优势劣势"></a>2.6 索引优势劣势</h3><p>优势:</p><ol><li>提高检索效率,降低数据库的IO成本</li><li>通过索引对数据进行排序,降低数据排序的成本,降低了COU的小号</li></ol><p>劣势:</p><ol><li>实际上索引也是一张表,该表保存了主键与索引字段,并且指向实体表记录,所以索引也是要占用空间的</li><li>虽然索引大大提高了查询速度,但是却会降低更新表的速度</li><li>都会调整因为更新所带来的键值变化后的索引信息</li></ol><h3 id="2-7-索引分类和建索引命令语句"><a href="#2-7-索引分类和建索引命令语句" class="headerlink" title="2.7 索引分类和建索引命令语句"></a>2.7 索引分类和建索引命令语句</h3><p>分类</p><ol><li>单值索引:即一个索引只包含单个列,一个表可以有多个单列索引</li><li>唯一索引:索引列的值唯一,但允许有空值</li><li>复合索引:即一个索引包含多个列</li></ol><p>语法</p><ol><li>创建<code>create [unique] index indexname on mytable(columnname(length))``alter mytable add [unique] index [indexname] on (columnname(length))</code></li><li>删除:<code>drop index [indexname] on mytable</code></li><li>查看:<code>show index from table_name\G</code></li></ol><h3 id="2-8-索引结构与检索原理"><a href="#2-8-索引结构与检索原理" class="headerlink" title="2.8 索引结构与检索原理"></a>2.8 索引结构与检索原理</h3><p>BTree索引、Hash索引、full-text全文索引、R-Tree索引</p><h3 id="2-9-哪些情况适合建索引"><a href="#2-9-哪些情况适合建索引" class="headerlink" title="2.9 哪些情况适合建索引"></a>2.9 哪些情况适合建索引</h3><ol><li>主键自动建立唯一索引</li><li>频繁作为查询条件的字段应该创建索引</li><li>查询中与其他表关联的字段,外键关系建立索引</li><li>频繁更新的字段不适合创建索引,因为每次更新不单单是更新了记录还会更新索引</li><li>where条件里用不到的字段不创建索引</li><li>单键/组合索引的选择问题,who(在高并发下倾向创建组合索引)</li><li>查询中排序的字段,排序字段若通过索引去访问将大大提高排序的速度</li><li>查询中统计或者分组的字段</li></ol><h3 id="2-10-哪些情况不适合建索引"><a href="#2-10-哪些情况不适合建索引" class="headerlink" title="2.10 哪些情况不适合建索引"></a>2.10 哪些情况不适合建索引</h3><ol><li>表记录太少</li><li>经常增删改的表</li><li>数据重复且分布平均的表字段,因此应该只为最经常查询和最经常排序的数据建立索引。⚠️如果某个数据列包含许多重复内容,为他建立索引就没有太大的实际效果</li></ol><h3 id="2-11-性能分析"><a href="#2-11-性能分析" class="headerlink" title="2.11 性能分析"></a>2.11 性能分析</h3><h4 id="2-11-1-性能分析前提知识"><a href="#2-11-1-性能分析前提知识" class="headerlink" title="2.11.1 性能分析前提知识"></a>2.11.1 性能分析前提知识</h4><p>MySQL常见瓶颈:</p><ol><li>CPU在饱和的时候一般发生在数据装入内存或从磁盘上读取数据的时候</li><li>磁盘I/O瓶颈发生在装入数据远大于内存容量的时候</li><li>服务器硬件的性能瓶颈,top,free,iostat和vmstat来查看系统的性能状态</li></ol><h4 id="2-11-2-explain使用简介"><a href="#2-11-2-explain使用简介" class="headerlink" title="2.11.2 explain使用简介"></a>2.11.2 explain使用简介</h4><p>使用explain关键字可以模拟优化器执行sql查询语句,从而知道mysql是如何处理sql语句的。分析查询语句或是表结构的性能瓶颈</p><p>使用方法:<code>explain + 对应的查询语句</code></p><p>能干啥:</p><ol><li>表的读取顺序</li><li>数据读取操作的操作类型</li><li>哪些索引可以使用</li><li>哪些索引被实际使用</li><li>表之间的引用</li><li>每张表有多少行被优化器查询</li></ol><h4 id="2-11-3-explain之ID介绍"><a href="#2-11-3-explain之ID介绍" class="headerlink" title="2.11.3 explain之ID介绍"></a>2.11.3 explain之ID介绍</h4><p>select查询的序列号,包含一组数字,表示查询中select子句或操作表的顺序<br>三种情况:</p><ol><li>id相同,执行顺序由上至下</li><li>id不相同,如果是子查询,id的序号会递增,id越大优先级越高,越先被执行</li><li>id相同和不同同时存在,id越大,越先执行,id相同的,同时执行</li></ol><h4 id="2-11-4-explain之select-type和table介绍"><a href="#2-11-4-explain之select-type和table介绍" class="headerlink" title="2.11.4 explain之select_type和table介绍"></a>2.11.4 explain之select_type和table介绍</h4><p>type:查询的类型,主要用于区别普通查询、联合查询、子查询等复杂的查询</p><ol><li>simple:简单的select查询,查询中不包含子查询或者union</li><li>primary:查询中若包含任何复杂的字部分,最外层查询则被标记为</li><li>subquery:在select或where列表中包含了子查询</li><li>derived:在from列表中包含的资产讯被标记为derived(衍生),mysql会递归执行这些子查询,把结果放在临时表</li><li>union:若第二个select出现在union之后,则被标记为union,若union包含在from的子句的子查询中,外层select将被标记为derived</li><li>union result:从union表中select获取的结果</li></ol><p>table:是表示这一行的数据表示哪张表</p><h4 id="2-11-5-explain之type介绍"><a href="#2-11-5-explain之type介绍" class="headerlink" title="2.11.5 explain之type介绍"></a>2.11.5 explain之type介绍</h4><p>显示查询使用了何种类型:<br>从最好到最差依次是:<code>system>const>eq_ref>ref>range>index>all</code></p><p><strong><em>system:</em></strong>表只有一行记录等于系统表,这是const类型的特例,平常不会出现,可以忽略不计<br><strong><em>const:</em></strong>表示通过索引一次就找到了,const用于比较primary key或者是unique索引。因为之匹配一行数据,所以很快如将主键置于where列表中,mysql就能将该查询装换为一个常量<br><strong><em>eq_ref:</em></strong>唯一索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描<br><strong><em>ref:</em></strong>非唯一性索引扫描,返回匹配某个值的所有行.本质上也是一种索引访问,它返回所有匹配某个单独值的行。然而,他可能会找到多个复合条件的行,所以它属于查找和扫描的混合体<br><strong><em>range:</em></strong>只检索给定范围的行,使用一个索引来选定行,key列显示使用了哪个索引。一般就是在你的where语句中出现了between、<、>、in等的查询,这种范围扫描索引扫描比全表扫描要好。因为它只需要开始与索引的某一个点,而结束于另一点,不用扫描全部索引<br><strong><em>index:</em></strong>full index sacn。index与all区别为index类型值遍历索引树。通常比all快。index从所有的索引中取值。<br><strong><em>all:</em></strong>full table scan将遍历全表以找到适合的行</p><h4 id="2-11-6-explain之possible-key和key介绍"><a href="#2-11-6-explain之possible-key和key介绍" class="headerlink" title="2.11.6 explain之possible_key和key介绍"></a>2.11.6 explain之possible_key和key介绍</h4><p>possible_key:显示可能应用在这张表中的索引,一个或者多个。查询涉及到字段上若存在索引,则该索引将被列出。但不一定被查询实际使用<br>key:实际使用的索引。如果没有则显示为null.查询中若使用了覆盖索引。则该索引仅出现在key列表中</p><h4 id="2-11-7-explain之key-len介绍"><a href="#2-11-7-explain之key-len介绍" class="headerlink" title="2.11.7 explain之key_len介绍"></a>2.11.7 explain之key_len介绍</h4><p>表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度。在不损失精确性的情况下,长度越短越好。key_len现实的值为索引字段的最大可能长度,并非实际使用长度,即key_len是分局表定义计算而得。不是通过表内检索出的</p><h4 id="2-11-8-explain之ref介绍"><a href="#2-11-8-explain之ref介绍" class="headerlink" title="2.11.8 explain之ref介绍"></a>2.11.8 explain之ref介绍</h4><p>显示索引哪一列被使用了。如果可能的话,是一个常数,哪些列或常量被用于查找索引列上的值</p><h4 id="2-11-9-explain之rows介绍"><a href="#2-11-9-explain之rows介绍" class="headerlink" title="2.11.9 explain之rows介绍"></a>2.11.9 explain之rows介绍</h4><p>根据表统计信息及索引选用情况。大致估算出找到所需的记录所需要读取的行数</p><h4 id="2-11-10-explain之extra介绍"><a href="#2-11-10-explain之extra介绍" class="headerlink" title="2.11.10 explain之extra介绍"></a>2.11.10 explain之extra介绍</h4><p>包含不在其他列展示,但是又十分重要的额外信息</p><ol><li>using filesort:说明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL中无法利用索引完成的排序操作称为“文件排序”</li><li>using temporary:使用临时表保存中间结果,mysql在对查询结果排序时使用临时表。常见于排序order by和分组查询group by</li><li>using index:表示相应的select操作中使用了覆盖索引(Covering index),避免访问了表的数据行,效率不错!如果同时出现using where ,表明索引被用来执行索引键值的查找。如果没有同时出现 using where ,表明索引用来读取数据而非执行查找动作。</li><li>using where:表明使用了where过滤</li><li>using join buffer</li><li>impossible where:where子句的值总是false,不能用来获取任何元组</li><li>select tables optimized away</li><li>distinct:</li></ol><h3 id="2-12-索引优化"><a href="#2-12-索引优化" class="headerlink" title="2.12 索引优化"></a>2.12 索引优化</h3><ol><li>全值匹配我最爱</li><li>最佳左前缀法则:如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中列</li><li>不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描</li><li>存储引擎不能使用索引中范围条件右边的列(范围之后的索引全都失效)</li><li>尽量使用覆盖索引(只访问索引的查询(索引和查询列一致)),减少select *</li><li>mysql在使用不等于(!= 或者<>)的时候无法使用索引或导致全表扫描</li><li>is null,is not null 也无法使用索引</li><li>like以通配符开头,mysql索引失效会变成全表扫描的操作</li><li>字符串不加单引号索引失效</li><li>少用or,用它来连接时会索引失效</li></ol><h2 id="3-查询截取分析"><a href="#3-查询截取分析" class="headerlink" title="3.查询截取分析"></a>3.查询截取分析</h2><h3 id="3-1-查询优化"><a href="#3-1-查询优化" class="headerlink" title="3.1 查询优化"></a>3.1 查询优化</h3><h4 id="3-1-1-小表驱动大表"><a href="#3-1-1-小表驱动大表" class="headerlink" title="3.1.1 小表驱动大表"></a>3.1.1 小表驱动大表</h4><p>小表驱动大表,即小的数据集驱动大的数据集<br>当B表的数据集必须小于A表的数据集时,用in优于exists<br>当A表数据集小于B表的数据集时,用exist优于in<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghi9hjlvmwj30om0gkwj2.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghi9kd8ynfj31e20akaff.jpg" alt=""></p><h4 id="3-1-2-in和exists"><a href="#3-1-2-in和exists" class="headerlink" title="3.1.2 in和exists"></a>3.1.2 in和exists</h4><h4 id="3-1-3-使用索引orderby优化"><a href="#3-1-3-使用索引orderby优化" class="headerlink" title="3.1.3 使用索引orderby优化"></a>3.1.3 使用索引orderby优化</h4><ol><li>order by子句,尽量使用index方式排序,避免使用filesort的方式排序</li><li>尽可能在索引列上完成排序操作,遵照索引建的最佳左前缀</li><li>如果不在索引列上 filesort有两种算法</li></ol><h4 id="3-1-4-group-by优化"><a href="#3-1-4-group-by优化" class="headerlink" title="3.1.4 group by优化"></a>3.1.4 group by优化</h4><p>基本上和order by的情况相同</p><h3 id="3-2-慢查询日志"><a href="#3-2-慢查询日志" class="headerlink" title="3.2 慢查询日志"></a>3.2 慢查询日志</h3><p>默认情况下,MySQL数据库没有开启慢查询日志,需要我们手动来设置这个参数。当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定性能影响。慢查询日志支持将日志记录写入文件</p><ol><li>查看是否开启及如何开启<br> 默认:<code>show variables like '%slow_query_log%'</code><br> 开启:<code>set global slow_query_log = 1</code>,只对当前数据库生效,mysql重启后失效</li><li>开启后什么样的sql会写入<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghibx93564j31160hg7ca.jpg" alt=""></li><li>设置慢的阙值时间:<code>set global long_query_time = 3;</code></li><li>看不到改变的原因:需要重新连接或者新开一个会话才能看到修改值。 <code>show variables like 'long_query_time%'</code>、<code>show global variables like 'long_query_time'</code></li><li>记录慢SQL后并后续分析</li><li>日志分析工具mysqldunpslow<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghice893tuj311o0kodjm.jpg" alt=""><br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghicen234tj30ye0i67dp.jpg" alt=""></li></ol><h3 id="3-3-批量数据脚本"><a href="#3-3-批量数据脚本" class="headerlink" title="3.3 批量数据脚本"></a>3.3 批量数据脚本</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghickdsh3sj31300ho46b.jpg" alt=""></p><h3 id="3-4-show-Profile"><a href="#3-4-show-Profile" class="headerlink" title="3.4 show Profile"></a>3.4 show Profile</h3><p><strong><em>是什么:</em></strong>是mysql提供剋月用来分析当前会话中语句执行的资源消耗情况。可以用于SQL的调优测量<br>默认情况下,参数处于关闭状态,并保存最近15次的运行结果。<br><strong><em>分析步骤:</em></strong></p><ol><li><p>是否支持,看看当前的mysql版本是否支持<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghigr2l8n3j30ia0hqjuh.jpg" alt=""></p></li><li><p>开启功能,默认是关闭的,使用前需要开启<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghigsph5hjj30m60kyq5y.jpg" alt=""></p></li><li><p>运行sql</p></li><li><p>查看结果,show profiles</p></li><li><p>诊断SQL:<code>show profile cpu,block io for query 上一步前面问题sql数字号码</code><br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghih6afod4j314q0hyqb2.jpg" alt=""></p></li><li><p>日常开发需要注意的结论</p><ul><li>converting heap to myisam 查询结果太大,内存都不够用了,往磁盘上办了</li><li>creating tmp table 创建临时表(拷贝数据到临时表,用完在删除)</li><li>copying to tmp table on disk 把内存中临时表复制到磁盘,危险!!!</li><li>locked<h3 id="3-5-全局查询日志"><a href="#3-5-全局查询日志" class="headerlink" title="3.5 全局查询日志"></a>3.5 全局查询日志</h3></li></ul></li><li><p>配置启用<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghihkcf6fjj30fy0c6414.jpg" alt=""></p></li><li><p>编码启用<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghihkomj0dj31700jqn2g.jpg" alt=""></p></li><li><p>永远不要在生产环境中启用</p><h2 id="4-MySQL锁机制"><a href="#4-MySQL锁机制" class="headerlink" title="4. MySQL锁机制"></a>4. MySQL锁机制</h2><h3 id="4-1-数据库锁理论概述"><a href="#4-1-数据库锁理论概述" class="headerlink" title="4.1 数据库锁理论概述"></a>4.1 数据库锁理论概述</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghihuq1prwj31fo092ahe.jpg" alt=""></p></li></ol><p><strong><em>锁的分类:</em></strong><br>从对数据操作的类型(读/写)分<br><strong><em>读锁(共享锁):</em></strong>针对同一份数据,多个读操作可以同时进行而不会互相影响<br><strong><em>行锁(排他锁):</em></strong>当前写操作没有完成前,他会阻断其他写锁和读锁<br>从对数据操作的粒度分:表锁/行锁</p><h3 id="4-2-读锁案例讲解"><a href="#4-2-读锁案例讲解" class="headerlink" title="4.2 读锁案例讲解"></a>4.2 读锁案例讲解</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghii4kaa1yj30pk06wgnm.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghiih2oo1pj31ee0my0yz.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghiii02u2aj31dc0hqwkv.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghiiihnxfoj318o05atay.jpg" alt=""></p><hr><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghiin5iacdj31540niaiy.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghiiodvv1wj311q08s40u.jpg" alt=""></p><hr><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghiip42lv5j31fi0mgtl8.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghiipq4xc0j30w6018t9w.jpg" alt=""></p><hr><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghiirel3s0j31fk0lqgw8.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghiislmhomj31fm02qjud.jpg" alt=""></p><h3 id="4-3-行锁理论"><a href="#4-3-行锁理论" class="headerlink" title="4.3 行锁理论"></a>4.3 行锁理论</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghijdqt0quj31cg0myahp.jpg" alt=""></p><h3 id="4-4-索引失效行锁变表锁"><a href="#4-4-索引失效行锁变表锁" class="headerlink" title="4.4 索引失效行锁变表锁"></a>4.4 索引失效行锁变表锁</h3><h3 id="4-5-间隙锁危害"><a href="#4-5-间隙锁危害" class="headerlink" title="4.5 间隙锁危害"></a>4.5 间隙锁危害</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghik0ej11zj31fy0deqf4.jpg" alt=""></p><h3 id="4-6-如何锁定一行"><a href="#4-6-如何锁定一行" class="headerlink" title="4.6 如何锁定一行"></a>4.6 如何锁定一行</h3><h3 id="4-7-行锁总结"><a href="#4-7-行锁总结" class="headerlink" title="4.7 行锁总结"></a>4.7 行锁总结</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghik7r83nsj31g60bkwmx.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghik9c7sxmj313q0n8tgi.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghikb51r6qj30vw0aoq92.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghikbigutej31fk092wk6.jpg" alt=""></p><h2 id="5-主从复制"><a href="#5-主从复制" class="headerlink" title="5. 主从复制"></a>5. 主从复制</h2><ol><li><p>复制的基本原理<br> slave会从master读取binlog来进行数据同步<br> 三个步骤:<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1ghiki7gwqjj315q0lmk34.jpg" alt=""></p></li><li><p>复制的基本原则<br> 每个slave只有一个master</p></li><li><p>复制的最大问题<br> 延时</p></li><li><p>主从常见配置</p></li></ol>]]></content>
<summary type="html">
<h1 id="MySQL高级部分学习一"><a href="#MySQL高级部分学习一" class="headerlink" title="MySQL高级部分学习一"></a>MySQL高级部分学习一</h1><h2 id="1-mysql的架构介绍"><a href="#1
</summary>
</entry>
<entry>
<title>MySQL数据库学习笔记.md</title>
<link href="http://lwblog.xyz/posts/8d9f420d.html"/>
<id>http://lwblog.xyz/posts/8d9f420d.html</id>
<published>2020-08-17T01:03:37.000Z</published>
<updated>2020-08-17T01:07:00.874Z</updated>
<content type="html"><![CDATA[<h1 id="MySQL数据库学习笔记"><a href="#MySQL数据库学习笔记" class="headerlink" title="MySQL数据库学习笔记"></a>MySQL数据库学习笔记</h1><h2 id="1-MySQL的语法规范"><a href="#1-MySQL的语法规范" class="headerlink" title="1.MySQL的语法规范"></a>1.MySQL的语法规范</h2><ol><li>不区分大小写,但建议关键字大写,表名、列名小写</li><li>每条命令最好用分号结尾</li><li>每条命令根据需要,可以进行缩进 或换行</li><li>注释<ul><li>单行注释:#注释文字</li><li>单行注释:– 注释文字</li><li>多行注释:/* 注释文字 */<h2 id="2-SQL的语言分类"><a href="#2-SQL的语言分类" class="headerlink" title="2.SQL的语言分类"></a>2.SQL的语言分类</h2></li></ul></li><li>DQL(Data Query Language):数据查询语言 select</li><li>DML(Data Manipulate Language):数据操作语言:insert、update、delete</li><li>DDL(Data Define Languge):数据定义语言:create alter drop</li><li>TCL(Transaction Control Language):事务控制语言 commit rollback</li></ol><h2 id="3-SQL的常见命令"><a href="#3-SQL的常见命令" class="headerlink" title="3.SQL的常见命令"></a>3.SQL的常见命令</h2><h2 id="4-DQL语言的学习"><a href="#4-DQL语言的学习" class="headerlink" title="4.DQL语言的学习"></a>4.DQL语言的学习</h2><p><strong><em>更加具体的讲解详见对应的尚硅谷查询语句的pdf</em></strong></p><h3 id="进阶1:基础查询"><a href="#进阶1:基础查询" class="headerlink" title="进阶1:基础查询"></a>进阶1:基础查询</h3><p>语法:select 查询的东西 [from 表名]<br>特点:<br> 1. 通过select查询完的结果 ,是一个虚拟的表格,不是真实存在<br> 2. 要查询的东西 可以是常量值、可以是表达式、可以是字段、可以是函数</p><h3 id="进阶2:条件查询"><a href="#进阶2:条件查询" class="headerlink" title="进阶2:条件查询"></a>进阶2:条件查询</h3><p>条件查询:根据条件过滤原始表的数据,查询到想要的数据<br>语法:<br> select 要查询的字段|表达式|常量值|函数<br> from 表名<br> where 条件;<br>分类:<br> 1. 条件表达式<br> * ><br> * <<br> * >=<br> * >=<br> * =<br> * !=<br> * <>:建议使用,不建议使用!=<br> 2. 逻辑表达式:用于连接条件表达式<br> * and(&&):两个条件如果同时成立,结果为true,否则为false<br> * or(||):两个条件只要有一个成立,结果为true,否则为false<br> * not(!):如果条件成立,则not后为false,否则为true<br> 3. 模糊查询<br> * like<br> * between and<br> * in<br> * is null</p><h3 id="进阶3:排序查询"><a href="#进阶3:排序查询" class="headerlink" title="进阶3:排序查询"></a>进阶3:排序查询</h3><p><strong><em>详细笔记请见尚硅谷基础学习笔记3</em></strong></p><h3 id="进阶4:常见函数"><a href="#进阶4:常见函数" class="headerlink" title="进阶4:常见函数"></a>进阶4:常见函数</h3><p>一、单行函数<br> 1、字符函数<br> concat拼接<br> substr截取子串<br> upper转换成大写<br> lower转换成小写<br> trim去前后指定的空格和字符<br> ltrim去左边空格<br> rtrim去右边空格<br> replace替换<br> lpad左填充<br> rpad右填充<br> instr返回子串第一次出现的索引<br> length 获取字节个数<br> 2、数学函数<br> round 四舍五入<br> rand 随机数<br> floor向下取整<br> ceil向上取整<br> mod取余<br> truncate截断<br>3、日期函数<br> now当前系统日期+时间<br> curdate当前系统日期<br> curtime当前系统时间<br> str_to_date 将字符转换成日期<br> date_format将日期转换成字符<br>4、流程控制函数<br> if 处理双分支<br> case语句 处理多分支<br> 情况1:处理等值判断<br> 情况2:处理条件判断<br>5、其他函数<br> version版本<br> database当前库<br> user当前连接用户</p>]]></content>
<summary type="html">
<h1 id="MySQL数据库学习笔记"><a href="#MySQL数据库学习笔记" class="headerlink" title="MySQL数据库学习笔记"></a>MySQL数据库学习笔记</h1><h2 id="1-MySQL的语法规范"><a href="#1
</summary>
</entry>
<entry>
<title>StartUML使用技巧.md</title>
<link href="http://lwblog.xyz/posts/80aa353a.html"/>
<id>http://lwblog.xyz/posts/80aa353a.html</id>
<published>2020-08-13T01:36:12.000Z</published>
<updated>2020-08-13T01:37:41.416Z</updated>
<content type="html"><![CDATA[<h1 id="StartUML使用技巧"><a href="#StartUML使用技巧" class="headerlink" title="StartUML使用技巧"></a>StartUML使用技巧</h1><h2 id="1-工作界面简单介绍"><a href="#1-工作界面简单介绍" class="headerlink" title="1. 工作界面简单介绍"></a>1. 工作界面简单介绍</h2><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghdlytwsyij31dc0u0ass.jpg" alt=""></p><h2 id="2-类组件的基本操作介绍"><a href="#2-类组件的基本操作介绍" class="headerlink" title="2.类组件的基本操作介绍"></a>2.类组件的基本操作介绍</h2><p>单击选择Class,至工作区域内单机左键,即可创建一个class实例。创建实例后,周围会出现一堆,功能按钮,去描述这个类<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghdm3rtyovj30zc0fk77t.jpg" alt=""><br>功能介绍:</p><ol><li>用来标识Class的可见性</li><li>用来添加note的,比如:类的说明</li><li>增加类的属性</li><li>增加类的操作方法</li><li>增加Reception</li><li>增加子类</li><li>增加父类</li><li>添加已有的接口</li><li>添加需要的接口</li><li>添加关联</li><li>添加聚合</li><li>添加组合</li><li>添加端口</li><li>添加部件</li></ol><h2 id="3-类与类之间的关系"><a href="#3-类与类之间的关系" class="headerlink" title="3. 类与类之间的关系"></a>3. 类与类之间的关系</h2><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghdmh7zo5mj30s60l8whj.jpg" alt=""></p><ol><li><strong>聚合关系(Aggregation)</strong>:表示一个整体与部分的关系。在聚合关系中,成员类是整体类的一部分,即成员对象是整体对象的一部分,成员对象可以脱离整体对象独立存在。 在 UML 中,<em>聚合关系用带空心菱形的直线表示</em>。</li><li><strong>组合关系(Composition)</strong>:组合关系也表示类之间整体和部分的关系,但是组合关系中部分和整体具有统一的生存期。一旦整体对象不存在,部分对象也将不存在,部分对象与整体对象之间具有同生共死的关系。在组合关系中,成员类是整体类的一部分,而且整体类可以控制成员类的生命周期,即成员类的存在依赖于整体类。 在UML中,<em>组合关系用带实心菱形的直线表示</em>。</li><li><strong>依赖关系(Dependency)</strong>:依赖关系是一种使用关系,特定事物的改变有可能会影响到使用该事物的其他事物,在需要表示一个事物使用另一个事物时使用依赖关系。大多数情况下,依赖关系体现在某个类的方法使用另一个类的对象作为参数。在UML中,<em>依赖关系用带箭头的虚线表示</em>,由依赖的一方指向被依赖的一方。</li><li><strong>泛化关系(Generalization)</strong>:也就是继承关系,也称为“is-a-kind-of”关系,泛化关系用于描述父类与子类之间的关系,父类又称作基类或超类,子类又称作派生类。在 UML 中,<em>泛化关系用带空心三角形的直线来表示</em>。</li><li><strong>实现关系</strong>:实现关系(Realization)是类实现了接口,类中的操作实现了接口中所声明的操作。在UML中,<em>类与接口之间的实现关系用带空心三角形的虚线来表示</em>。</li><li><strong>关联关系(Association)</strong>:类与类之间最常用的一种关系,它是一种结构化关系,用于表示一个类对象与另一个类对象之间有联系。在 UML 类图中,用实线连接有关联的对象所对应的类。在实现关联关系时,通常将一个类的对象作为另一个类的属性。<ul><li><strong>单向关联</strong>:类的关联关系可以是单向的,<em>单向关联用带箭头的实线表示。Ctril + L</em> 弄直<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghdmzpjhldj30lp02rmxh.jpg" alt=""> </li><li><strong>双向关联</strong>:默认情况下,<em>关联是双向的</em><br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghdn06ezb6j30lu02t74o.jpg" alt=""></li><li><strong>自关联</strong>:在系统中可能会存在一些类的属性对象类型为该类本身,这种特殊的关联关系称为自关联。<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghdn0jz27zj30ax05nq34.jpg" alt=""></li><li><strong>重数性关联</strong>:重数性关联关系又称为多重性关联关系(Multiplicity),表示一个类的对象与另一个类的对象连接的个数。在 UML 中多重性关系可以直接在关联直线上增加一个数字表示与之对应的另一个类的对象的个数<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghdn0v8ff2j30m402x0t0.jpg" alt=""><br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghdn128z7pj30ix07ogmi.jpg" alt=""></li></ul></li></ol><h2 id="4-UML方法的返回值"><a href="#4-UML方法的返回值" class="headerlink" title="4. UML方法的返回值"></a>4. UML方法的返回值</h2><p>Operation的返回值:StarUML添加一个Operation,要Add一个Parameter,将这个Parameter的DirectionKind设为RETURN。<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1ghdnfom3v9j31do0u0q9o.jpg" alt=""></p>]]></content>
<summary type="html">
<h1 id="StartUML使用技巧"><a href="#StartUML使用技巧" class="headerlink" title="StartUML使用技巧"></a>StartUML使用技巧</h1><h2 id="1-工作界面简单介绍"><a href="#1-工
</summary>
</entry>
<entry>
<title>Mybatis学习笔记二</title>
<link href="http://lwblog.xyz/posts/a71dc8d.html"/>
<id>http://lwblog.xyz/posts/a71dc8d.html</id>
<published>2020-06-10T13:17:53.000Z</published>
<updated>2020-06-10T13:18:55.544Z</updated>
<content type="html"><![CDATA[<h2 id="1-Mybatis逆向工程"><a href="#1-Mybatis逆向工程" class="headerlink" title="1. Mybatis逆向工程"></a>1. Mybatis逆向工程</h2><h3 id="1-1-说明"><a href="#1-1-说明" class="headerlink" title="1.1 说明"></a>1.1 说明</h3><ol><li><p>MyBatis Generator<a href="http://mybatis.org/generator/#" target="_blank" rel="noopener">官方文档地址</a></p></li><li><p><a href="https://github.com/mybatis/generator/releases" target="_blank" rel="noopener">官方工程地址</a></p></li><li><p>依赖的包</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><!--mybatis逆向工程依赖包--></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.mybatis.generator</groupId></span><br><span class="line"> <artifactId>mybatis-generator-core</artifactId></span><br><span class="line"> <version>1.4.0</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.mybatis.generator</groupId></span><br><span class="line"> <artifactId>mybatis-generator-maven-plugin</artifactId></span><br><span class="line"> <version>1.4.0</version></span><br><span class="line"> </dependency></span><br></pre></td></tr></table></figure><h3 id="1-2-逆向功能的配置文件"><a href="#1-2-逆向功能的配置文件" class="headerlink" title="1.2 逆向功能的配置文件"></a>1.2 逆向功能的配置文件</h3> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><!DOCTYPE generatorConfiguration</span><br><span class="line"> PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"</span><br><span class="line"> "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"></span><br><span class="line"><generatorConfiguration></span><br><span class="line"></span><br><span class="line"><!-- </span><br><span class="line">targetRuntime="MyBatis3Simple":生成简单版的CRUD</span><br><span class="line">MyBatis3:豪华版</span><br><span class="line"></span><br><span class="line"> --></span><br><span class="line"> <context id="DB2Tables" targetRuntime="MyBatis3"></span><br><span class="line"> <!-- jdbcConnection:指定如何连接到目标数据库 --></span><br><span class="line"> <jdbcConnection driverClass="com.mysql.jdbc.Driver"</span><br><span class="line"> connectionURL="jdbc:mysql://localhost:3306/mybatis?allowMultiQueries=true"</span><br><span class="line"> userId="root"</span><br><span class="line"> password="123456"></span><br><span class="line"> </jdbcConnection></span><br><span class="line"></span><br><span class="line"><!-- --></span><br><span class="line"> <javaTypeResolver ></span><br><span class="line"> <property name="forceBigDecimals" value="false" /></span><br><span class="line"> </javaTypeResolver></span><br><span class="line"></span><br><span class="line"><!-- javaModelGenerator:指定javaBean的生成策略 </span><br><span class="line">targetPackage="test.model":目标包名</span><br><span class="line">targetProject="\MBGTestProject\src":目标工程</span><br><span class="line">--></span><br><span class="line"> <javaModelGenerator targetPackage="com.atguigu.mybatis.bean" </span><br><span class="line"> targetProject=".\src"></span><br><span class="line"> <property name="enableSubPackages" value="true" /></span><br><span class="line"> <property name="trimStrings" value="true" /></span><br><span class="line"> </javaModelGenerator></span><br><span class="line"></span><br><span class="line"><!-- sqlMapGenerator:sql映射生成策略: --></span><br><span class="line"> <sqlMapGenerator targetPackage="com.atguigu.mybatis.dao" </span><br><span class="line"> targetProject=".\conf"></span><br><span class="line"> <property name="enableSubPackages" value="true" /></span><br><span class="line"> </sqlMapGenerator></span><br><span class="line"></span><br><span class="line"><!-- javaClientGenerator:指定mapper接口所在的位置 --></span><br><span class="line"> <javaClientGenerator type="XMLMAPPER" targetPackage="com.atguigu.mybatis.dao" </span><br><span class="line"> targetProject=".\src"></span><br><span class="line"> <property name="enableSubPackages" value="true" /></span><br><span class="line"> </javaClientGenerator></span><br><span class="line"></span><br><span class="line"><!-- 指定要逆向分析哪些表:根据表要创建javaBean --></span><br><span class="line"> <table tableName="tbl_dept" domainObjectName="Department"></table></span><br><span class="line"> <table tableName="tbl_employee" domainObjectName="Employee"></table></span><br><span class="line"> </context></span><br><span class="line"></generatorConfiguration></span><br></pre></td></tr></table></figure></li></ol><h2 id="2-Mybatis的运行原理"><a href="#2-Mybatis的运行原理" class="headerlink" title="2. Mybatis的运行原理"></a>2. Mybatis的运行原理</h2><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfn1ec5vpzj30pc0eqdi7.jpg" alt="运行原理图"><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfn1fqhsrdj315l0u07b9.jpg" alt="框架原理图"></p><h3 id="2-1-sqlsessionFactory的初始化"><a href="#2-1-sqlsessionFactory的初始化" class="headerlink" title="2.1 sqlsessionFactory的初始化"></a>2.1 sqlsessionFactory的初始化</h3><ol><li>根据配置文件创建sqlsessionFactory<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfn8jtopjwj315e0q6jwj.jpg" alt=""></li><li>几个重要的类<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfn8l20ikdj30oy08amyc.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfn8lcrpp2j30wy0n6gqg.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfn8lnaxpkj310m0pijwy.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfn8lu4tvtj31ca094tbp.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfn8m1jq87j316q0cotc7.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfn8mhihjrj30s408mdhp.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfn8mo15jrj30s408mdhp.jpg" alt="缓存中保存的key:方法id+sql+参数xxx"></li></ol><h3 id="2-2-openSession获取SqlSession对象"><a href="#2-2-openSession获取SqlSession对象" class="headerlink" title="2.2 openSession获取SqlSession对象"></a>2.2 openSession获取SqlSession对象</h3><p>返回SqlSession的实现类DefaultSqlSession对象。他里面包含了Executor和Configuration;Executor会在这一步被创建<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfn931bghjj317a0mcn16.jpg" alt=""></p><h3 id="2-3-getMapper获取到接口的代理对象"><a href="#2-3-getMapper获取到接口的代理对象" class="headerlink" title="2.3 getMapper获取到接口的代理对象"></a>2.3 getMapper获取到接口的代理对象</h3><p>getMapper返回接口的代理对象包含了SqlSession对象<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfn9ey08pxj312a0lon0i.jpg" alt=""></p><h3 id="2-4-查询实现"><a href="#2-4-查询实现" class="headerlink" title="2.4 查询实现"></a>2.4 查询实现</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfnagofu78j30zm0u043h.jpg" alt=""></p><h2 id="3-插件"><a href="#3-插件" class="headerlink" title="3.插件"></a>3.插件</h2><p>MyBatis在四大对象的创建过程中,都会有插件进行介入。插件可以利用动态代理机制一层层的包装目标对象,而实现在目标对象执行目标方法之前进行拦截的效果。<br>MyBatis 允许在已映射语句执行过程中的某一点进行拦截调用。<br>默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:</p><ul><li>Executor(update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)</li><li>ParameterHandler(getParameterObject, setParameters)</li><li>ResultSetHandler(handleResultSets, handleOutputParameters)</li><li>StatementHandler(prepare, parameterize, batch, update, query)</li></ul><h3 id="3-1-插件开发的步骤"><a href="#3-1-插件开发的步骤" class="headerlink" title="3.1 插件开发的步骤"></a>3.1 插件开发的步骤</h3><ol><li><p>编写插件实现Interceptor接口并使用@Intercepts注解完成插件签名</p><pre><code><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line">package com.atguigu.in;</span><br><span class="line"></span><br><span class="line">import org.apache.ibatis.executor.statement.StatementHandler;</span><br><span class="line">import org.apache.ibatis.plugin.*;</span><br><span class="line"></span><br><span class="line">import java.util.Properties;</span><br><span class="line"></span><br><span class="line">/**</span><br><span class="line"> * intercept:拦截目标对象的目标方法的执行</span><br><span class="line"> * 完成插件的签名:</span><br><span class="line"> * 告诉mybatis当前插件来拦截那个执行器的那个方法</span><br><span class="line"> */</span><br><span class="line">@Intercepts({</span><br><span class="line"> @Signature(</span><br><span class="line"> type = StatementHandler.class,method = "parameterize",args=java.sql.Statement.class</span><br><span class="line"> )</span><br><span class="line">})</span><br><span class="line">public class MyFirstIn implements Interceptor {</span><br><span class="line"> @Override</span><br><span class="line"> public Object intercept(Invocation invocation) throws Throwable {</span><br><span class="line"> //放行执行目标方法</span><br><span class="line"> Object proceed = invocation.proceed();</span><br><span class="line"> return proceed;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> /**</span><br><span class="line"> * 插件包装</span><br><span class="line"> * 为目标对象创建一个代理对象</span><br><span class="line"> * @param target</span><br><span class="line"> * @return</span><br><span class="line"> */</span><br><span class="line"> @Override</span><br><span class="line"> public Object plugin(Object target) {</span><br><span class="line"> Object wrap = Plugin.wrap(target, this);</span><br><span class="line"> //我们可以借助Plugin的wrap方法来使用当前的拦截器包装我们的对象</span><br><span class="line"> //返回为当前target创建的动态代理</span><br><span class="line"> return wrap;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> /**</span><br><span class="line"> * 将插件注册时的properties属性注册出来</span><br><span class="line"> * @param properties</span><br><span class="line"> */</span><br><span class="line"> @Override</span><br><span class="line"> public void setProperties(Properties properties) {</span><br><span class="line"> System.out.println("可以拿到插件的信息");</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></code></pre></li><li><p>在全局配置文件中注册插件</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><plugins></span><br><span class="line"> <plugin interceptor="com.atguigu.in.MyFirstIn"></span><br><span class="line"> <property name="name" value="ceshi"/></span><br><span class="line"> </plugin></span><br><span class="line"> </plugins></span><br></pre></td></tr></table></figure></li></ol><h2 id="4-mybatis批量操作"><a href="#4-mybatis批量操作" class="headerlink" title="4. mybatis批量操作"></a>4. mybatis批量操作</h2><ul><li><p>默认的openSession() 方法没有参数,它会创建有如下特性的</p><ul><li>会开启一个事务(也就是不自动提交)</li><li>连接对象会从由活动环境配置的数据源实例得到</li><li>事务隔离级别将会使用驱动或数据源的默认设置</li><li>预处理语句不会被复用,也不会批量处理更</li></ul></li><li><p>openSession 方法的ExecutorType类型的参数,枚举类型:</p><ul><li>ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情(这是默认装配的)。它为每个语句的执行创建一个新的预处理语句</li><li>ExecutorType.REUSE: 这个执行器类型会复用预处理语句</li><li>ExecutorType.BATCH: 这个执行器会批量执行所有更新语句<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfng3gzkm0j30qh05f0uv.jpg" alt=""></li></ul></li><li><p>批量操作我们是使用MyBatis提供的BatchExecutor进行的,他的底层就是通过jdbc攒sql的方式进行的。我们可以让他攒够一定数量后发给数据库一次</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"> publicvoidtest01() {</span><br><span class="line">SqlSession openSession = build.openSession(ExecutorType.BATCH);</span><br><span class="line">UserDao mapper = openSession.getMapper(UserDao.class);</span><br><span class="line">longstart = System.currentTimeMillis();</span><br><span class="line">for(inti = 0; i < 1000000; i++) {</span><br><span class="line">String name = UUID.randomUUID().toString().substring(0, 5);</span><br><span class="line">mapper.addUser(newUser(null, name, 13));</span><br><span class="line">}</span><br><span class="line">openSession.commit();</span><br><span class="line">openSession.close();</span><br><span class="line">longend = System.currentTimeMillis();</span><br><span class="line">System.out.println("耗时时间:"+(end-start));</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li><p>与Spring整合中,我们推荐,额外的配置一个可以专门用来执行批量操作的sqlSession<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfngak3h1uj30ur02kt9l.jpg" alt=""></p></li><li><p>需要用到批量操作的时候,我们可以注入配置的这个批量SqlSession。通过他获取到mapper映射器进行操作</p></li></ul><p><strong><em>注意</em></strong></p><ol><li>批量操作是在session.commit()以后才发送sql语句给数据库进行执行的</li><li>如果我们想让其提前执行,以方便后续可能的查询操作获取数据,我们可以使用sqlSession.flushStatements()方法,让其直接冲刷到数据库进行执行</li></ol><h2 id="5-一个带游标的存储过程"><a href="#5-一个带游标的存储过程" class="headerlink" title="5. 一个带游标的存储过程"></a>5. 一个带游标的存储过程</h2><ul><li><p>MyBatis对存储过程的游标提供了一个JdbcType=CURSOR的支持,可以智能的把游标读取到的数据,映射到我们声明的结果集中</p></li><li><p>存储过程的调用</p><ul><li><p>select标签中statementType=“CALLABLE”</p></li><li><p>标签体中调用语法:{call procedure_name(#{param1_info},#{param2_info})}</p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfngl1c895j30ol066gn3.jpg" alt=""></p></li></ul></li></ul><h2 id="6-自定义TypeHandler处理枚举"><a href="#6-自定义TypeHandler处理枚举" class="headerlink" title="6.自定义TypeHandler处理枚举"></a>6.自定义TypeHandler处理枚举</h2><ul><li>我们可以通过自定义TypeHandler的形式来在设置参数或者取出结果集的时候自定义参数封装策略</li><li>步骤<ul><li>实现TypeHandler接口或者继承BaseTypeHandler</li><li>使用@MappedTypes定义处理的java类型</li><li>使用@MappedJdbcTypes定义jdbcType类型</li><li>在自定义结果集标签或者参数处理的时候声明使用自定义TypeHandler进行处理,或者在全局配置TypeHandler要处理的javaType</li></ul></li></ul>]]></content>
<summary type="html">
<h2 id="1-Mybatis逆向工程"><a href="#1-Mybatis逆向工程" class="headerlink" title="1. Mybatis逆向工程"></a>1. Mybatis逆向工程</h2><h3 id="1-1-说明"><a href="#1
</summary>
<category term="mybatis" scheme="http://lwblog.xyz/categories/mybatis/"/>
<category term="mybatis" scheme="http://lwblog.xyz/tags/mybatis/"/>
</entry>
<entry>
<title>学习计划</title>
<link href="http://lwblog.xyz/posts/5e21c553.html"/>
<id>http://lwblog.xyz/posts/5e21c553.html</id>
<published>2020-06-10T13:11:13.000Z</published>
<updated>2020-06-10T14:17:56.921Z</updated>
<content type="html"><![CDATA[<h2 id="Java基础和框架学习计划"><a href="#Java基础和框架学习计划" class="headerlink" title="Java基础和框架学习计划"></a>Java基础和框架学习计划</h2><ul><li><input checked="" disabled="" type="checkbox"> Spring Boot视频教程(上)核心技术篇</li><li><input disabled="" type="checkbox"> Spring Boot视频教程(下)整合篇</li><li><input disabled="" type="checkbox"> JAVA常用类</li><li><input checked="" disabled="" type="checkbox"> MyBatis-Plus </li><li><input disabled="" type="checkbox"> 通用Mapper</li><li><input disabled="" type="checkbox"> JVM</li><li><input disabled="" type="checkbox"> SpringCloud</li><li><input disabled="" type="checkbox"> 尚硅谷Dubbo视频</li><li><input disabled="" type="checkbox"> redis</li><li><input disabled="" type="checkbox"> JDBC升级版</li><li><input disabled="" type="checkbox"> Java8新特性</li><li><input disabled="" type="checkbox"> JUC</li><li><input disabled="" type="checkbox"> NIO</li></ul>]]></content>
<summary type="html">
学习计划
</summary>
<category term="学习计划" scheme="http://lwblog.xyz/categories/%E5%AD%A6%E4%B9%A0%E8%AE%A1%E5%88%92/"/>
<category term="学习计划" scheme="http://lwblog.xyz/tags/%E5%AD%A6%E4%B9%A0%E8%AE%A1%E5%88%92/"/>
</entry>
<entry>
<title>Maven学习笔记</title>
<link href="http://lwblog.xyz/posts/be02a930.html"/>
<id>http://lwblog.xyz/posts/be02a930.html</id>
<published>2020-06-05T05:33:18.000Z</published>
<updated>2020-06-05T05:36:44.215Z</updated>
<content type="html"><![CDATA[<h2 id="1-Maven-简介"><a href="#1-Maven-简介" class="headerlink" title="1.Maven 简介"></a>1.Maven 简介</h2><p>Maven是Apache软件基金会组织维护的一款自动化构建工具专注服务于Java平台的项目构建和依赖管理 。</p><h2 id="2-构建过程的主要几个环节"><a href="#2-构建过程的主要几个环节" class="headerlink" title="2. 构建过程的主要几个环节"></a>2. 构建过程的主要几个环节</h2><p>①清理 :删除以前的编译结果,为重新编译做好准备。<br>②编译 :将Java源程序编译为字节码文件。<br>③测试 :针对项目中的关键点进行测试,确保项目在迭代开发过程中关键点的正确性。<br>④报告 :在每一次测试后以标准的格式记录和展示测试结果。<br>⑤打包 :将一个包含诸多文件的工程封装为一个压缩文件用于安装或部署。Java工程对应jar包,Web工程对应war包。<br>⑥安装 :在 Maven 环境下特指将打包的结果jar包或war包安装到本地仓库中。<br>⑦部署 :将打包的结果部署到远程仓库或将war包部署到服务器上运行。</p><h2 id="3-maven程序安装"><a href="#3-maven程序安装" class="headerlink" title="3.maven程序安装"></a>3.maven程序安装</h2><ol><li><p><a href="https://maven.apache.org/download.cgi" target="_blank" rel="noopener">maven下载</a><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffi2t9uvej31vk0mgq7v.jpg" alt=""></p><ul><li>Binary:编译之后的二进制文件</li><li>Source:表示可以查看源代码的,比Binary大一点</li><li>tar.gz archive:Linux、macOS系统使用</li><li>zip archive:windows系统使用</li></ul></li><li><p>解压到本地,注意解压的目录下不要有中文</p></li><li><p>配置环境变量</p><ul><li><p>mac<br>打开terminel输入以下命令:<code>vim ~/.bash_profile</code>打开.bash_profile文件,在次文件中添加设置环境变量的命令</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">export M2_HOME= ***这里换成自己解压maven的地址***</span><br><span class="line">//示例:export M2_HOME=/Users/XXX/Maven/apache-maven-3.6.3</span><br><span class="line">export PATH=$PATH:$M2_HOME/bin</span><br></pre></td></tr></table></figure><p> 添加之后保存并推出,执行以下命令使配置生效:<code>source ~/.bash_profile</code><br> mac中解决<code>source ~/.bash_profile</code>关闭终端后在打开不生效的问题,需要在~/.zshrc文件最后,增加一行:<code>source ~/.bash_profile</code>。如果没有此文件可以使用<code>vim ~/.zshr</code>新建一个文件,在添加对应的命令</p></li><li><p>win<br> 参考<a href="https://blog.csdn.net/weixin_41557632/article/details/78939663" target="_blank" rel="noopener">WIN10下安装配置mave</a>文章进行配置</p></li></ul></li></ol><h2 id="4-配置maven本地仓库"><a href="#4-配置maven本地仓库" class="headerlink" title="4.配置maven本地仓库"></a>4.配置maven本地仓库</h2><h3 id="4-1-仓库的分类"><a href="#4-1-仓库的分类" class="headerlink" title="4.1 仓库的分类"></a>4.1 仓库的分类</h3><ol><li>本地仓库:为当前本机电脑上的所有Maven工程服务。</li><li>远程仓库<ul><li>私服:架设在当前局域网环境下,为当前局域网范围内的所有Maven工程服务。<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffiq931w6j30ie06h0ta.jpg" alt=""></li><li>中央仓库:架设在 Internet 上,为全世界所有Maven工程服务。</li><li>中央仓库的镜像:架设在各个大洲,为中央仓库分担流量。减轻中央仓库的压力,同时更快的响应用户请求。</li></ul></li></ol><h3 id="4-2-本地仓库的配置"><a href="#4-2-本地仓库的配置" class="headerlink" title="4.2 本地仓库的配置"></a>4.2 本地仓库的配置</h3><p>在 conf/setting.xml的文件中更改默认的仓库位置,也就是我们jar包下载后存放的位置</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><!--需要添加的配置--></span><br><span class="line"> <localRepository>/Users/wangyufei/Maven/repository</localRepository></span><br></pre></td></tr></table></figure><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffj8b8m19j316s0n0gqp.jpg" alt=""></p><h2 id="5-maven的标准目录结构"><a href="#5-maven的标准目录结构" class="headerlink" title="5.maven的标准目录结构"></a>5.maven的标准目录结构</h2><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffu24cncjj30pt0bntbh.jpg" alt=""></p><h2 id="6-maven的常用命令"><a href="#6-maven的常用命令" class="headerlink" title="6.maven的常用命令"></a>6.maven的常用命令</h2><h3 id="6-1-clean命令"><a href="#6-1-clean命令" class="headerlink" title="6.1 clean命令"></a>6.1 clean命令</h3><p>清除编译产生的target文件夹内容,可以配合相应命令一起使用,如mvn clean package, mvn clean test</p><h3 id="6-2-complie命令"><a href="#6-2-complie命令" class="headerlink" title="6.2 complie命令"></a>6.2 complie命令</h3><p>该命令可以对src/main/java目录的下的代码进行编译</p><h3 id="6-3-test命令"><a href="#6-3-test命令" class="headerlink" title="6.3 test命令"></a>6.3 test命令</h3><p>测试命令,或执行src/test/java/下junit的测试用例</p><h3 id="6-4-package命令"><a href="#6-4-package命令" class="headerlink" title="6.4 package命令"></a>6.4 package命令</h3><p>mvn package,打包项目</p><h3 id="6-5-install命令"><a href="#6-5-install命令" class="headerlink" title="6.5 install命令"></a>6.5 install命令</h3><p>mvn install,打包后将其安装在本地仓库</p><h2 id="7-maven的生命周期"><a href="#7-maven的生命周期" class="headerlink" title="7. maven的生命周期"></a>7. maven的生命周期</h2><h3 id="7-1-Maven-有三套相互独立的生命周期"><a href="#7-1-Maven-有三套相互独立的生命周期" class="headerlink" title="7.1 Maven 有三套相互独立的生命周期"></a>7.1 Maven 有三套相互独立的生命周期</h3><ol><li>Clean Lifecycle 在进行真正的构建之前进行一些清理工作。</li><li>Default Lifecycle 构建的核心部分,编译,测试,打包,安装,部署等等。</li><li>Site Lifecycle 生成项目报告,站点,发布站点。<br>它们是相互独立的,你可以仅仅调用<br>clean 来清理工作目录,仅仅调用 site 来生 成站点。 当然你也可以<br>直接运行 mvn clean install site 运行所有这三套生命周期。</li></ol><h2 id="8-maven的概念模型图"><a href="#8-maven的概念模型图" class="headerlink" title="8. maven的概念模型图"></a>8. maven的概念模型图</h2><h3 id="8-1-POM"><a href="#8-1-POM" class="headerlink" title="8.1 POM"></a>8.1 POM</h3><p>Project Object Model:项目对象模型。将 Java 工程 的相关信息封装为 对象 作为便于操作和管理的 模型 。Maven 工程的核心配置。可以说学习Maven 就是学习 pom.xml 文件中的配置。</p><h3 id="8-2-Maven-的坐标"><a href="#8-2-Maven-的坐标" class="headerlink" title="8.2 Maven 的坐标"></a>8.2 Maven 的坐标</h3><p>使用如下三个向量在Maven的仓库中唯一的确定一个Maven工程。</p><ol><li><p>groupid:公司或组织的域名倒序当前项目名称</p></li><li><p>artifactId:当前项目的模块名称</p></li><li><p>version:当前模块的版本</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><groupId>org.example</groupId></span><br><span class="line"><artifactId>wugujiawebmaven</artifactId></span><br><span class="line"><version>1.0-SNAPSHOT</version></span><br></pre></td></tr></table></figure></li></ol><h3 id="8-3-如何通过坐标到仓库中查找-jar包"><a href="#8-3-如何通过坐标到仓库中查找-jar包" class="headerlink" title="8.3 如何通过坐标到仓库中查找 jar包"></a>8.3 如何通过坐标到仓库中查找 jar包</h3><ol><li>将 gav 三个向量连起来<code>org.example+wugujiawebmaven+1.0-SNAPSHOT</code></li><li>以连起来的字符串作为目录结构到仓库中查找<code>org/example/wugujiawebmaven/1.0-SNAPSHOT</code></li></ol><p><strong><em>※注意:我们自己的Maven工程必须执行安装操作才会进入仓库 。安装的命令是: mvn install</em></strong></p><h2 id="9-idea集成maven插件"><a href="#9-idea集成maven插件" class="headerlink" title="9. idea集成maven插件"></a>9. idea集成maven插件</h2><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffrb1dkjqj31c00u07wh.jpg" alt=""><br>配置创建java工程<code>-DarchetypeCatalog=local</code> 是为了防止在无网络的情况下可是使用本地已经下载好的maven的骨架<br>配置路径如下:<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffreyumrvj314f0u0tf8.jpg" alt=""></p><h2 id="10-使用骨架创建maven的java工程"><a href="#10-使用骨架创建maven的java工程" class="headerlink" title="10. 使用骨架创建maven的java工程"></a>10. 使用骨架创建maven的java工程</h2><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffri7ezbpj31iu0u0k3u.jpg" alt=""></p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffrkwyag3j31i50u079a.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffrnc34uej31gz0u00xc.jpg" alt=""></p><h2 id="11-不实用骨架创建maven的java工程"><a href="#11-不实用骨架创建maven的java工程" class="headerlink" title="11. 不实用骨架创建maven的java工程"></a>11. 不实用骨架创建maven的java工程</h2><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffrtdfg0nj31h70u0gyf.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffrtxvpltj31ne0t0whp.jpg" alt=""></p><h2 id="12-使用骨架创建maven的web工程"><a href="#12-使用骨架创建maven的web工程" class="headerlink" title="12. 使用骨架创建maven的web工程"></a>12. 使用骨架创建maven的web工程</h2><ol><li>创建web工程<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffryrg9q3j31h40u0aom.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffs07au3bj31i30u00wt.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffs0ll4c2j31hf0u079r.jpg" alt=""></li><li>创建好的javaweb工程(图1),所以我们需要手动添加一个java的目录用于编写java代码(图2),还要将java目录添加为Source Root(图3)<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffs5okhm8j317m0m4e81.jpg" alt="图1"><br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffs77nvf6j31h40u0x6p.jpg" alt="图2"><br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffs9f0i5cj312h0u0b2a.jpg" alt="图3"></li></ol><h2 id="13-创建自定义的JavaWeb工程"><a href="#13-创建自定义的JavaWeb工程" class="headerlink" title="13. 创建自定义的JavaWeb工程"></a>13. 创建自定义的JavaWeb工程</h2><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gfft5u46n5j31hb0u0dqk.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gfft6zy94pj31ih0u0gsk.jpg" alt=""><br>创建web工程信息<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gfft8j06icj30u00wt4qp.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gffta8mvonj31080u07am.jpg" alt=""><br>创建好的javaweb工程目录如图所示<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gfftb47ep7j326i0qwqv6.jpg" alt=""></p><h2 id="14-idea中执行maven的命令"><a href="#14-idea中执行maven的命令" class="headerlink" title="14.idea中执行maven的命令"></a>14.idea中执行maven的命令</h2><ol><li>clean、test、complie、package、install的命令输入方法相同<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gfftegsyzaj31a50u0kjl.jpg" alt=""></li></ol><h2 id="15-Maven插件"><a href="#15-Maven插件" class="headerlink" title="15. Maven插件"></a>15. Maven插件</h2><p>Maven是一个核心引擎,提供了基本的项目处理能力和建设过程的管理,以及一系列的插件是用来执行实际建设任务。maven插件可以完成一些特定的功能。例如,集成jdk插件可以方便的修改项目的编译环境;集成tomcat插件后,无需安装tomcat服务器就可以运行tomcat进行项目的发布与测试。在pom.xml中通过plugin标签引入maven的功能插件。</p><h3 id="15-1-JDK编译版本的插件"><a href="#15-1-JDK编译版本的插件" class="headerlink" title="15.1 JDK编译版本的插件"></a>15.1 JDK编译版本的插件</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><!-- jdk版本插件 --></span><br><span class="line"><plugin></span><br><span class="line"> <groupId>org.apache.maven.plugins</groupId></span><br><span class="line"> <artifactId>maven-compiler-plugin</artifactId></span><br><span class="line"> <version>3.2</version></span><br><span class="line"> <configuration></span><br><span class="line"> <source>1.8</source></span><br><span class="line"> <target>1.8</target></span><br><span class="line"> <encoding>UTF-8</encoding></span><br><span class="line"> <showWarnings>true</showWarnings></span><br><span class="line"> </configuration></span><br><span class="line"></plugin></span><br></pre></td></tr></table></figure><h3 id="15-2-Tomcat7服务端的插件"><a href="#15-2-Tomcat7服务端的插件" class="headerlink" title="15.2 Tomcat7服务端的插件"></a>15.2 Tomcat7服务端的插件</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><!-- tomcat7插件 --></span><br><span class="line"><plugin></span><br><span class="line"> <groupId>org.apache.tomcat.maven</groupId></span><br><span class="line"> <artifactId>tomcat7-maven-plugin</artifactId></span><br><span class="line"> <version>2.1</version></span><br><span class="line"> <configuration></span><br><span class="line"> <port>8080</port></span><br><span class="line"> <server>tomcat7</server></span><br><span class="line"> </configuration></span><br><span class="line"></plugin></span><br></pre></td></tr></table></figure><p><strong><em>tomcat插件注意问题</em></strong><br>Maven的中央仓库中只有Tomcat7.X版本的插件,而之前我们使用的是8.X的版本,如果想使用Tomcat8.X的插件可以去其他第三方仓库进行寻找,或者使用IDEA集成外部Tomcat8极其以上版本,进行项目的发布</p><h2 id="16-依赖范围"><a href="#16-依赖范围" class="headerlink" title="16. 依赖范围"></a>16. 依赖范围</h2><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gfftnby1jsj30dn07g0sq.jpg" alt=""></p><ul><li>compile 编译、测试、运行,A在编译时依赖B,并且在测试和运行时也依赖<br> strus-core、spring-beans。打到war包或jar包</li><li>provided 编译、和测试有效,A在编译和测试时需要B<br> servlet-api就是编译和测试有用,在运行时不用(tomcat容器已提供)<br>不会打到war</li><li>runtime:测试、运行有效<br> 在运行和测试时需要通过jdbc驱动包(mysql驱动)连接数据库,需要的会打到war</li><li>test:只是测试有效,只在单元测试类中用<br> 例如:junit 不会打到war</li><li>按照依赖强度,由强到弱来排序:(理解)<br> compile> provided> runtime> test</li></ul><h2 id="17-maven倒入jar包冲突解决"><a href="#17-maven倒入jar包冲突解决" class="headerlink" title="17. maven倒入jar包冲突解决"></a>17. maven倒入jar包冲突解决</h2><ol><li>路径最短者优先<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gffzi2u0s7j30dw03oaah.jpg" alt=""></li><li>路径相同时先声明者优先。这里声明的先后顺序指的是dependency标签配置的先后顺序。<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gffzigrc5cj30di03caae.jpg" alt=""></li><li>使用<code><exclusions></code>标签排除</li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><dependency></span><br><span class="line"> <groupId>com.a tguigu.maven</groupId></span><br><span class="line"> <artifactId>HelloFriend</artifactId></span><br><span class="line"> <version>0.0.1 SNAPSHOT</version></span><br><span class="line"> <type>jar</type></span><br><span class="line"> <scope>compile</scope></span><br><span class="line"> <exclusions></span><br><span class="line"> <exclusion></span><br><span class="line"> <groupId>commons logging</groupId></span><br><span class="line"> <artifactId>commons logging</artifactId></span><br><span class="line"> </exclusion></span><br><span class="line"> </exclusions></span><br><span class="line"></dependency></span><br></pre></td></tr></table></figure><h2 id="18-统一管理所依赖的版本"><a href="#18-统一管理所依赖的版本" class="headerlink" title="18. 统一管理所依赖的版本"></a>18. 统一管理所依赖的版本</h2><p>对同一个框架的一组jar包最好使用相同的版本。为了方便升级框架,可以将 jar 包的版本信息统一提取出来</p><ol><li><p>统一声明版本号</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"> //其中</span><br><span class="line">atguigu.spring.version 部分 是自定义标签</span><br><span class="line"> <properties></span><br><span class="line"> <atguigu.spring.version>4.1.1.RELEASE</atguigu.s pring.version></span><br><span class="line"></properties></span><br></pre></td></tr></table></figure></li><li><p>引用前面声明的版本号</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"> <dependencies></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework</groupId></span><br><span class="line"> <artifactId>springcore</artifactId></span><br><span class="line"> <version>${atguigu.spring. version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> ……</span><br><span class="line"></dependencies></span><br></pre></td></tr></table></figure></li><li><p>完整示例</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"><project xmlns="http://maven.apache.org/POM/4.0.0"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"></span><br><span class="line"> <modelVersion>4.0.0</modelVersion></span><br><span class="line"> <groupId>com.itheima</groupId></span><br><span class="line"> <artifactId>ssm_parent_331</artifactId></span><br><span class="line"> <packaging>pom</packaging></span><br><span class="line"> <version>1.0-SNAPSHOT</version></span><br><span class="line"> <modules></span><br><span class="line"> <module>ssm_dao_331</module></span><br><span class="line"> <module>ssm_service_331</module></span><br><span class="line"> <module>ssm_web_331</module></span><br><span class="line"> <module>ssm_domain_331</module></span><br><span class="line"> <module>ssm_utils_331</module></span><br><span class="line"> </modules></span><br><span class="line"> <properties></span><br><span class="line"> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></span><br><span class="line"> <maven.compiler.source>1.7</maven.compiler.source></span><br><span class="line"> <maven.compiler.target>1.7</maven.compiler.target></span><br><span class="line"> <spring.version>5.0.2.RELEASE</spring.version></span><br><span class="line"> <spring.security.version>5.0.2.RELEASE</spring.security.version></span><br><span class="line"> </properties></span><br><span class="line"> <dependencies></span><br><span class="line"> <!-- spring相关的jar包 --></span><br><span class="line"> <!-- 容器 --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework</groupId></span><br><span class="line"> <artifactId>spring-context</artifactId></span><br><span class="line"> <version>${spring.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- 事务 --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework</groupId></span><br><span class="line"> <artifactId>spring-tx</artifactId></span><br><span class="line"> <version>${spring.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- JDBC --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework</groupId></span><br><span class="line"> <artifactId>spring-jdbc</artifactId></span><br><span class="line"> <version>${spring.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- 测试 --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework</groupId></span><br><span class="line"> <artifactId>spring-test</artifactId></span><br><span class="line"> <version>${spring.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- springMVC --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework</groupId></span><br><span class="line"> <artifactId>spring-webmvc</artifactId></span><br><span class="line"> <version>${spring.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- mybatis --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.mybatis</groupId></span><br><span class="line"> <artifactId>mybatis</artifactId></span><br><span class="line"> <version>3.4.5</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- mybatis与Spring整合 --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.mybatis</groupId></span><br><span class="line"> <artifactId>mybatis-spring</artifactId></span><br><span class="line"> <version>1.3.1</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- AOP切面 --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.aspectj</groupId></span><br><span class="line"> <artifactId>aspectjweaver</artifactId></span><br><span class="line"> <version>1.8.7</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- 数据源 --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.alibaba</groupId></span><br><span class="line"> <artifactId>druid</artifactId></span><br><span class="line"> <version>1.1.9</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- 单元测试 --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>junit</groupId></span><br><span class="line"> <artifactId>junit</artifactId></span><br><span class="line"> <version>4.12</version></span><br><span class="line"> <scope>test</scope></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- servletAPI --></span><br><span class="line"> <!-- JSP应用 --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>javax.servlet</groupId></span><br><span class="line"> <artifactId>jsp-api</artifactId></span><br><span class="line"> <version>2.0</version></span><br><span class="line"> <scope>provided</scope></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- servlet应用 --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>javax.servlet</groupId></span><br><span class="line"> <artifactId>servlet-api</artifactId></span><br><span class="line"> <version>2.5</version></span><br><span class="line"> <scope>provided</scope></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- 日志记录工具 --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>log4j</groupId></span><br><span class="line"> <artifactId>log4j</artifactId></span><br><span class="line"> <version>1.2.17</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.apache.logging.log4j</groupId></span><br><span class="line"> <artifactId>log4j-api</artifactId></span><br><span class="line"> <version>2.10.0</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.apache.logging.log4j</groupId></span><br><span class="line"> <artifactId>log4j-core</artifactId></span><br><span class="line"> <version>2.10.0</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.apache.logging.log4j</groupId></span><br><span class="line"> <artifactId>log4j-web</artifactId></span><br><span class="line"> <version>2.9.1</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.slf4j</groupId></span><br><span class="line"> <artifactId>slf4j-api</artifactId></span><br><span class="line"> <version>1.7.25</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.apache.logging.log4j</groupId></span><br><span class="line"> <artifactId>log4j-slf4j-impl</artifactId></span><br><span class="line"> <version>2.9.1</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.apache.logging.log4j</groupId></span><br><span class="line"> <artifactId>log4j-jcl</artifactId></span><br><span class="line"> <version>2.9.1</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- mysql --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>mysql</groupId></span><br><span class="line"> <artifactId>mysql-connector-java</artifactId></span><br><span class="line"> <version>5.1.6</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!--oracle的jar包--></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.oracle</groupId></span><br><span class="line"> <artifactId>ojdbc14</artifactId></span><br><span class="line"> <version>10.2.0.2.0</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- JSTL --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>jstl</groupId></span><br><span class="line"> <artifactId>jstl</artifactId></span><br><span class="line"> <version>1.2</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>taglibs</groupId></span><br><span class="line"> <artifactId>standard</artifactId></span><br><span class="line"> <version>1.1.1</version></span><br><span class="line"> </dependency></span><br><span class="line"> <!-- 文件上传 --></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>commons-fileupload</groupId></span><br><span class="line"> <artifactId>commons-fileupload</artifactId></span><br><span class="line"> <version>1.3.1</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>commons-io</groupId></span><br><span class="line"> <artifactId>commons-io</artifactId></span><br><span class="line"> <version>2.5</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>c3p0</groupId></span><br><span class="line"> <artifactId>c3p0</artifactId></span><br><span class="line"> <version>0.9.1.2</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>com.github.pagehelper</groupId></span><br><span class="line"> <artifactId>pagehelper</artifactId></span><br><span class="line"> <version>5.1.2</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.security</groupId></span><br><span class="line"> <artifactId>spring-security-web</artifactId></span><br><span class="line"> <version>${spring.security.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.security</groupId></span><br><span class="line"> <artifactId>spring-security-config</artifactId></span><br><span class="line"> <version>${spring.security.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.security</groupId></span><br><span class="line"> <artifactId>spring-security-core</artifactId></span><br><span class="line"> <version>${spring.security.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> <dependency></span><br><span class="line"> <groupId>org.springframework.security</groupId></span><br><span class="line"> <artifactId>spring-security-taglibs</artifactId></span><br><span class="line"> <version>${spring.security.version}</version></span><br><span class="line"> </dependency></span><br><span class="line"> </dependencies></span><br><span class="line"></project></span><br></pre></td></tr></table></figure></li></ol><h2 id="19-maven工程的拆分与聚合"><a href="#19-maven工程的拆分与聚合" class="headerlink" title="19. maven工程的拆分与聚合"></a>19. maven工程的拆分与聚合</h2><h3 id="19-1-创建父工程-只需要有pom-xnl文件"><a href="#19-1-创建父工程-只需要有pom-xnl文件" class="headerlink" title="19.1 创建父工程(只需要有pom.xnl文件)"></a>19.1 创建父工程(只需要有pom.xnl文件)</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfg1lp5p48j31ih0u0wrb.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfg1nppqvjj31i50u0gqy.jpg" alt=""><br>父工程中可以将<code>src</code>的文件夹删除掉,只留下<code>pom.xml</code>文件<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfg1prv2npj31fy0u01ky.jpg" alt=""></p><h3 id="19-2-子模块的创建"><a href="#19-2-子模块的创建" class="headerlink" title="19.2 子模块的创建"></a>19.2 子模块的创建</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfg1s2lmzmj310i0u01ky.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfg1tfvpygj31io0u013q.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfg1upasaqj31ij0u0ted.jpg" alt=""></p><h3 id="19-3-工程和模块的区别"><a href="#19-3-工程和模块的区别" class="headerlink" title="19.3 工程和模块的区别"></a>19.3 工程和模块的区别</h3><p>区别:</p><ol><li>工程不等于完整的项目,模块也不等于一个完整的项目。代码完整,就可以说这是一个完整的项目和此项目和模块没有关系</li><li>工程只能使用自己的内部资源,工程天生时独立的。后天可以和其他工程和模块建立关联关系</li><li>模块天生是属于父工程的,模块一旦创建,所有父工程的资源都可以使用</li></ol><p>关系:</p><ol><li>父子工程中,子模块天生集成父工程,可以使用父工程所有的资源</li><li>子模块之间是没有关联的</li><li>子模块之间可以使用<code>denpendency</code>之间来互相引用,建立关联</li><li>平级之间引用叫做依赖,依赖不是先天的,是后天建立的</li><li>父子工程之间不用建立关系,继承关系是先天的,不需要手动建立</li></ol><h3 id="19-4-maven父子工程三种启动方式"><a href="#19-4-maven父子工程三种启动方式" class="headerlink" title="19.4 maven父子工程三种启动方式"></a>19.4 maven父子工程三种启动方式</h3><ol><li>可以在父工程中使用 mvn run</li><li>使用web模块中启动时,需要先将其依赖的jar发布到本地仓库或者远程仓库中</li><li>添加本地的tomcat,不在使用maven中自带的tomcat</li></ol><h3 id="19-5-搭建maven的私服环境"><a href="#19-5-搭建maven的私服环境" class="headerlink" title="19.5 搭建maven的私服环境"></a>19.5 搭建maven的私服环境</h3><ol><li><p>下载<a href=":http://www.sonatype.org/nexus/archived/">nexus</a><br>Nexus 是Maven仓库管理器,通过nexus可以搭建maven仓库,同时nexus还提供强大的仓库管理功能,构件搜索功能等。</p></li><li><p>Centos7上搭建私服</p><ul><li><p>上传到Centos7服务器<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfg5gm5vknj31iw0fojv2.jpg" alt=""></p></li><li><p>使用命令<code>tar -avxf nexus-3.23.0-03-unix.tar.gz</code>解压完成后会出现一下两个文件(一个是nexus服务,一个是私有仓库)<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfg5iheh9tj31gg0f60wc.jpg" alt=""></p></li><li><p>修改默认的端口<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfg72x96olj31fo0gigoo.jpg" alt=""></p></li><li><p>启动nexus<br>启动 Nexus(默认端口是8081),Nexus 常用的一些命令包括:/nexus-3.23.0-03/bin/nexus {start|stop|run|run-redirect|status|restart|force-reload},下面我们启动Nexus: </p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">WARNING: ************************************************************</span><br><span class="line">WARNING: Detected execution as "root" user. This is NOT recommended!</span><br><span class="line">WARNING: ************************************************************</span><br><span class="line">Starting nexus</span><br></pre></td></tr></table></figure><p>上面在启动过程中出现警告:“不推荐使用root用户启动”。这个警告不影响Nexus的正常访问和使用。 如果上面的环境变量配置了,试着修改</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/bin/nexus.rc文件中的run_as_user= “root”</span><br></pre></td></tr></table></figure><h3 id="19-6-私服的应用"><a href="#19-6-私服的应用" class="headerlink" title="19.6 私服的应用"></a>19.6 私服的应用</h3><h4 id="19-6-1-账号和密码是固定的-admin-admin123"><a href="#19-6-1-账号和密码是固定的-admin-admin123" class="headerlink" title="19.6.1 账号和密码是固定的 admin/admin123"></a>19.6.1 账号和密码是固定的 admin/admin123</h4><h4 id="19-6-2-登陆私服的配置-server-xml"><a href="#19-6-2-登陆私服的配置-server-xml" class="headerlink" title="19.6.2 登陆私服的配置(server.xml)"></a>19.6.2 登陆私服的配置(server.xml)</h4> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><server></span><br><span class="line"> <id>releases</id></span><br><span class="line"> <username>admin</username></span><br><span class="line"> <password>admin123</password></span><br><span class="line"> </server></span><br><span class="line"> <server></span><br><span class="line"> <id>snapshots</id></span><br><span class="line"> <username>admin</username></span><br><span class="line"> <password>admin123</password></span><br><span class="line"> </server></span><br></pre></td></tr></table></figure><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfgc8gj788j31a80lwjvk.jpg" alt=""></p></li></ul></li></ol><h4 id="19-6-3-配置项目pom-xml"><a href="#19-6-3-配置项目pom-xml" class="headerlink" title="19.6.3 配置项目pom.xml"></a>19.6.3 配置项目pom.xml</h4><p>配置私服仓库的地址,本公司的自己的jar包会上传到私服的宿主仓库,根据工程的版本号决定上传到哪个宿主仓库,如果版本为release则上传到私服的release仓库,如果版本为snapshot则上传到私服的snapshot仓库</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><distributionManagement></span><br><span class="line"> <repository></span><br><span class="line"> <id>release</id></span><br><span class="line"> <name>Release Repository</name></span><br><span class="line"> <url>http://ip/nexus/content/repositories/releases</url></span><br><span class="line"> </repository></span><br><span class="line"> <snapshotRepository></span><br><span class="line"> <id>snapshot</id></span><br><span class="line"> <name>Snapshot Repository</name></span><br><span class="line"> <url>http://ip/nexus/content/repositories/snapshots</url></span><br><span class="line"> </snapshotRepository></span><br><span class="line"></distributionManagement></span><br></pre></td></tr></table></figure><p><strong><em>注意:pom.xml这里<id> 和 settings.xml 配置 <id> 对应!</em></strong></p><h4 id="19-6-4-相关jar包的下载"><a href="#19-6-4-相关jar包的下载" class="headerlink" title="19.6.4 相关jar包的下载"></a>19.6.4 相关jar包的下载</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><!-- 下载jar包配置 --></span><br><span class="line"><profile> </span><br><span class="line"><!--profile的id --></span><br><span class="line"><id>dev</id></span><br><span class="line"><repositories></span><br><span class="line"><repository> <!--仓库id,repositories可以配置多个仓库,保证id不重复 --></span><br><span class="line"><id>nexus</id> <!--仓库地址,即nexus仓库组的地址 --></span><br><span class="line"><url>http://localhost:8081/nexus/content/groups/public/</url> <!--是否下载releases构件 --></span><br><span class="line"><releases></span><br><span class="line"><enabled>true</enabled></span><br><span class="line"></releases> <!--是否下载snapshots构件 --></span><br><span class="line"><snapshots></span><br><span class="line"><enabled>true</enabled></span><br><span class="line"></snapshots></span><br><span class="line"></repository></span><br><span class="line"></repositories></span><br><span class="line"><pluginRepositories> <!-- 插件仓库,maven的运行依赖插件,也需要从私服下载插件 --></span><br><span class="line"><pluginRepository> <!-- 插件仓库的id不允许重复,如果重复后边配置会覆盖前边 --></span><br><span class="line"><id>public</id></span><br><span class="line"><name>Public Repositories</name></span><br><span class="line"><url>http://localhost:8081/nexus/content/groups/public/</url></span><br><span class="line"></pluginRepository></span><br><span class="line"></pluginRepositories></span><br><span class="line"></profile></span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><activeProfiles></span><br><span class="line"><activeProfile>dev</activeProfile></span><br><span class="line"></activeProfiles></span><br></pre></td></tr></table></figure><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfgcmn2bayj311r0u0qit.jpg" alt=""></p><h4 id="19-6-5-安装第三方jar包到本地仓库和私服"><a href="#19-6-5-安装第三方jar包到本地仓库和私服" class="headerlink" title="19.6.5 安装第三方jar包到本地仓库和私服"></a>19.6.5 安装第三方jar包到本地仓库和私服</h4><ol><li>安装第三方jar包到本地仓库</li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">----进入jar包所在目录运行</span><br><span class="line">mvn install:install-file -DgroupId=com.alibaba -DartifactId=fastjson -Dversion=1.1.37 -Dfile=fastjson-1.1.37.jar -Dpackaging=jar</span><br><span class="line">----打开cmd直接运行</span><br><span class="line">mvn install:install-file -DgroupId=com.alibaba -DartifactId=fastjson -Dversion=1.1.37 -Dpackaging=jar -Dfile=C:\my_java\授课资料\资料:maven【高级】\安装第三方jar包\fastjson-1.1.37.jar</span><br></pre></td></tr></table></figure><ol><li>安装第三方jar包到私服</li></ol><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">--在settings配置文件中添加登录私服第三方登录信息</span><br><span class="line"><server></span><br><span class="line"><id>thirdparty</id></span><br><span class="line"><username>admin</username></span><br><span class="line"><password>admin123</password></span><br><span class="line"></server></span><br><span class="line">----进入jar包所在目录运行</span><br><span class="line">mvn deploy:deploy-file -DgroupId=com.alibaba -DartifactId=fastjson -Dversion=1.1.37 -Dpackaging=jar -Dfile=fastjson-1.1.37.jar -Durl=http://localhost:8081/nexus/content/repositories/thirdparty/ -DrepositoryId=thirdparty</span><br><span class="line">----打开cmd直接运行</span><br><span class="line">mvn deploy:deploy-file -DgroupId=com.alibaba -DartifactId=fastjson -Dversion=1.1.37 -Dpackaging=jar -Dfile=C:\my_java\授课资料\资料:maven【高级】\安装第三方jar包\fastjson-1.1.37.jar -Durl=http://localhost:8081/nexus/content/repositories/thirdparty/ -DrepositoryId=thirdparty</span><br></pre></td></tr></table></figure><h2 id="20-配置全局的jdk"><a href="#20-配置全局的jdk" class="headerlink" title="20. 配置全局的jdk"></a>20. 配置全局的jdk</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><!--配置全局的jdk为1.8--></span><br><span class="line"> <profile></span><br><span class="line"> <id>jdk-1.8</id> </span><br><span class="line"> <activation></span><br><span class="line"> <activeByDefault>true</activeByDefault></span><br><span class="line"> <jdk>1.8</jdk> </span><br><span class="line"> </activation> </span><br><span class="line"> </span><br><span class="line"> <properties> </span><br><span class="line"> <maven.compiler.source>1.8</maven.compiler.source> </span><br><span class="line"> <maven.compiler.target>1.8</maven.compiler.target> </span><br><span class="line"> <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion> </span><br><span class="line"> </properties> </span><br><span class="line"> </profile></span><br></pre></td></tr></table></figure><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfgd6p48qbj315y0u0qar.jpg" alt=""></p>]]></content>
<summary type="html">
Maven是Apache软件基金会组织维护的一款自动化构建工具专注服务于Java平台的项目构建和依赖管理
</summary>
<category term="java" scheme="http://lwblog.xyz/categories/java/"/>
<category term="maven" scheme="http://lwblog.xyz/tags/maven/"/>
</entry>
<entry>
<title>IDEA中查看maven的依赖关系</title>
<link href="http://lwblog.xyz/posts/c9331070.html"/>
<id>http://lwblog.xyz/posts/c9331070.html</id>
<published>2020-06-05T05:32:58.000Z</published>
<updated>2020-06-05T05:36:44.215Z</updated>
<content type="html"><![CDATA[<h2 id="1-使用maven自带的工具"><a href="#1-使用maven自带的工具" class="headerlink" title="1. 使用maven自带的工具"></a>1. 使用maven自带的工具</h2><h3 id="1-1-确保idea中UML的插件可以使用"><a href="#1-1-确保idea中UML的插件可以使用" class="headerlink" title="1.1 确保idea中UML的插件可以使用"></a>1.1 确保idea中UML的插件可以使用</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfhb2uvgs8j314r0u0afz.jpg" alt=""></p><h3 id="1-2-pom-xml文件依赖分析"><a href="#1-2-pom-xml文件依赖分析" class="headerlink" title="1.2 pom.xml文件依赖分析"></a>1.2 pom.xml文件依赖分析</h3><ol><li>在需要分析的pom.xml文件中右键选择<code>maven</code>-><code>Show Dependencies</code><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfhb5cwrgej30u00zyx6f.jpg" alt=""><br>打开后的图形<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfhbae8o9oj315c0u04qr.jpg" alt=""></li><li>使用技巧<ul><li>按住<code>option</code>,移动鼠标会出现放大镜,放大当前的依赖</li><li>按住<code>control</code>,滚轮向前 放大整个屏幕</li><li>红色实现表示冲突的文件,右键,排除,他就自动在pom文件里面给exclud啦</li><li>红色的虚线表示用一个jar包都在哪里被多次引用</li></ul></li></ol><h2 id="2-使用maven-helper插件"><a href="#2-使用maven-helper插件" class="headerlink" title="2. 使用maven helper插件"></a>2. 使用maven helper插件</h2><ol><li><p>打开需要查看的pom.xml文件,下边会出现<code>Denpendency Anlyzar</code>,点击按钮<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfhbmhob3ij31cm0u01l1.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfhbnq116yj31fk0u0hdw.jpg" alt=""></p></li><li><p>菜单功能</p><ul><li>Conflicts:冲突</li><li>All Dependencies as List:列表形式查看所有依赖</li><li>All Dependencies as Tree:树结构查看所有依赖</li></ul></li><li><p>冲突jar包的解决<br> 切换到maven 依赖视图选择冲突选项,如果有冲突,在左下面区域会有红色显示。<br> 解决冲突,右键单击红色区域,弹出菜单选择Exclude命令,对冲突进行排除<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gfhcdt8upij316c0u0qv7.jpg" alt=""></p></li></ol>]]></content>
<summary type="html">
须待完善
</summary>
<category term="java" scheme="http://lwblog.xyz/categories/java/"/>
<category term="maven" scheme="http://lwblog.xyz/tags/maven/"/>
</entry>
<entry>
<title>Activiti6.0工作流引擎学习(二) -- 引擎配置</title>
<link href="http://lwblog.xyz/posts/1d8f65f1.html"/>
<id>http://lwblog.xyz/posts/1d8f65f1.html</id>
<published>2020-05-28T03:09:05.000Z</published>
<updated>2020-05-28T03:15:06.231Z</updated>
<content type="html"><![CDATA[<h1 id="Activiti6-0工作流引擎学习-二-–-引擎配置"><a href="#Activiti6-0工作流引擎学习-二-–-引擎配置" class="headerlink" title="Activiti6.0工作流引擎学习(二) – 引擎配置"></a>Activiti6.0工作流引擎学习(二) – 引擎配置</h1><h2 id="1-Activiti流程引擎配置涉及的类"><a href="#1-Activiti流程引擎配置涉及的类" class="headerlink" title="1.Activiti流程引擎配置涉及的类"></a>1.Activiti流程引擎配置涉及的类</h2><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gf6rcr6dzaj31b40nw4bp.jpg" alt="Activiti流程引擎配置"></p><h3 id="1-1-流程引擎配置类的作用"><a href="#1-1-流程引擎配置类的作用" class="headerlink" title="1.1 流程引擎配置类的作用"></a>1.1 流程引擎配置类的作用</h3><ol><li>ProcessEngineConfiguration<ul><li>查找并解析xml配置文件activiti.cfg.xml</li><li>提供多个静态方法创建配置对象<br> <img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gf6rna78thj310407mwsc.jpg" alt="静态方法创建配置对象"></li><li>实现几个基于不同场景场景的子类,配置方式非常的灵活<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gf6ry2ub4qj318808oat3.jpg" alt="使用场景"></li></ul></li></ol><h3 id="1-2-部分子类的使用"><a href="#1-2-部分子类的使用" class="headerlink" title="1.2 部分子类的使用"></a>1.2 部分子类的使用</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testConfig1</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="comment">//通过默认来创建引擎;会通过spring的解析进行创建引擎对象</span></span><br><span class="line"> ProcessEngineConfiguration engine</span><br><span class="line"> = ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault();</span><br><span class="line"> log.info(<span class="string">"engine ={}"</span>,engine);</span><br><span class="line"> }</span><br><span class="line"> <span class="meta">@Test</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">testConfig2</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="comment">//直接创建标准的引擎,直接new一个引擎对象</span></span><br><span class="line"> ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();</span><br><span class="line"> log.info(<span class="string">"configuration = {}"</span>,configuration);</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><h2 id="2-数据库配置"><a href="#2-数据库配置" class="headerlink" title="2.数据库配置"></a>2.数据库配置</h2><h3 id="2-1-缺省配置默认,使用H2内存数据库"><a href="#2-1-缺省配置默认,使用H2内存数据库" class="headerlink" title="2.1 缺省配置默认,使用H2内存数据库"></a>2.1 缺省配置默认,使用H2内存数据库</h3><h3 id="2-2-配置JDBC属性,使用mybatis提供的链接池"><a href="#2-2-配置JDBC属性,使用mybatis提供的链接池" class="headerlink" title="2.2 配置JDBC属性,使用mybatis提供的链接池"></a>2.2 配置JDBC属性,使用mybatis提供的链接池</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gf6trk2he0j315o0bydor.jpg" alt=""></p><h3 id="2-3-配置DataSource,可自选第三方实现"><a href="#2-3-配置DataSource,可自选第三方实现" class="headerlink" title="2.3 配置DataSource,可自选第三方实现"></a>2.3 配置DataSource,可自选第三方实现</h3><ol><li>Druid 为监控而生的数据库连接池 来自阿里<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gf6tzwnzmgj31a806awm5.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gf6u1fe54sj319o0c417z.jpg" alt=""></li><li>Dbcp 老牌数据源连接池,稳定可靠,Tomcat自带</li><li>HikariCP 来自日本的极速数据源连接池,Spring默选</li></ol><h3 id="2-4-数据库更新策略"><a href="#2-4-数据库更新策略" class="headerlink" title="2.4 数据库更新策略"></a>2.4 数据库更新策略</h3><ol><li>配置databaseSchemaUpdate<ul><li>false:启动时检查数据库版本,发生不匹配抛异常</li><li>true: 启动时自动检查并甭信数据库表,不存在会创建</li><li>create-drop: 启动时创建数据库表结构,结束时删除表结构</li></ul></li></ol><h3 id="2-5-数据库配置编码"><a href="#2-5-数据库配置编码" class="headerlink" title="2.5 数据库配置编码"></a>2.5 数据库配置编码</h3><h4 id="2-5-1-使用默认的配置文件创建流程引擎"><a href="#2-5-1-使用默认的配置文件创建流程引擎" class="headerlink" title="2.5.1 使用默认的配置文件创建流程引擎"></a>2.5.1 使用默认的配置文件创建流程引擎</h4><p><code>activiti.cfg.xml</code>文件</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?xml version="1.0" encoding="UTF-8"?></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"processEngineConfiguration"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">class</span>=<span class="string">"org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="comment"><!--<property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" /></span></span><br><span class="line"><span class="comment"> <property name="jdbcDriver" value="org.h2.Driver" /></span></span><br><span class="line"><span class="comment"> <property name="jdbcUsername" value="sa" /></span></span><br><span class="line"><span class="comment"> <property name="jdbcPassword" value="" /></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> &lt;!&ndash; Database configurations &ndash;&gt;</span></span><br><span class="line"><span class="comment"> <property name="databaseSchemaUpdate" value="drop-create" /></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> <property name="history" value="full" />--></span></span><br><span class="line"> <span class="tag"></<span class="name">bean</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"></<span class="name">beans</span>></span></span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test1</span><span class="params">()</span></span>{</span><br><span class="line"> ProcessEngineConfiguration configuration =</span><br><span class="line"> ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault();</span><br><span class="line"> log.info(<span class="string">"configuration = {}"</span>,configuration);</span><br><span class="line"> ProcessEngine processEngine = configuration.buildProcessEngine();</span><br><span class="line"> log.info(<span class="string">"获取流程引擎 = [{}]"</span>,processEngine.getName());</span><br><span class="line"> processEngine.close();</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><h4 id="2-5-2-使用druid数据源"><a href="#2-5-2-使用druid数据源" class="headerlink" title="2.5.2 使用druid数据源"></a>2.5.2 使用druid数据源</h4><p>activiti_druid.cfg.xml配置文件</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?xml version="1.0" encoding="UTF-8"?></span></span><br><span class="line"></span><br><span class="line"><span class="tag"><<span class="name">beans</span> <span class="attr">xmlns</span>=<span class="string">"http://www.springframework.org/schema/beans"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xmlns:xsi</span>=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">xsi:schemaLocation</span>=<span class="string">"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"processEngineConfiguration"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">class</span>=<span class="string">"org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="comment"><!--<property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" /></span></span><br><span class="line"><span class="comment"> <property name="jdbcDriver" value="org.h2.Driver" /></span></span><br><span class="line"><span class="comment"> <property name="jdbcUsername" value="sa" /></span></span><br><span class="line"><span class="comment"> <property name="jdbcPassword" value="" /></span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment"> &lt;!&ndash; Database configurations &ndash;&gt;--></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"databaseSchemaUpdate"</span> <span class="attr">value</span>=<span class="string">"drop-create"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"dataSource"</span> <span class="attr">ref</span>=<span class="string">"dataSource"</span>/></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"history"</span> <span class="attr">value</span>=<span class="string">"full"</span> /></span></span><br><span class="line"> <span class="comment"><!--引擎是否使用历史数据--></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"dbHistoryUsed"</span> <span class="attr">value</span>=<span class="string">"true"</span>/></span></span><br><span class="line"> <span class="comment"><!--引擎是否使用身份验证--></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"dbIdentityUsed"</span> <span class="attr">value</span>=<span class="string">"true"</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">bean</span>></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">bean</span> <span class="attr">id</span>=<span class="string">"dataSource"</span> <span class="attr">class</span>=<span class="string">"com.alibaba.druid.pool.DruidDataSource"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"url"</span> <span class="attr">value</span>=<span class="string">"jdbc:mysql://111.229.203.5:3306/activiti?serverTimezone=CTT<span class="symbol">&amp;</span>useUnicode=true<span class="symbol">&amp;</span>characterEncoding=utf-8<span class="symbol">&amp;</span>allowMultiQueries=true"</span>/></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"driverClassName"</span> <span class="attr">value</span>=<span class="string">"com.mysql.cj.jdbc.Driver"</span>/></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"username"</span> <span class="attr">value</span>=<span class="string">"weaver"</span>/></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"password"</span> <span class="attr">value</span>=<span class="string">"192612"</span>/></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"initialSize"</span> <span class="attr">value</span>=<span class="string">"1"</span>/></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"maxActive"</span> <span class="attr">value</span>=<span class="string">"10"</span>/></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"filters"</span> <span class="attr">value</span>=<span class="string">"stat,slf4j"</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">bean</span>></span></span><br><span class="line"></span><br><span class="line"><span class="tag"></<span class="name">beans</span>></span></span><br></pre></td></tr></table></figure><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test2</span><span class="params">()</span></span>{</span><br><span class="line"> ProcessEngineConfiguration configuration =</span><br><span class="line"> ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(<span class="string">"activiti_druid.cfg.xml"</span>);</span><br><span class="line"> log.info(<span class="string">"configuration = {}"</span>,configuration);</span><br><span class="line"> ProcessEngine processEngine = configuration.buildProcessEngine();</span><br><span class="line"> log.info(<span class="string">"获取流程引擎 = [{}]"</span>,processEngine.getName());</span><br><span class="line"> processEngine.close();</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><h2 id="3-日志记录配置"><a href="#3-日志记录配置" class="headerlink" title="3.日志记录配置"></a>3.日志记录配置</h2><h3 id="3-1-日志组件的关系及MDC"><a href="#3-1-日志组件的关系及MDC" class="headerlink" title="3.1 日志组件的关系及MDC"></a>3.1 日志组件的关系及MDC</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gf6z7p2plmj311o0ps194.jpg" alt=""></p><h4 id="3-1-1-配置开启MDC-Mapped-Diagnostic-Contexts"><a href="#3-1-1-配置开启MDC-Mapped-Diagnostic-Contexts" class="headerlink" title="3.1.1 配置开启MDC(Mapped Diagnostic Contexts)"></a>3.1.1 配置开启MDC(Mapped Diagnostic Contexts)</h4><ol><li>默认没有开启,需要手动设置<code>LogMDC.setMDCEnable(true)</code></li><li>配置logback.xml日志模版 <code>%X{mdcProcessInstanceID}</code></li><li>流程只有在执行过程出现异常才会记录MDC信息</li></ol><h3 id="3-2-配置历史记录级别-HistoryLevel"><a href="#3-2-配置历史记录级别-HistoryLevel" class="headerlink" title="3.2 配置历史记录级别(HistoryLevel)"></a>3.2 配置历史记录级别(HistoryLevel)</h3><h4 id="3-2-1-配置HistoryLevel"><a href="#3-2-1-配置HistoryLevel" class="headerlink" title="3.2.1 配置HistoryLevel"></a>3.2.1 配置HistoryLevel</h4><ol><li>none:不记录历史流程,性能高,流程结束后不可读取</li><li>activiti:归档流程实例和活动实例,流程变量不同步</li><li>addit:默认值,在activiti基础上同步变量值,保存表单属性</li><li>full:性能较差,记录所有实例和变量细节变化</li></ol><h3 id="3-3-配置基于db的事件日志-Event-logging"><a href="#3-3-配置基于db的事件日志-Event-logging" class="headerlink" title="3.3 配置基于db的事件日志(Event logging)"></a>3.3 配置基于db的事件日志(Event logging)</h3><h4 id="3-3-1-配置Event-Logging"><a href="#3-3-1-配置Event-Logging" class="headerlink" title="3.3.1 配置Event Logging"></a>3.3.1 配置Event Logging</h4><ol><li>试验性的事件记录机制,性能影响较大</li><li>开启默认记录所有数据的变化过程,表记录快速增长</li><li>日志内容json格式,建议存入mongoDB、Elastic Search</li></ol><h3 id="3-4-日志记录-mdc"><a href="#3-4-日志记录-mdc" class="headerlink" title="3.4 日志记录 mdc"></a>3.4 日志记录 mdc</h3><h2 id="4-历史记录配置"><a href="#4-历史记录配置" class="headerlink" title="4 历史记录配置"></a>4 历史记录配置</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.atguigu.test;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> com.google.common.collect.Maps;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.history.HistoricActivityInstance;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.history.HistoricDetail;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.runtime.Execution;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.runtime.ProcessInstance;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.task.Task;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.test.ActivitiRule;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.test.Deployment;</span><br><span class="line"><span class="keyword">import</span> org.junit.Rule;</span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"><span class="keyword">import</span> org.slf4j.Logger;</span><br><span class="line"><span class="keyword">import</span> org.slf4j.LoggerFactory;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@program</span>: activiti6</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description</span>: 测试MDC</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: Mr.Wang</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@create</span>: 2020-14-31</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TestMDC</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> Logger log = LoggerFactory.getLogger(TestMDC<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line"> <span class="meta">@Rule</span></span><br><span class="line"> <span class="keyword">public</span> ActivitiRule activitiRule = <span class="keyword">new</span> ActivitiRule();</span><br><span class="line"> <span class="meta">@Test</span></span><br><span class="line"> <span class="comment">//定义流程文件部署</span></span><br><span class="line"> <span class="meta">@Deployment</span>(resources = {<span class="string">"my-process.bpmn20.xml"</span>})</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test</span><span class="params">()</span></span>{</span><br><span class="line"> Map<String,Object> params = Maps.newHashMap();</span><br><span class="line"> params.put(<span class="string">"keyStart1"</span>,<span class="string">"value1"</span>);</span><br><span class="line"> params.put(<span class="string">"keyStart2"</span>,<span class="string">"value2"</span>);</span><br><span class="line"> <span class="comment">//启动流程</span></span><br><span class="line"> ProcessInstance processInstance =</span><br><span class="line"> activitiRule.getRuntimeService().startProcessInstanceByKey(<span class="string">"my-process"</span>,params);</span><br><span class="line"> <span class="comment">//修改变量</span></span><br><span class="line"> List<Execution> executions = activitiRule.getRuntimeService().createExecutionQuery().listPage(<span class="number">0</span>, <span class="number">100</span>);</span><br><span class="line"> <span class="keyword">for</span> (Execution execution : executions) {</span><br><span class="line"> log.info(<span class="string">"executions {}"</span>,executions);</span><br><span class="line"> }</span><br><span class="line"> log.info(<span class="string">"executions size = {}"</span>,executions.size());</span><br><span class="line"> String id = executions.iterator().next().getId();</span><br><span class="line"> activitiRule.getRuntimeService().setVariable(id,<span class="string">"keyStart1"</span>,<span class="string">"value1_"</span>);</span><br><span class="line"> <span class="comment">//提交表单task 修改变量</span></span><br><span class="line"> Task task = activitiRule.getTaskService().createTaskQuery().singleResult();</span><br><span class="line"> Map<String,String> properties = Maps.newHashMap();</span><br><span class="line"> properties.put(<span class="string">"formkey1"</span>,<span class="string">"valuef1"</span>);</span><br><span class="line"> properties.put(<span class="string">"formkey2"</span>,<span class="string">"valuef2"</span>);</span><br><span class="line"> activitiRule.getFormService().submitTaskFormData(task.getId(),properties);</span><br><span class="line"> <span class="comment">//activitiRule.getTaskService().complete(task.getId());</span></span><br><span class="line"> <span class="comment">//输出历史活动</span></span><br><span class="line"> List<HistoricActivityInstance> historicActivityInstances = activitiRule.getHistoryService().createHistoricActivityInstanceQuery().listPage(<span class="number">0</span>, <span class="number">100</span>);</span><br><span class="line"> <span class="keyword">for</span> (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {</span><br><span class="line"> log.info(<span class="string">"historicActivityInstances = {}"</span>,historicActivityInstances);</span><br><span class="line"> }</span><br><span class="line"> log.info(<span class="string">"historicActivityInstances size = {}"</span>,historicActivityInstances.size());</span><br><span class="line"></span><br><span class="line"> <span class="comment">//输出历史表单</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">//输出历史详情</span></span><br><span class="line"> List<HistoricDetail> historicDetails = activitiRule.getHistoryService().createHistoricDetailQuery().listPage(<span class="number">0</span>, <span class="number">100</span>);</span><br><span class="line"> <span class="keyword">for</span> (HistoricDetail historicDetail : historicDetails) {</span><br><span class="line"> log.info(<span class="string">"historicDetail [{}]"</span>,historicDetail);</span><br><span class="line"> }</span><br><span class="line"> log.info(<span class="string">"historicDetail size = [{}]"</span>, historicDetails.size());</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="5-事件处理及监听配置-eventlog"><a href="#5-事件处理及监听配置-eventlog" class="headerlink" title="5.事件处理及监听配置-eventlog"></a>5.事件处理及监听配置-eventlog</h2><h3 id="5-1-事件及监听器原理"><a href="#5-1-事件及监听器原理" class="headerlink" title="5.1 事件及监听器原理"></a>5.1 事件及监听器原理</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gf7zqvwqsnj31js0fmq5s.jpg" alt=""></p><h3 id="5-2-监听器的配置方式"><a href="#5-2-监听器的配置方式" class="headerlink" title="5.2 监听器的配置方式"></a>5.2 监听器的配置方式</h3><ol><li>配置Listener<ol><li>eventListeners:监听所有事件派发通知</li><li>typedEventListeners:监听指定事件类型的通知</li><li>activiti:eventListener:只监听特定流程定义的事件<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gf7zr4t5btj31jo0hytck.jpg" alt=""></li></ol></li></ol><h3 id="5-3-Activiti事件监听"><a href="#5-3-Activiti事件监听" class="headerlink" title="5.3 Activiti事件监听"></a>5.3 Activiti事件监听</h3><h4 id="5-3-1-相关API"><a href="#5-3-1-相关API" class="headerlink" title="5.3.1 相关API"></a>5.3.1 相关API</h4><ul><li>ActivitiEvent:事件对象</li><li>ActivitiEventListener:监听器</li><li>ActivitiEventType:事件类型</li></ul><h3 id="5-4-ActivitiEventListener监听器的使用"><a href="#5-4-ActivitiEventListener监听器的使用" class="headerlink" title="5.4 ActivitiEventListener监听器的使用"></a>5.4 ActivitiEventListener监听器的使用</h3><ol><li>配置文件中增加对应的配置</li></ol><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!--配置事件监听器--></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"eventListeners"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">list</span>></span></span><br><span class="line"> <span class="comment"><!--监听器的实现类--></span></span><br><span class="line"> <span class="tag"><<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"com.atguigu.event.ProcessEventListener"</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">list</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">property</span>></span></span><br></pre></td></tr></table></figure><ol start="2"><li>创建一个实体类,实现<code>ActivitiEventListener</code>类</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.atguigu.event;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.activiti.bpmn.model.ActivitiListener;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.delegate.event.ActivitiEvent;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.delegate.event.ActivitiEventListener;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.delegate.event.ActivitiEventType;</span><br><span class="line"><span class="keyword">import</span> org.slf4j.Logger;</span><br><span class="line"><span class="keyword">import</span> org.slf4j.LoggerFactory;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@program</span>: activiti6</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description</span>: 流程监听</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: Mr.Wang</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@create</span>: 2020-05-27-21-26</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ProcessEventListener</span> <span class="keyword">implements</span> <span class="title">ActivitiEventListener</span> </span>{</span><br><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> Logger log = LoggerFactory.getLogger(ProcessEventListener<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onEvent</span><span class="params">(ActivitiEvent event)</span> </span>{</span><br><span class="line"> ActivitiEventType type = event.getType();</span><br><span class="line"> <span class="comment">//判断是是否为流程启动</span></span><br><span class="line"> <span class="keyword">if</span>(ActivitiEventType.PROCESS_STARTED.equals(type)){</span><br><span class="line"> log.info(<span class="string">"流程启动 {}"</span>,event.getProcessInstanceId());</span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(ActivitiEventType.PROCESS_COMPLETED.equals(type)){</span><br><span class="line"> log.info(<span class="string">"流程结束"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isFailOnException</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="5-5-TypedEventListeners监听器的使用"><a href="#5-5-TypedEventListeners监听器的使用" class="headerlink" title="5.5 TypedEventListeners监听器的使用"></a>5.5 TypedEventListeners监听器的使用</h3><ol><li>配置文件</li></ol><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"typedEventListeners"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">map</span>></span></span><br><span class="line"> <span class="comment"><!--这样配置的时候,只会监听流程启动--></span></span><br><span class="line"> <span class="tag"><<span class="name">entry</span> <span class="attr">key</span>=<span class="string">"PROCESS_STARTED"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">list</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"com.atguigu.event.ProcessEventListener"</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">list</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">entry</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">map</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">property</span>></span></span><br></pre></td></tr></table></figure><ol start="2"><li>流程监听实体类</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.atguigu.event;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.activiti.bpmn.model.ActivitiListener;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.delegate.event.ActivitiEvent;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.delegate.event.ActivitiEventListener;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.delegate.event.ActivitiEventType;</span><br><span class="line"><span class="keyword">import</span> org.slf4j.Logger;</span><br><span class="line"><span class="keyword">import</span> org.slf4j.LoggerFactory;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@program</span>: activiti6</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description</span>: 流程监听</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: Mr.Wang</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@create</span>: 2020-05-27-21-26</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ProcessEventListener</span> <span class="keyword">implements</span> <span class="title">ActivitiEventListener</span> </span>{</span><br><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> Logger log = LoggerFactory.getLogger(ProcessEventListener<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onEvent</span><span class="params">(ActivitiEvent event)</span> </span>{</span><br><span class="line"> ActivitiEventType type = event.getType();</span><br><span class="line"> <span class="comment">//判断是是否为流程启动</span></span><br><span class="line"> <span class="keyword">if</span>(ActivitiEventType.PROCESS_STARTED.equals(type)){</span><br><span class="line"> log.info(<span class="string">"流程启动 {}"</span>,event.getProcessInstanceId());</span><br><span class="line"> }<span class="keyword">else</span> <span class="keyword">if</span>(ActivitiEventType.PROCESS_COMPLETED.equals(type)){</span><br><span class="line"> log.info(<span class="string">"流程结束"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isFailOnException</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="comment">//输出的结果为:22:18:38.450 [main] [INFO ]流程启动 4 c.a.e.ProcessEventListener.onEvent:23</span></span><br></pre></td></tr></table></figure><h2 id="6-命令拦截器配置–command"><a href="#6-命令拦截器配置–command" class="headerlink" title="6. 命令拦截器配置–command"></a>6. 命令拦截器配置–command</h2><h3 id="6-1-命令模式与责任链模式"><a href="#6-1-命令模式与责任链模式" class="headerlink" title="6.1 命令模式与责任链模式"></a>6.1 命令模式与责任链模式</h3><h4 id="6-1-1-命令模式"><a href="#6-1-1-命令模式" class="headerlink" title="6.1.1 命令模式"></a>6.1.1 命令模式</h4><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gf7dv4a99yj31dk0qy4bt.jpg" alt=""><br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gf7dx177oaj319e0qo16v.jpg" alt="时序图"></p><h4 id="6-1-2-责任链模式"><a href="#6-1-2-责任链模式" class="headerlink" title="6.1.2 责任链模式"></a>6.1.2 责任链模式</h4><ul><li>CommandInterceptor<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gf7dzxamvhj31fk0ca7ba.jpg" alt=""></li><li>配置Interceptor<ul><li>customPreCommandInterceptors:配置在默认拦截器之前</li><li>customPostCommandInterceptors:配置在默认拦截器之后</li><li>commandInvoker:配置最后的执行器</li></ul></li></ul><h3 id="6-2-拦截器的配置方式"><a href="#6-2-拦截器的配置方式" class="headerlink" title="6.2 拦截器的配置方式"></a>6.2 拦截器的配置方式</h3><ol><li>activiti.cfg.xml文件的修改</li></ol><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"><!--拦截器的配置--></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"customPreCommandInterceptors"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">list</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">bean</span> <span class="attr">class</span>=<span class="string">"com.atguigu.interceptor.DurationInterceptor"</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">list</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">property</span>></span></span><br></pre></td></tr></table></figure><ol start="2"><li>实体类的编写</li></ol><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.atguigu.interceptor;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.impl.interceptor.AbstractCommandInterceptor;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.impl.interceptor.Command;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.impl.interceptor.CommandConfig;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@program</span>: activiti6</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description</span>: 执行的时间</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: Mr.Wang</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@create</span>: 2020-05-27-22-53</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">DurationInterceptor</span> <span class="keyword">extends</span> <span class="title">AbstractCommandInterceptor</span> </span>{</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> <T> <span class="function">T <span class="title">execute</span><span class="params">(CommandConfig config, Command<T> command)</span> </span>{</span><br><span class="line"> <span class="keyword">long</span> l = System.currentTimeMillis();</span><br><span class="line"> <span class="keyword">this</span>.getNext().execute(config,command);</span><br><span class="line"> <span class="keyword">long</span> l1 = System.currentTimeMillis();</span><br><span class="line"> <span class="keyword">long</span> duration = l1 - l;</span><br><span class="line"> System.out.println(<span class="string">"执行的时长----->"</span>+duration);</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">null</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="6-3-Activiti的拦截器"><a href="#6-3-Activiti的拦截器" class="headerlink" title="6.3 Activiti的拦截器"></a>6.3 Activiti的拦截器</h3><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gf7e7154rqj30xw0dekfa.jpg" alt=""></p><h2 id="7-作业执行器-Job-Executor"><a href="#7-作业执行器-Job-Executor" class="headerlink" title="7. 作业执行器 Job Executor"></a>7. 作业执行器 Job Executor</h2><h3 id="7-1-作业执行器配置"><a href="#7-1-作业执行器配置" class="headerlink" title="7.1 作业执行器配置"></a>7.1 作业执行器配置</h3><p>(1) asyncExecutorActivate:激活作业执行器<br>(2) asyncExectuorXXX:异步执行器的属性配置<br>(3) asyncExecutor:异步执行器的bean</p><h3 id="7-2-配置自定义线程池"><a href="#7-2-配置自定义线程池" class="headerlink" title="7.2 配置自定义线程池"></a>7.2 配置自定义线程池</h3><h4 id="7-2-1-自定义线程池ExecutorService"><a href="#7-2-1-自定义线程池ExecutorService" class="headerlink" title="7.2.1 自定义线程池ExecutorService"></a>7.2.1 自定义线程池ExecutorService</h4><p>(1) corePoolSize:核心线程数<br>(2) maxPoolSize: 最大线程数<br>(3) queueCapacity:堵塞队列大小</p><h4 id="7-2-2-基于spring线程池的配置"><a href="#7-2-2-基于spring线程池的配置" class="headerlink" title="7.2.2 基于spring线程池的配置"></a>7.2.2 基于spring线程池的配置</h4><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gf7wkem35qj31580ben91.jpg" alt=""></p><h3 id="7-3-流程定义定时启动流程"><a href="#7-3-流程定义定时启动流程" class="headerlink" title="7.3 流程定义定时启动流程"></a>7.3 流程定义定时启动流程</h3><h4 id="7-3-1-定时开始事件"><a href="#7-3-1-定时开始事件" class="headerlink" title="7.3.1 定时开始事件"></a>7.3.1 定时开始事件</h4><ol><li>timeDate:指定启动时间</li><li>timeDuration:指定持续时间间隔后执行</li><li>timeCycle:R5/P1DT1H指定事件段后周期执行</li></ol><h3 id="7-4-配置文件修改"><a href="#7-4-配置文件修改" class="headerlink" title="7.4 配置文件修改"></a>7.4 配置文件修改</h3><p>activiti.cfg.xml文件修改</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><bean id="processEngineConfiguration"</span><br><span class="line"> class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"></span><br><span class="line"> <!--打开定时任务的激活器--></span><br><span class="line"> <property name="asyncExecutorActivate" value="true"/></span><br><span class="line"> <!--定义异步执行器--></span><br><span class="line"> <property name="asyncExecutor" ref="defaultAsyncJobExecutor"/></span><br><span class="line"> </bean></span><br><span class="line"> <!--系统默认的自定义任务执行器--></span><br><span class="line"> <bean id = "defaultAsyncJobExecutor" class="org.activiti.engine.impl.asyncexecutor.DefaultAsyncJobExecutor"></span><br><span class="line"> <!--需要的服务--></span><br><span class="line"> <property name="executorService" ref="executorService"/></span><br><span class="line"> </bean></span><br><span class="line"> <!--使用spring的线程池--></span><br><span class="line"> <bean id = "executorService" class="org.springframework.scheduling.concurrent.ThreadPoolExecutorFactoryBean"></span><br><span class="line"> <!--具体的配置--></span><br><span class="line"> </bean></span><br></pre></td></tr></table></figure><h2 id="8-Activiti与Spring的集成"><a href="#8-Activiti与Spring的集成" class="headerlink" title="8 Activiti与Spring的集成"></a>8 Activiti与Spring的集成</h2><h3 id="8-1-集成Spring配置"><a href="#8-1-集成Spring配置" class="headerlink" title="8.1 集成Spring配置"></a>8.1 集成Spring配置</h3><h4 id="8-1-1-相关配置"><a href="#8-1-1-相关配置" class="headerlink" title="8.1.1 相关配置"></a>8.1.1 相关配置</h4><p>(1) 添加pom依赖activiti-spring</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><!-- https://mvnrepository.com/artifact/org.activiti/activiti-spring --></span><br><span class="line"><dependency></span><br><span class="line"> <groupId>org.activiti</groupId></span><br><span class="line"> <artifactId>activiti-spring</artifactId></span><br><span class="line"> <version>6.0.0</version></span><br><span class="line"></dependency></span><br></pre></td></tr></table></figure><p>(2) 基于Spring的默认配置activiti-context.xml</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><?xml version="1.0" encoding="UTF-8"?></span><br><span class="line"></span><br><span class="line"><beans xmlns="http://www.springframework.org/schema/beans"</span><br><span class="line"> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"</span><br><span class="line"> xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"></span><br><span class="line"><!--数据源配置--></span><br><span class="line"> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"></span><br><span class="line"> <property name="url" value="jdbc:mysql://111.229.203.5:3306/activiti?serverTimezone=CTT&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true"/></span><br><span class="line"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/></span><br><span class="line"> <property name="username" value="weaver"/></span><br><span class="line"> <property name="password" value="192612"/></span><br><span class="line"> <property name="initialSize" value="1"/></span><br><span class="line"> <property name="maxActive" value="10"/></span><br><span class="line"> <property name="filters" value="stat,slf4j"/></span><br><span class="line"> </bean></span><br><span class="line"> <!--事务管理器配置--></span><br><span class="line"> <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"></span><br><span class="line"> <!--指定数据源--></span><br><span class="line"> <property name="dataSource" ref="dataSource"/></span><br><span class="line"> </bean></span><br><span class="line"> <bean id="processEngineConfiguration"</span><br><span class="line"> class="org.activiti.spring.SpringProcessEngineConfiguration"></span><br><span class="line"> <property name="dataSource" ref="dataSource"/></span><br><span class="line"> <!--配置事务管理--></span><br><span class="line"> <property name="transactionManager" ref="dataSourceTransactionManager"/></span><br><span class="line"> <!--数据源的创建格式--></span><br><span class="line"> <property name="databaseSchemaUpdate" value="true"/></span><br><span class="line"> </bean></span><br><span class="line"> <!--构造流程引擎对象--></span><br><span class="line"> <bean id = "processEngineFactoryBean" class="org.activiti.spring.ProcessEngineFactoryBean"></span><br><span class="line"> <!--指定流程配置对象--></span><br><span class="line"> <property name="processEngineConfiguration" ref="processEngineConfiguration"/></span><br><span class="line"> </bean></span><br><span class="line"><!--报漏服务给Spring--></span><br><span class="line"> <bean id="runtimeService" factory-bean="processEngineFactoryBean" factory-method="getRuntimeService"></bean></span><br><span class="line"> <bean id="repositoryService" factory-bean="processEngineFactoryBean" factory-method="getRepositoryService"></bean></span><br><span class="line"> <bean id="formService" factory-bean="processEngineFactoryBean" factory-method="getFormService"></bean></span><br><span class="line"> <bean id="taskService" factory-bean="processEngineFactoryBean" factory-method="getTaskService"></bean></span><br><span class="line"> <bean id="historyService" factory-bean="processEngineFactoryBean" factory-method="getHistoryService"></bean></span><br><span class="line"> <bean id="activitiRule" class="org.activiti.engine.test.ActivitiRule"></span><br><span class="line"> <property name="processEngine" ref="processEngineFactoryBean"/></span><br><span class="line"> </bean></span><br><span class="line"></beans></span><br></pre></td></tr></table></figure><p>(3) Activiti核心服务注入Spring容器<br><strong><em>详细配置见上一步</em></strong></p><h3 id="8-2-基于Spring对Activiti管理"><a href="#8-2-基于Spring对Activiti管理" class="headerlink" title="8.2 基于Spring对Activiti管理"></a>8.2 基于Spring对Activiti管理</h3><h4 id="8-2-1-功能特征"><a href="#8-2-1-功能特征" class="headerlink" title="8.2.1 功能特征"></a>8.2.1 功能特征</h4><p>(1) 集成Spring事务管理器<br>(2) 定义文件表达式中使用Spring bean<br>(3) 自动部署资源文件</p><h3 id="8-3-基于Spring的流程单元测试"><a href="#8-3-基于Spring的流程单元测试" class="headerlink" title="8.3 基于Spring的流程单元测试"></a>8.3 基于Spring的流程单元测试</h3><h4 id="8-3-1-单元测试"><a href="#8-3-1-单元测试" class="headerlink" title="8.3.1 单元测试"></a>8.3.1 单元测试</h4><p>(1) 添加pom依赖spring-test</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><!-- https://mvnrepository.com/artifact/org.springframework/spring-test --></span><br><span class="line"><dependency></span><br><span class="line"> <groupId>org.springframework</groupId></span><br><span class="line"> <artifactId>spring-test</artifactId></span><br><span class="line"> <version>4.2.5.RELEASE</version></span><br><span class="line"> <scope>test</scope></span><br><span class="line"></dependency></span><br></pre></td></tr></table></figure><p>(2) 辅助测试Rule:ActivitiRule</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.atguigu.test;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.RuntimeService;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.TaskService;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.runtime.ProcessInstance;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.task.Task;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.test.ActivitiRule;</span><br><span class="line"><span class="keyword">import</span> org.activiti.engine.test.Deployment;</span><br><span class="line"><span class="keyword">import</span> org.junit.Rule;</span><br><span class="line"><span class="keyword">import</span> org.junit.Test;</span><br><span class="line"><span class="keyword">import</span> org.junit.runner.RunWith;</span><br><span class="line"><span class="keyword">import</span> org.slf4j.Logger;</span><br><span class="line"><span class="keyword">import</span> org.slf4j.LoggerFactory;</span><br><span class="line"><span class="keyword">import</span> org.springframework.beans.factory.annotation.Autowired;</span><br><span class="line"><span class="keyword">import</span> org.springframework.test.context.ContextConfiguration;</span><br><span class="line"><span class="keyword">import</span> org.springframework.test.context.junit4.SpringJUnit4ClassRunner;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.util.List;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@program</span>: activiti6</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@description</span>: 测试与Spring的集成</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span>: Mr.Wang</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@create</span>: 2020-05-28-10-26</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">@RunWith</span>(SpringJUnit4ClassRunner<span class="class">.<span class="keyword">class</span>)</span></span><br><span class="line"><span class="class">@<span class="title">ContextConfiguration</span>(<span class="title">locations</span> </span>= {<span class="string">"classpath:activiti-context.xml"</span>})</span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TestSpring</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> Logger log = LoggerFactory.getLogger(TestSpring<span class="class">.<span class="keyword">class</span>)</span>;</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Rule</span></span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">public</span> ActivitiRule activitiRule;</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> RuntimeService runtimeService;</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> TaskService taskService;</span><br><span class="line"> <span class="meta">@Test</span></span><br><span class="line"> <span class="meta">@Deployment</span>(resources = {<span class="string">"my-process.bpmn20.xml"</span>})</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">test</span><span class="params">()</span></span>{</span><br><span class="line"> ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(<span class="string">"my-process"</span>);</span><br><span class="line"> <span class="comment">/*List<Task> tasks = taskService.createTaskQuery().listPage(0, 100);</span></span><br><span class="line"><span class="comment"> for (Task task : tasks) {</span></span><br><span class="line"><span class="comment"> log.info("task 的某些测试数据 {}",task);</span></span><br><span class="line"><span class="comment"> }*/</span></span><br><span class="line"> Task task = taskService.createTaskQuery().singleResult();</span><br><span class="line"> taskService.complete(task.getId());</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>(3) 辅助测试TestCase:SpringActivitiTestCase</p>]]></content>
<summary type="html">
<h1 id="Activiti6-0工作流引擎学习-二-–-引擎配置"><a href="#Activiti6-0工作流引擎学习-二-–-引擎配置" class="headerlink" title="Activiti6.0工作流引擎学习(二) – 引擎配置"></a>Acti
</summary>
<category term="java" scheme="http://lwblog.xyz/categories/java/"/>
<category term="activiti6.0" scheme="http://lwblog.xyz/tags/activiti6-0/"/>
</entry>
<entry>
<title>Java8日期和时间处理</title>
<link href="http://lwblog.xyz/posts/58f1702a.html"/>
<id>http://lwblog.xyz/posts/58f1702a.html</id>
<published>2020-05-21T14:13:14.000Z</published>
<updated>2020-05-25T14:51:07.708Z</updated>
<content type="html"><![CDATA[<h2 id="1-java8新特性-新时间与日期API本地时间与时间戳"><a href="#1-java8新特性-新时间与日期API本地时间与时间戳" class="headerlink" title="1.java8新特性-新时间与日期API本地时间与时间戳"></a>1.java8新特性-新时间与日期API本地时间与时间戳</h2><p><code>LocalDate</code>、<code>LocalTime</code>、<code>LocalDateTime</code>类的实例是不可变的对象,分别表示使用ISO-8601的日历系统的日期、时间、日期和时间。新的API提供了简单的日期和时间的获取方法。不包含与时区有关的信息</p><h3 id="1-1-使用静态方法now获取本地时间"><a href="#1-1-使用静态方法now获取本地时间" class="headerlink" title="1.1 使用静态方法now获取本地时间"></a>1.1 使用静态方法now获取本地时间</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">LocalDate now = LocalDate.now();</span><br><span class="line">System.out.println(<span class="string">"获取系统的日期:"</span>+now);<span class="comment">// 2020-05-25</span></span><br><span class="line">LocalTime localTime = LocalTime.now();</span><br><span class="line">System.out.println(<span class="string">"获取系统的时间:"</span>+localTime);<span class="comment">//20:32:55.091</span></span><br><span class="line">LocalDateTime localDateTime = LocalDateTime.now();</span><br><span class="line">System.out.println(<span class="string">"获取系统的日期和时间:"</span>+localDateTime);<span class="comment">//2020-05-25T20:32:55.092</span></span><br></pre></td></tr></table></figure><h3 id="1-2-使用静态方法of获取日期和时间"><a href="#1-2-使用静态方法of获取日期和时间" class="headerlink" title="1.2 使用静态方法of获取日期和时间"></a>1.2 使用静态方法of获取日期和时间</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">LocalDate localDate = LocalDate.of(<span class="number">2012</span>, <span class="number">3</span>, <span class="number">23</span>);</span><br><span class="line">System.out.println(localDate);<span class="comment">//2012-03-23</span></span><br><span class="line">LocalTime localTime = LocalTime.of(<span class="number">12</span>, <span class="number">12</span>);</span><br><span class="line">System.out.println(localTime);<span class="comment">//12:12</span></span><br><span class="line">LocalDateTime localDateTime = LocalDateTime.of(<span class="number">2012</span>, <span class="number">3</span>, <span class="number">24</span>, <span class="number">12</span>, <span class="number">12</span>, <span class="number">12</span>);</span><br><span class="line">System.out.println(localDateTime);<span class="comment">//2012-03-24T12:12:12</span></span><br></pre></td></tr></table></figure><h3 id="1-3-plusDays、plusWeeks、plusMonths、plusYear向当前LocalDate对象添加几天、几周、几个月、几年"><a href="#1-3-plusDays、plusWeeks、plusMonths、plusYear向当前LocalDate对象添加几天、几周、几个月、几年" class="headerlink" title="1.3 plusDays、plusWeeks、plusMonths、plusYear向当前LocalDate对象添加几天、几周、几个月、几年"></a>1.3 plusDays、plusWeeks、plusMonths、plusYear向当前LocalDate对象添加几天、几周、几个月、几年</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">LocalDate localDate = LocalDate.now();</span><br><span class="line">System.out.println(localDate);<span class="comment">//2020-05-25</span></span><br><span class="line">LocalDate localDate1 = localDate.plusDays(<span class="number">2L</span>);</span><br><span class="line">System.out.println(localDate1);<span class="comment">//2020-05-27</span></span><br><span class="line">LocalDate localDate2 = localDate.plusMonths(<span class="number">2L</span>);</span><br><span class="line">System.out.println(localDate2);<span class="comment">//2020-07-25</span></span><br><span class="line">LocalDate localDate3 = localDate.plusWeeks(<span class="number">2L</span>);</span><br><span class="line">System.out.println(localDate3);<span class="comment">//2020-06-08</span></span><br><span class="line">LocalDate localDate4 = localDate.plusYears(<span class="number">2L</span>);</span><br><span class="line">System.out.println(localDate4);<span class="comment">//2022-05-25</span></span><br></pre></td></tr></table></figure><h3 id="1-4-Instant时间戳"><a href="#1-4-Instant时间戳" class="headerlink" title="1.4 Instant时间戳"></a>1.4 Instant时间戳</h3><p>时间戳(以Unix元年:1970年1月1日00:00:00到某个时间之间的毫秒值)</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//默认获取的是以UTC时区</span></span><br><span class="line">Instant now = Instant.now();</span><br><span class="line">System.out.println(now);<span class="comment">//2020-05-25T13:32:32.718Z</span></span><br><span class="line"><span class="comment">//对时间进行偏移量处理,以便获取当前所在时区的时间</span></span><br><span class="line">OffsetDateTime offsetDateTime=now.atOffset(ZoneOffset.ofHours(<span class="number">8</span>));</span><br><span class="line">System.out.println(offsetDateTime);<span class="comment">//2020-05-25T21:32:32.718+08:00</span></span><br><span class="line"><span class="comment">//把获取的时间转换成对应的毫秒值</span></span><br><span class="line"><span class="keyword">long</span> l = now.toEpochMilli();</span><br><span class="line">System.out.println(l);<span class="comment">//1590413552718</span></span><br></pre></td></tr></table></figure><h2 id="1-5-Duration计算两个时间之间的间隔-Period计算两个日期之间的间隔"><a href="#1-5-Duration计算两个时间之间的间隔-Period计算两个日期之间的间隔" class="headerlink" title="1.5 Duration计算两个时间之间的间隔,Period计算两个日期之间的间隔"></a>1.5 Duration计算两个时间之间的间隔,Period计算两个日期之间的间隔</h2><p><code>Duration</code>和<code>Period</code>的使用方式相同</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">Instant now = Instant.now();</span><br><span class="line"><span class="keyword">try</span> {</span><br><span class="line"> <span class="comment">//用线程睡眠一秒钟来测试Duration的时间差</span></span><br><span class="line"> Thread.sleep(<span class="number">1000L</span>);</span><br><span class="line">} <span class="keyword">catch</span> (InterruptedException e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line">}</span><br><span class="line">Instant now2 = Instant.now();</span><br><span class="line"><span class="comment">//比较两个时间的间隔</span></span><br><span class="line">Duration duration = Duration.between(now, now2);</span><br><span class="line"><span class="comment">//默认输出`PT1.002S`为ISO-861的表示方法</span></span><br><span class="line">System.out.println(duration);</span><br><span class="line"><span class="comment">//将ISO的表示的方法转换为纳秒、或者毫秒值</span></span><br><span class="line"><span class="keyword">long</span> l = duration.toNanos();<span class="comment">//1002000000</span></span><br><span class="line"><span class="comment">//转换为毫秒值</span></span><br><span class="line"><span class="comment">//long l1 = duration.toMillis();</span></span><br><span class="line">System.out.println(l);</span><br><span class="line"><span class="comment">//System.out.println(l1);</span></span><br></pre></td></tr></table></figure><h2 id="2-java8新特性-新时间与日期API-时间校正器"><a href="#2-java8新特性-新时间与日期API-时间校正器" class="headerlink" title="2.java8新特性-新时间与日期API-时间校正器"></a>2.java8新特性-新时间与日期API-时间校正器</h2><p><code>TemporalAdjuster</code>:时间校正器。有时候我们需要获取例如:将日期调整到“下周日”等操作。<br><code>TemporalAdjusters</code>:该类通过静态方法提供了大量的常用<code>TemporalAdjuster</code>的实现</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">LocalDateTime ldt = LocalDateTime.now();</span><br><span class="line">System.out.println(ldt);<span class="comment">//2020-05-25T22:00:35.532</span></span><br><span class="line"><span class="comment">//获取下一个周日</span></span><br><span class="line">LocalDateTime dateTime = ldt.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));</span><br><span class="line">System.out.println(dateTime);<span class="comment">//2020-05-31T22:00:35.532</span></span><br><span class="line"><span class="comment">//自定义:下一个工作日是什么时候</span></span><br><span class="line">LocalDateTime with = ldt.with(l -> {</span><br><span class="line"> LocalDateTime ldt4 = (LocalDateTime) l;</span><br><span class="line"> <span class="comment">//获取今天是星期几</span></span><br><span class="line"> DayOfWeek dayOfWeek = ldt4.getDayOfWeek();</span><br><span class="line"> System.out.println(dayOfWeek);<span class="comment">//MONDAY</span></span><br><span class="line"> <span class="keyword">if</span> (dayOfWeek.equals(DayOfWeek.FRIDAY)) {</span><br><span class="line"> <span class="keyword">return</span> ldt4.plusDays(<span class="number">3L</span>);</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (dayOfWeek.equals(DayOfWeek.SUNDAY)) {</span><br><span class="line"> <span class="keyword">return</span> ldt4.plusDays(<span class="number">2L</span>);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> ldt4.plusDays(<span class="number">1L</span>);</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"> System.out.println(with);<span class="comment">//2020-05-26T22:06:51.576</span></span><br></pre></td></tr></table></figure><h2 id="3-java8新特性-新时间与日期API-时间格式化与时区处理"><a href="#3-java8新特性-新时间与日期API-时间格式化与时区处理" class="headerlink" title="3.java8新特性-新时间与日期API-时间格式化与时区处理"></a>3.java8新特性-新时间与日期API-时间格式化与时区处理</h2><h3 id="3-1时间和日期的格式化"><a href="#3-1时间和日期的格式化" class="headerlink" title="3.1时间和日期的格式化"></a>3.1时间和日期的格式化</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">DateTimeFormatter isoLocalDate = DateTimeFormatter.ISO_LOCAL_DATE;</span><br><span class="line">LocalDateTime now = LocalDateTime.now();</span><br><span class="line">System.out.println(now);</span><br><span class="line">String format = now.format(isoLocalDate);<span class="comment">//2020-05-25T22:22:48.083</span></span><br><span class="line">System.out.println(format);<span class="comment">//2020-05-25</span></span><br><span class="line"><span class="comment">//定义自己的格式</span></span><br><span class="line">DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(<span class="string">"yyyy年MM月dd日"</span>);</span><br><span class="line">String format1 = dateTimeFormatter.format(now);</span><br><span class="line">System.out.println(format1);<span class="comment">//2020年05月25日</span></span><br></pre></td></tr></table></figure><h3 id="3-2-时区的处理"><a href="#3-2-时区的处理" class="headerlink" title="3.2 时区的处理"></a>3.2 时区的处理</h3><p>java8中加入了对时区的支持,带时区的时间分别为<code>ZonedDate</code>,<code>ZonedTIme</code>,<code>ZoneDateTime</code>。其中每个时区都对应着ID,地区ID都是<code>区域/城市</code>的格式,例如:<code>Asia/Shanghai</code>等。<br><code>ZoneId</code>该类中包含了所有的时区信息:<br>getAvailableZoneIds():可以获取所有时区的信息<br>of(id):用指定的时区信息获取ZoneId对象</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//获取所有的时区</span></span><br><span class="line">Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();</span><br><span class="line">availableZoneIds.forEach(System.out::println);</span><br><span class="line"><span class="comment">//获取时区为上海的时间</span></span><br><span class="line">LocalDateTime now = LocalDateTime.now(ZoneId.of(<span class="string">"Asia/Shanghai"</span>));<span class="comment">//2020-05-25T22:47:57.216</span></span><br><span class="line">System.out.println(now);</span><br><span class="line"><span class="comment">//也可以使用以下的方法设置时区,返回的是带有时区的时间和日期</span></span><br><span class="line">LocalDateTime now1 = LocalDateTime.now();</span><br><span class="line">ZonedDateTime zonedDateTime = now1.atZone(ZoneId.of(<span class="string">"Asia/Shanghai"</span>));<span class="comment">//2020-05-25T22:47:57.222+08:00[Asia/Shanghai]</span></span><br><span class="line">System.out.println(zonedDateTime);</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="1-java8新特性-新时间与日期API本地时间与时间戳"><a href="#1-java8新特性-新时间与日期API本地时间与时间戳" class="headerlink" title="1.java8新特性-新时间与日期API本地时间与时间戳"></a>1.
</summary>
<category term="java" scheme="http://lwblog.xyz/categories/java/"/>
<category term="java" scheme="http://lwblog.xyz/tags/java/"/>
<category term="JDK1.8" scheme="http://lwblog.xyz/tags/JDK1-8/"/>
</entry>
<entry>
<title>谷歌浏览器调试技巧</title>
<link href="http://lwblog.xyz/posts/4cc93b7c.html"/>
<id>http://lwblog.xyz/posts/4cc93b7c.html</id>
<published>2020-05-18T01:14:32.000Z</published>
<updated>2020-05-18T01:15:41.580Z</updated>
<summary type="html">
</summary>
<category term="google" scheme="http://lwblog.xyz/categories/google/"/>
<category term="调试" scheme="http://lwblog.xyz/tags/%E8%B0%83%E8%AF%95/"/>
</entry>
<entry>
<title>谷歌云盘折腾记</title>
<link href="http://lwblog.xyz/posts/af6fa0b3.html"/>
<id>http://lwblog.xyz/posts/af6fa0b3.html</id>
<published>2020-05-17T03:17:09.000Z</published>
<updated>2020-05-22T13:47:44.551Z</updated>
<content type="html"><![CDATA[<h2 id="折腾原因"><a href="#折腾原因" class="headerlink" title="折腾原因"></a>折腾原因</h2><p>前段时间由于某些原因,Goindex基于rclone挂载的谷歌云盘在某些原因的情况下不能免科学上网进行访问。这对于我这个大量文件都存放在谷歌云盘上的人来说就有点难受了。毕竟咱是一个无产阶级没有那么多的money进行购买机场流量。只能在茫茫的查找对应的替代品,功夫不负有心人。最终在努力下终于找到一个解决的办法,故此在这里记录一下</p><h2 id="前期准备"><a href="#前期准备" class="headerlink" title="前期准备"></a>前期准备</h2><ul><li>能科学上网的环境(准备的情况下需要科学上网)</li><li><a href="https://rclone.org/downloads/" target="_blank" rel="noopener">rclone</a> <strong>下载安装rclone</strong></li><li><a href="https://www.cloudflare.com/" target="_blank" rel="noopener">CLOUDFLARE</a> <strong>提前注册好账号</strong></li><li><a href="https://install.gd.workers.dev/" target="_blank" rel="noopener">Goindex</a> <strong>现在已经不能用了,原先我就是用的这个</strong></li></ul><h2 id="安装免科学上网访问谷歌云盘"><a href="#安装免科学上网访问谷歌云盘" class="headerlink" title="安装免科学上网访问谷歌云盘"></a>安装免科学上网访问谷歌云盘</h2><p>我是在参考YouTube上大佬小小白的视频进行操作的,这里附上大佬的<a href="https://www.youtube.com/watch?v=oPcb1FZXu5o" target="_blank" rel="noopener">视频链接</a>。各位看官,可以先参考这位大佬的视频进行操作。如果顺利的话就能正常的免科学上网的访问自己的谷歌云盘了。但是,我偏偏是这个不幸中的一人。我按照视频的操作过程中,总是卡在获取谷歌云盘的token验证失败的情况,查了很多资料都没能解决此问题。如果你也遇到这样的问题话,可以参考我的做法。<br>首先,<strong><em>你原先在GoIndex上生成过对应的代码,并且在cloudflare上部署过</em></strong>,下图是我部署代码的部分截图<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gevadnpk2xj31o20jetce.jpg" alt=""><br>其次,需要在cloudflare上新建一个worked,将<a href="https://github.com/yanzai/goindex" target="_blank" rel="noopener">这里</a>index.js的代码复制到刚刚新建的worked中,并且将下图中的ID、密钥和token替换成原先使用Goindex生成的代码中的ID、密钥和token。(<strong><em>这里之所以是这样做,是因为使用rclone生成token的时候总是报错</em></strong>)<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlgy1gevahdci01j31je0u0k1z.jpg" alt=""><br>最后,保存并部署代码就OK了,这样就能再次在不科学上网的情况下继续浏览自己谷歌云盘中的内容了。<br>在这次更新的代码中还有很多的改进,比如可以对不同的文件夹赋予不同的权限,能在进行搜索操作</p><h2 id="GDIndex代码生成器"><a href="#GDIndex代码生成器" class="headerlink" title="GDIndex代码生成器"></a>GDIndex代码生成器</h2><p>虽然GoIndex代码生成器目前已经不能使用了,但是现在有一个新的GDIndex代码生成器可以替代GoIndex的代码生成器<br><a href="https://gdindex-code-builder.glitch.me/" target="_blank" rel="noopener">GDIndex</a>的使用方法同GoIndex。需要的小伙伴可以自行百度设置,或者参考上面提到的视频。</p><p><strong><em>文章参考:</em></strong></p><ol><li><a href="https://www.youtube.com/watch?v=oPcb1FZXu5o" target="_blank" rel="noopener">小小白大佬的视频</a></li><li><a href="https://xiaoxiaobai.ga/?p=256" target="_blank" rel="noopener">小小白大佬的文档说明</a></li></ol>]]></content>
<summary type="html">
对于科学上网流量访问你google driver的捉襟见肘的你,可以进来瞅一瞅
</summary>
<category term="google" scheme="http://lwblog.xyz/categories/google/"/>
<category term="google diriver" scheme="http://lwblog.xyz/tags/google-diriver/"/>
</entry>
<entry>
<title>macbookpro使用技巧</title>
<link href="http://lwblog.xyz/posts/2366fd10.html"/>
<id>http://lwblog.xyz/posts/2366fd10.html</id>
<published>2020-05-15T04:48:36.000Z</published>
<updated>2020-05-15T06:59:49.314Z</updated>
<content type="html"><![CDATA[<h2 id="1-mac的隐藏功能"><a href="#1-mac的隐藏功能" class="headerlink" title="1.mac的隐藏功能"></a>1.mac的隐藏功能</h2><ul><li><p>直观听到音量的渐变声音: shfit+音量键</p></li><li><p>声音或者亮度1/4的变化:shfit+option+音量键/亮度建</p></li><li><p>聊天打字快速调出emoj动画:command+control+空格</p></li><li><p>切换显示已关闭或者最小化的窗口:command+tab同时摁下option</p></li><li><p>隐藏当前窗口的程序:command+H</p><ul><li>区分关闭和隐藏的代码(开启后隐藏的图标呈现半透明状态)</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">defaults write com.apple.Dock showhidden -bool TRUE; killall Dock</span><br></pre></td></tr></table></figure><ul><li>关闭的代码</li></ul><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">defaults write com.apple.Dock showhidden -bool FALSE; killall Dock</span><br></pre></td></tr></table></figure></li><li><p>command+tab选中图标后摁下Q是关闭程序</p></li></ul><h2 id="2-mac中常用软件"><a href="#2-mac中常用软件" class="headerlink" title="2. mac中常用软件"></a>2. mac中常用软件</h2><h2 id="3-mac的高效使用"><a href="#3-mac的高效使用" class="headerlink" title="3.mac的高效使用"></a>3.mac的高效使用</h2><ul><li><p>一位数密码:pwpolicy -clearaccountpolicies 需要在终端执行此命令</p></li><li><p>更改搜索这台mac为搜索此文件夹</p><p>访达—偏好设置—高级—执行搜索选择搜索但前文件夹</p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get21swmawj30la0m8gw3.jpg" style="zoom:50%;" /><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get22t0o27j30lg0leqau.jpg" style="zoom:50%;" /></li><li><p>打开程序的偏好设置: command+,</p></li><li><p>手动添加打开系统偏好设置的快捷键</p><p>系统偏好设置—键盘—快捷键—APP快捷键—点击“+”,应用程序选择所有应用程序,菜单标题改为“系统偏好设置…”,快捷键中输入自己熟悉的快捷键就OK—点击添加</p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get2c3wzzdj30ue0ns4ca.jpg" alt=""></p><ul><li>全局开启访达<ol><li>打开自动操作</li></ol></li></ul><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get2lrvz89j31xk0kk7nk.jpg" alt=""></p><ol start="2"><li>点击新建文稿</li></ol><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get2ny6jayj31as0pkn9h.jpg" alt=""></p><ol start="2"><li>快速操作</li></ol><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get2old69wj31jm0u0kjl.jpg" alt=""></p><ol start="3"><li>点击实用工具,将开启应用程序拖拽到右边</li></ol><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get2r1n9e8j31jo0m01bx.jpg" alt=""></p><ol start="4"><li><p>工作流程收到选择:没有输入</p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get2swslhhj31io0ca46c.jpg" alt=""></p></li><li><p>选择新建变量—系统—资源库—coreservices—访达</p></li></ol><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get2wqu7o0j316y0u0qv5.jpg" alt=""></p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get31lzelkj318w0p2as3.jpg" alt=""></p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get32azve5j30z40cq46w.jpg" alt=""></p></li></ul><ol start="6"><li><p>点击这里可以测试是否配置正确,然后存储</p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get33dggnij31js0k6nfj.jpg" alt=""></p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get35y97f7j319q0mm1kx.jpg" alt=""></p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get36sw1rjj317m0e0tkl.jpg" alt=""></p></li><li><p>快捷键定义</p><p>通过系统偏好设置—键盘—快捷键—服务—通用—全局开启访达</p><p>![image-20200515135133428](/Users/wangyufei/Library/Application Support/typora-user-images/image-20200515135133428.png)</p></li><li><p>在全局开启访达后边点击设置快捷键,我这里设置的是command+option+空格</p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1get3gr7xbaj30k20f8tc5.jpg" alt=""></p></li></ol>]]></content>
<summary type="html">
mac笔记本使用技巧
</summary>
<category term="Mac" scheme="http://lwblog.xyz/categories/Mac/"/>
<category term="Mac" scheme="http://lwblog.xyz/tags/Mac/"/>
</entry>
<entry>
<title>sqlserver数据库还原单表数据操作</title>
<link href="http://lwblog.xyz/posts/4a17b156.html"/>
<id>http://lwblog.xyz/posts/4a17b156.html</id>
<published>2020-05-08T14:53:07.000Z</published>
<updated>2020-05-15T02:45:06.117Z</updated>
<content type="html"><![CDATA[<p>在系统数据和数据库数据备份或者升级的时候,我们总是全量的备份应用或者数据。在升级完成使用一段时间后突然间发现某张表的数据有问题,此时在全部的还原数据库的数据则不太合理,那如何只还原出现问题的这张表的数据呢?</p><p>首先,我们需要将升级时全量备份的数据库还原成一个新的数据库,如何还原一个新的数据库,此处不在赘述,网上有好多。自我感觉还是参考<a href="https://docs.microsoft.com/zh-cn/sql/relational-databases/backup-restore/restore-a-database-to-a-new-location-sql-server?view=sql-server-ver15" target="_blank" rel="noopener">sqlserver官方的还原说明</a>或者参考<a href="https://www.jianshu.com/p/a153c20a577d?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation" target="_blank" rel="noopener">SQL Server从BAK文件还原到新数据库</a></p><p>之后,我们选择刚刚还原完成的数据库使用如下的命令将ecology.dbo.hrmresource 所有的数据导入到demo.dbo.hrmresource_Test中<br><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gesxhysb3zj31hx0u0n7s.jpg" alt=""></p><p>选中刚刚还原的数据库,执行如下的sql语句,执行完成后刷新可以看到demo中已经出现了需要还原的表单数据</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">Select</span> * <span class="keyword">into</span> demo.dbo.hrmresource_test <span class="keyword">From</span> ecology.dbo.hrmresource</span><br></pre></td></tr></table></figure><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gesxkucf1wj319e0u0x5l.jpg" alt=""></p><p>两张表单对比,我这里的表单中没有数据,但是可以看到需要还原的demo库中对应的表单结构已经有了</p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gesxp4rmjgj318s0u01kx.jpg" alt="ecology"></p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gesxr7mbkxj31670u01kx.jpg" alt="demo库"></p><p>最后,我们使用下列命令将原来的表进行删除,并把HtmlLabelInfo_Test 重命名为HtmlLabelInfo</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">//删除原有的表单,此处我的里边没有对用的表单,就没有执行这一步</span><br><span class="line"><span class="keyword">drop</span> <span class="keyword">table</span> [dbo].[Hrmresource]</span><br><span class="line">//表单重命名,或者在ssms操作工具中直接在actionsetting_test上摁下F2进行表单重命名</span><br><span class="line">EXEC sp_rename <span class="string">'Hrmresource_test'</span>,<span class="string">'Hrmresource'</span></span><br></pre></td></tr></table></figure><p>或者是在navicat中可以直接右键选择重命名,对表单的名称进行更改</p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gesxs79m9wj30w20u07wh.jpg" alt=""></p><p>至此,在全量备份的情况下即可还原某一张表的数据。</p>]]></content>
<summary type="html">
sqlserver数据库通过全备份还原某张表数据
</summary>
<category term="数据库" scheme="http://lwblog.xyz/categories/%E6%95%B0%E6%8D%AE%E5%BA%93/"/>
<category term="sqlserver" scheme="http://lwblog.xyz/tags/sqlserver/"/>
</entry>
<entry>
<title>网络在在线传输工具 --- 奶牛快传</title>
<link href="http://lwblog.xyz/posts/994d00c4.html"/>
<id>http://lwblog.xyz/posts/994d00c4.html</id>
<published>2020-05-08T14:53:07.000Z</published>
<updated>2020-05-14T03:11:14.184Z</updated>
<content type="html"><![CDATA[<h2 id="1-奶牛快传"><a href="#1-奶牛快传" class="headerlink" title="1.奶牛快传"></a>1.<a href="https://cowtransfer.com/" target="_blank" rel="noopener">奶牛快传</a></h2><h3 id="1-1-免费超快的传文件工具"><a href="#1-1-免费超快的传文件工具" class="headerlink" title="1.1 免费超快的传文件工具"></a>1.1 免费超快的传文件工具</h3><p>奶牛快传是一款免费、无需注册即可直接使用的网页端大文件临时传输网盘服务。它提供了网页版、微信小程序、IOS以及安卓端。无论是办公文档、照片、还是电影视频通通都能轻松分享。</p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gerseagq8pj31q10u0hdt.jpg" alt=""></p><p>未注册用户则可最大传输 2GB 文件,默认保留7天,可以免费下载100次。支持加密、邮件和短信分享</p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gerskqbjt2j31uf0u0u0x.jpg" alt=""></p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gersldpc6tj31vn0u0u0x.jpg" alt=""></p><h3 id="1-2-奶牛快传的使用"><a href="#1-2-奶牛快传的使用" class="headerlink" title="1.2 奶牛快传的使用"></a>1.2 奶牛快传的使用</h3><p>你只需在任何浏览器打开<a href="https://cowtransfer.com/" target="_blank" rel="noopener">奶牛快传</a>的网站,通过点击上传按钮或拖放文件即可开始上传,支持一次批量上传多个文件。</p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gerseagq8pj31q10u0hdt.jpg" alt=""></p><p>之后你就能获得文件的共享链接了。你只需将链接发给别人,对方就能直接通过浏览器下载了,对方并不需要注册登录,也无需下载 APP 等麻烦操作,实用性很强。同时,奶牛快传还提供了共享网址所对应的二维码以及微信小程序二维码,这样不管用手机还是电脑来下载文件都更方便。起码自己用电脑给手机发文件的场景也是经常会用到的。</p><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gersrgbg0gj31un0u01ky.jpg" alt=""></p><h3 id="1-3-奶牛快传注册账户"><a href="#1-3-奶牛快传注册账户" class="headerlink" title="1.3 奶牛快传注册账户"></a>1.3 奶牛快传注册账户</h3><p>还未体验过注册账户,待体验后在进行分享…..</p>]]></content>
<summary type="html">
不需注册就能上传和下载文件,奶牛快传非常适合进行大文件分享和存储
</summary>
<category term="网络在在线传输工具" scheme="http://lwblog.xyz/categories/%E7%BD%91%E7%BB%9C%E5%9C%A8%E5%9C%A8%E7%BA%BF%E4%BC%A0%E8%BE%93%E5%B7%A5%E5%85%B7/"/>
<category term="奶牛快传" scheme="http://lwblog.xyz/tags/%E5%A5%B6%E7%89%9B%E5%BF%AB%E4%BC%A0/"/>
<category term="文件传输" scheme="http://lwblog.xyz/tags/%E6%96%87%E4%BB%B6%E4%BC%A0%E8%BE%93/"/>
<category term="网络在在线传输工具" scheme="http://lwblog.xyz/tags/%E7%BD%91%E7%BB%9C%E5%9C%A8%E5%9C%A8%E7%BA%BF%E4%BC%A0%E8%BE%93%E5%B7%A5%E5%85%B7/"/>
</entry>
<entry>
<title>油猴(Tampermonkey)常用脚本</title>
<link href="http://lwblog.xyz/posts/44e1e43b.html"/>
<id>http://lwblog.xyz/posts/44e1e43b.html</id>
<published>2020-05-08T14:32:09.000Z</published>
<updated>2020-05-13T08:09:31.020Z</updated>
<content type="html"><![CDATA[<h2 id="1-什么是油猴"><a href="#1-什么是油猴" class="headerlink" title="1.什么是油猴"></a>1.什么是油猴</h2><p>从英文翻译而来-Tampermonkey是一个捐赠软件用户脚本管理器,可用作浏览器扩展。该软件使用户能够添加和使用用户脚本,这些脚本是可用于修改网页的JavaScript程序</p><h2 id="2-油猴下载地址"><a href="#2-油猴下载地址" class="headerlink" title="2.油猴下载地址"></a>2.油猴下载地址</h2><ul><li><a href="https://www.tampermonkey.net/" target="_blank" rel="noopener">官网下载</a></li><li><a href="https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo" target="_blank" rel="noopener">谷歌商店</a><h2 id="3-常用插件"><a href="#3-常用插件" class="headerlink" title="3.常用插件"></a>3.常用插件</h2><h3 id="3-1-批量下载网页图片-Picviewer-CE"><a href="#3-1-批量下载网页图片-Picviewer-CE" class="headerlink" title="3.1 批量下载网页图片 - Picviewer CE+"></a>3.1 批量下载网页图片 - Picviewer CE+</h3><a href="https://greasyfork.org/zh-CN/scripts/24204-picviewer-ce" target="_blank" rel="noopener">Picviewer CE+</a> 是一款浏览器油猴脚本,可以将包含很多图片的网页变成图片浏览器,还能对图片进行翻转、旋转、放大,显示原始大图、收藏、批量保存,聚合所有分页大图,图片在线编辑等操作</li></ul>]]></content>
<summary type="html">
<h2 id="1-什么是油猴"><a href="#1-什么是油猴" class="headerlink" title="1.什么是油猴"></a>1.什么是油猴</h2><p>从英文翻译而来-Tampermonkey是一个捐赠软件用户脚本管理器,可用作浏览器扩展。该软件使用户
</summary>
<category term="油猴" scheme="http://lwblog.xyz/tags/%E6%B2%B9%E7%8C%B4/"/>
<category term="Tampermonkey" scheme="http://lwblog.xyz/tags/Tampermonkey/"/>
</entry>
</feed>