-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
3848 lines (3846 loc) · 561 KB
/
search.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
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Bootstrap-Table</title>
<url>/2020/10/23/Bootstrap-Table/</url>
<content><![CDATA[<h2 id="前言">#前言</h2>
<p>由于需要使用到表格的排序功能,懒于自己写就打算搞个框架,之前使用的是Bootstrap框架,想着如果它自身有,那就太棒了…还真有,(^U^)ノ~YO</p>
<p>它就是 <span class="ljspan ljspan-reverse ljspan-blue"><a href="https://bootstrap-table.com/docs/getting-started/introduction/">Bootstrap-Table</a></span><a id="more"></a></p>
<p><span class="ljspan ljspan-reverse ljspan-blue"><a href="https://bootstrap-table.com/docs/getting-started/introduction/">Bootstrap-Table</a></span>在页面中的使用,有多种方法,一种是直接使用HTML5的写法,直接通过<span class="label warning">data-*</span>的方式指定个中属性设置,另一种就是HTML+JS方式实现弹性设置,我用的就是第二种</p>
<p>由于数据想使用ajax异步读取,这样方便,刚好,方法 <span class="ljspan ljspan-blue">bootstrapTable</span>就有这样的功能。</p>
<p>官方文档在<a href="https://bootstrap-table.com/docs/getting-started/introduction/">这里</a>,说实话,不太喜欢,这玩意用的方式跟我不同,🐢🐢,但是还是可以当作参考的。</p>
<blockquote>
<p>先准备一个表头,也可以把表格头的信息也写在<span class="ljspan ljspan-blue">bootstrapTable</span>方法里</p>
</blockquote>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">table</span> <span class="attr">id</span>=<span class="string">"bootstrap-table"</span> <span class="attr">class</span>=<span class="string">"table"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">thead</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">tr</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span> <span class="attr">data-field</span>=<span class="string">"Id"</span> <span class="attr">data-sortable</span>=<span class="string">"true"</span>></span>#<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span> <span class="attr">data-field</span>=<span class="string">"Name"</span> <span class="attr">data-sortable</span>=<span class="string">"true"</span>></span>name<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">th</span> <span class="attr">data-field</span>=<span class="string">"Age"</span> <span class="attr">data-sortable</span>=<span class="string">"true"</span>></span>age<span class="tag"></<span class="name">th</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">tr</span>></span></span><br><span class="line"> <span class="tag"></<span class="name">thead</span>></span></span><br><span class="line"><span class="tag"></<span class="name">table</span>></span> </span><br></pre></td></tr></table></figure>
<blockquote>
<p>开始使用 <span class="ljspan ljspan-reverse ljspan-blue">Bootstrap-Table</span></p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line">$(<span class="string">"#bootstrap-table"</span>).bootstrapTable({</span><br><span class="line"> <!------------发送ajax请求-----------></span><br><span class="line"> url : queryUrl, <span class="comment">//请求后台的URL(*)</span></span><br><span class="line"> dataType:<span class="string">"json"</span>, </span><br><span class="line"> contentType : <span class="string">"application/x-www-form-urlencoded"</span>,</span><br><span class="line"> sidePagination : <span class="string">"server"</span>, <span class="comment">//分页方式:client客户端分页,server服务端分页(*) </span></span><br><span class="line"> method : <span class="string">'POST'</span>, <span class="comment">//请求方式(*)</span></span><br><span class="line"> <!-----------------------------------> </span><br><span class="line"> search : <span class="literal">false</span>, <span class="comment">//是否显示表格搜索</span></span><br><span class="line"> showFooter : <span class="literal">false</span>, <span class="comment">//显示底部,默认不显示</span></span><br><span class="line"> sortName : <span class="string">"genesId"</span>,</span><br><span class="line"> sortOrder : <span class="string">"desc"</span>, <span class="comment">//排序方式</span></span><br><span class="line"> ....</span><br><span class="line">}) </span><br></pre></td></tr></table></figure>
<blockquote>
<p>刚开始,我也不知道它如何发送请求,后面看了上面最开始部分数据的数据格式后,发现,这字段怎么跟ajax那么像,查了源码才发现这就是采用ajax的方式,参数data改为使用sidePageination来传输,分client和server两种</p>
</blockquote>
<p>除了使用使用ajax发送请求外,其他字段都是一些对表格的设计的属性,下面介绍几个</p>
<ul>
<li>
<p>sidePagination:用来设置发送数据给后台的方法选择,有“server”和“client”之分,“client”用于</p>
</li>
<li>
<p>Query Params:它就是一个发送数据给服务器的方法,也就是ajax方法中的data,前提是需要设置<code>sidePagination : "server"</code>;除了本身的参数,可以额外添加参数</p>
</li>
<li>
<p>Formatter:用来格式化返回的表格列的显示形式,比如加图形,改变css样式等等</p>
</li>
<li>
<p>Locale:汉化,前提是导入<a href="https://examples.bootstrap-table.com/index.html#options/table-locale.html#view-source">语言js文件</a>,而且这个文件需要再 <span class="ljspan ljspan-reverse ljspan-blue">Bootstrap-Table</span>的js文件后面</p>
</li>
</ul>
<p>发送完参数后,后面就可以获取到响应了,那响应的内容如何设置呢?</p>
<h2 id="响应数据">响应数据</h2>
<p>响应数据是json数据,后台要处理为json字符串数据后返回。然后响应的内容格式为<code>{total:22,rows:{}}</code>,我在后台需要结合 <span class="ljspan ljspan-reverse ljspan-red">pagehelper</span>的使用,获取total。这样就更加简单了😄</p>
]]></content>
<categories>
<category>前端</category>
</categories>
</entry>
<entry>
<title>Classpath是什么?</title>
<url>/2020/09/04/Classpath%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F/</url>
<content><![CDATA[<h2 id="前言">#前言</h2>
<p>在写<code>SSM</code>配置文件的时候经常看到这个东西,比如:<code>classpath:applicationContext.xml</code>,有印象了吗😤?</p>
<a id="more"></a>
<p>请看下图👇,一看便知</p>
<p><img src="/assets/img/image-20200604094831938.png" alt="一般项目架构图"></p>
<p>可当项目被编译后,架构就变化了哦~😉</p>
<p><img src="/assets/img/image-20200604095454394.png" alt="编译后的架构图"></p>
<p>所以,编译后<code>java</code>文件夹的文件和<code>resource</code>文件夹的文件就都放在了<code>classes</code>目录;而<code>classpath</code>其实就是<code>WEB-INF/classes</code>这个目录路径</p>
]]></content>
<categories>
<category>Java</category>
</categories>
<tags>
<tag>SSM</tag>
<tag>Configuration</tag>
</tags>
</entry>
<entry>
<title>Conda用法</title>
<url>/2020/09/08/Conda%E7%94%A8%E6%B3%95/</url>
<content><![CDATA[<h3 id="conda是一个包管理、环境管理工具⚙️">conda是一个包管理、环境管理工具⚙️</h3>
<p>一般,miniconda只针对python🐍这个环境,而anaconda其实就比较全面,可以用于多个编程语言的环境管理,比如R语言,JavaScript等等</p>
<a id="more"></a>
<figure class="highlight routeros"><table><tr><td class="code"><pre><span class="line">安装路径:/home/xxx/miniconda3</span><br><span class="line"></span><br><span class="line">退出命令:conda deactivate env_name</span><br><span class="line"></span><br><span class="line">删除环境:conda env <span class="builtin-name">remove</span> env_name</span><br><span class="line"></span><br><span class="line">显示环境列表:conda env list</span><br><span class="line"></span><br><span class="line">如果创建环境,使用指定路径的方式,命令如下</span><br><span class="line"></span><br><span class="line">conda create <span class="attribute">-p</span>=path/env_name <span class="attribute">python</span>=python_version</span><br><span class="line"></span><br><span class="line">那么开启这个环境的方法:conda activate path/env_name</span><br><span class="line"></span><br><span class="line">同理,删除这个环境的方法就是conda env <span class="builtin-name">remove</span> -p /path/env_name</span><br></pre></td></tr></table></figure>
<p>这样的话,该环境就指定了特定的路径,但是名称却为空,暂时还找不到如何改名字的方法,也就是说,在创建环境的时候,要么指定路径,要么指定名称(路径规定只在path/miniconda/env中)</p>
<p>💥解决方法:是使用<span class="label success">软链接</span>把路径引入path/miniconda/env/env_name中,就可以了,like the picture show below.</p>
<p><img src="/assets/img/Conda%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE.png" alt=""></p>
<hr>
<p>有时候,使用python无法下载某些包,或者下载速度很慢,这是因为conda下载包是使用国外的网址来下载的,可以修改配置,使用国内的镜像</p>
<p>清华👨🎓镜像内容和修改方法在<a href="https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/">这里</a></p>
]]></content>
<categories>
<category>linux</category>
</categories>
<tags>
<tag>linux</tag>
</tags>
</entry>
<entry>
<title>DNS服务-域名解析和转发</title>
<url>/2020/09/20/DNS%E6%9C%8D%E5%8A%A1-%E5%9F%9F%E5%90%8D%E8%A7%A3%E6%9E%90%E5%92%8C%E8%BD%AC%E5%8F%91/</url>
<content><![CDATA[<p>在看frp时,看到它有一个Forward DNS query request的功能,看不懂,就翻了翻网上的资料,大概知道它是想干嘛了,但是既然谈到<span class="ljspan ljspan-red">转发DNS</span>,就干脆把DNS解析和转发等这些东西顺便写写✍️咯</p>
<a id="more"></a>
<h2 id="DNS域名解析">DNS域名解析</h2>
<h3 id="namespace为互联网上的服务">namespace为互联网上的服务</h3>
<p>linux上有个文件,<code>/etc/resolv.conf</code>是用来只想互联网上的DNS服务器的。一般内容如下:</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="comment"># Generated by NetworkManager</span></span><br><span class="line">nameserver 8.8.8.8</span><br><span class="line">nameserver 222.222.222.222</span><br></pre></td></tr></table></figure>
<p>这里就是域名解析啦,一般计算机使用域名上网时,会先找该本机的DNS服务器。如果本地DNS能找到域名,本地DNS直接回复客户机。如果本地DNS服务器不知道你请求的域名,他就转发DNS请求到互联网上,查找域名,就是通过8.8.8.8或者222.222.222.222,然后将查询到的域名解析后,最终将域名解析结果返回给客户机</p>
<h3 id="namespace为127-0-0-53">namespace为127.0.0.53</h3>
<p>之前在一篇<span class="ljspan ljspan-reverse ljspan-green"><a href="">resolv.conf</a></span>有谈到有点这个东西,但是我没有解释,这里顺道解释咯,如果nameserver配置为127.0.0.53,那么它将不解析你的主机名。也就是不从本地主机上读取DNS服务</p>
<h3 id="namespace为主机IP">namespace为主机IP</h3>
<p>那能否把自己主机IP当作当作DNS服务器吗?而不用Internet上的DNS服务,当然可以啦:happy:</p>
<p>DNS服务安装完毕后,他就有根提示,天生就知道互联网上13个根DNS服务器。只要安装DNS服务的那台机器可以访问Internet,就完全可以解析全球域名。</p>
<p>因此DNS服务器的/etc/resolv.conf完全可以指向自己,对于未知域名,DNS服务器上的DNS服务会自己找根DNS服务器进行域名解析,并把解析结果保存在本地DNS服务器上。</p>
<hr>
<h2 id="域名解析转发">域名解析转发</h2>
<p>考虑如下场景,母公司内部配置有本地DNS服务器,负责解析母公司内部服务器域名以及互联网上的域名。子公司与母公司物理距离较远,两地使用专线链接,专线带宽不高。子公司内部计算机不直接连接互联网。</p>
<p>假如不在子公司内部设置DNS服务器,子公司内部计算机对母公司内部域名解析请求以及互联网上域名解析请求都会交由母公司的DNS服务器(为啥子公司电脑不直接填互联网上的DNS?1.解析不到母公司私网的服务器 2.公司也不可能允许你这么做)。这部分域名解析流量会严重占用专用链路的带宽,导致网络阻塞。</p>
<p>在子公司内部设置一个DNS服务器,但是这个DNS服务器又有点不同。对于自己不知道域名,他并没有请求互联网上的根DNS服务器,而是把域名解析的流量转发给了母公司DNS服务器,这样有效降低了专用链路上域名解析的带宽占用。这种场景就是DNS转发。</p>
<p>DNS转发还有2种场景(或者说2个参数)</p>
<p><strong>①</strong>foward only:子公司DNS服务器指向母公司DNS服务器请求DNS解析。如果母公司DNS服务器挂了 或 子公司到母公司链路故障 或 母公司DNS上不了网(子公司DNS服务器可以解析母公司内网服务器域名),子公司DNS服务器无法解析Internet域名</p>
<p><strong>②</strong>foward first:子公司DNS服务器优先指向母公司DNS服务器,如果母公司DNS服务器连不上(比如子公司到母公司的链路故障)会使用子DNS服务器保存的根DNS服务器来解析域名(这时候无法解析母公司内网域名,可以解析Internet域名)。</p>
<p>如果子公司到母公司之间链路是好的,单纯母公司DNS服务器上不了网。子公司可以解析母公司内网服务器域名,但是无法解析Internet域名。</p>
<blockquote>
<p>此段域名解析转发摘抄自这个<a href="https://www.cnblogs.com/kelamoyujuzhen/">kelamoyujuzhen</a>的<a href="https://www.cnblogs.com/kelamoyujuzhen/p/9526915.html">文章</a></p>
</blockquote>
]]></content>
<categories>
<category>linux</category>
</categories>
</entry>
<entry>
<title>JavaScript</title>
<url>/2020/09/11/JavaScript/</url>
<content><![CDATA[<h3 id="js比值函数">js比值函数</h3>
<ol>
<li><code>sort()</code>以字母顺序对数组进行升序排序</li>
<li>而**数字顺序<code>**sort( )</code>无法凭自己单独实现,这里就体现了比值函数的作用</li>
</ol>
<a id="more"></a>
<p>这就是比值函数:<code>function(a,b){return (a-b)}</code>,会返回正负和零,<code>sort( )</code>可根据返回的值的<strong>正负</strong>对数组进行排序。</p>
<p><span class="ljspan"><a href="https://blog.csdn.net/qwe122343/article/details/103992772">参考文档</a></span></p>
<h3 id="Script标签嵌套内容">Script标签嵌套内容</h3>
<p>编写<code>js</code>出现的奇怪问题🎃一般地,引入资源,都用单独用一个<code>Script</code>标签,标签内内容为空,而改用src引入外部<code>js</code>资源。然后,我就想如果我引入的同时又在标签内写入,能不能用呢?</p>
<p>答案是,不管是标签内写的还是引用的外部资源,都无法相互使用</p>
<h3 id="Ajax">Ajax</h3>
<h4 id="当数据在浏览器跟服务器之间交换的时候,这些数据只能是文本,这时候就需要-Json-出马🐎了!">当数据在浏览器跟服务器之间交换的时候,这些数据只能是文本,这时候就需要**<code>Json</code>**出马🐎了!</h4>
<ol>
<li>使用<code>Ajax</code>来发送数据,可以遇到一个问题,貌似要在服务器端设置响应头部<code>Access-Control-Allow-Origin</code></li>
</ol>
<p><img src="/assets/img/JavaScript.png" alt="image-20200611105650226"></p>
<p> 解决方案:把服务器响应的数据改为<code>Json</code>,这样就可以了!因为需要解析!</p>
<ol start="2">
<li>对于**<code>Ajax</code>**:通过对<code>javascript</code>中<code>Ajax</code>的练习📃,发现<code>Ajax</code>确实具备状态性,比如说,我刚刚搜索了某东西,然后信息很多,分了很多页,那么当我点击下一页时📑,发送<code>Ajax</code>请求,它会显示我刚刚搜索的内容的下一页,而不需要我再次提交搜索内容!</li>
<li><code>ajax</code>是发送异步请求📧:同步和异步得区别很明显,同步发送请求后,需要等到接收到返回信息和数据才能继续发送请求;而异步则可以在发送请求后,不需要等待接收返回信息,直接发送其他请求,等待返回信息和数据是在另一个线程⚙️中进行的,不影响当前线程。</li>
</ol>
]]></content>
<categories>
<category>javascript</category>
</categories>
</entry>
<entry>
<title>Java上传和下载</title>
<url>/2020/11/18/Java%E4%B8%8A%E4%BC%A0%E5%92%8C%E4%B8%8B%E8%BD%BD/</url>
<content><![CDATA[<p>不管是上传和下载,我发现都需要设置请求头之类的配置,才能够完成上传下载功能</p>
<h2 id="上传">上传</h2>
<p>上传的请求头等设置是在表单里面设置的,比如form表单中设置**<code>enctype="multipart/form-data"</code>**<a id="more"></a></p>
<p>服务器里面对文件的处理</p>
<figure class="highlight cmake"><table><tr><td class="code"><pre><span class="line"><span class="comment">#前提:获取文件后</span></span><br><span class="line"><span class="comment">#获取文件名</span></span><br><span class="line"><span class="keyword">String</span> filename = <span class="keyword">file</span>.getOriginalFilename();</span><br><span class="line"><span class="keyword">String</span> path = <span class="string">"F:\\download"</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">##判断文件是否已经存在,文件目录是否存在,不在就新建</span></span><br><span class="line"><span class="keyword">File</span> filefake = new <span class="keyword">File</span>(path,filename);</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (!filefake.getParentFile().<span class="keyword">exists</span>()) { </span><br><span class="line"> filefake.getParentFile().mkdirs();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">#把文件传输到指定路径</span></span><br><span class="line"><span class="keyword">file</span>.transferTo(new <span class="keyword">File</span>(path+<span class="keyword">File</span>.separator+filename));</span><br></pre></td></tr></table></figure>
<h2 id="下载">下载</h2>
<p>下载最重要的是设置**<span class="label info">Content-Disposition</span><strong>响应头和实体头部</strong><span class="label info">Content-Disposition</span>**</p>
<h3 id="Content-Disposition">Content-Disposition</h3>
<p>在常规的HTTP应答中,<strong><span class="label info">Content-Disposition</span></strong> 响应头指示回复的内容该以何种形式展示,是以<strong>内联</strong>的形式(即网页或者页面的一部分),还是以<strong>附件</strong>的形式下载并保存到本地。</p>
<p>在multipart/form-data类型的应答消息体中, <strong><span class="label info">Content-Disposition</span></strong> 消息头可以被用在multipart消息体的子部分中,用来给出其对应字段的相关信息。各个子部分由在<a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Type"><span class="label warning">Content-Type</span></a> 中定义的<strong>分隔符</strong>分隔。用在消息体自身则无实际意义。</p>
<p>Content-Disposition消息头最初是在MIME标准中定义的,HTTP表单及<a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/POST"><code>POST</code></a> 请求只用到了其所有参数的一个子集。只有<code>form-data</code>以及可选的<code>name</code>和<code>filename</code>三个参数可以应用在HTTP场景中。</p>
<h4 id="1-作为消息主体中的消息头">1.作为消息主体中的消息头</h4>
<p>在HTTP场景中,第一个参数或者是**<code>inline</code>**(默认值,表示回复中的消息体会以页面的一部分或者整个页面的形式展示),或者是<code>attachment</code>(意味着消息体应该被下载到本地;大多数浏览器会呈现一个“保存为”的对话框,将<code>filename</code>的值预填为下载后的文件名,假如它存在的话)。</p>
<div class="note default">
<p>Content-Disposition: inline<br>Content-Disposition: attachment<br>Content-Disposition: attachment; filename=“filename.jpg”</p>
</div>
<h4 id="2-作为multipart-body中的消息头">2.作为multipart body中的消息头</h4>
<div class="note default">
<p>Content-Disposition: form-data<br>Content-Disposition: form-data; attachment<br>Content-Disposition: form-data; attachment; filename=“filename.jpg”</p>
</div>
<blockquote>
<p>详细内容请查看<a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Disposition"><span class="label default">这里</span></a></p>
</blockquote>
<h3 id="Content-Type">Content-Type</h3>
<p><strong><span class="label info">Content-Type</span></strong> 实体头部用于指示资源的MIME类型 <a href="https://developer.mozilla.org/zh-CN/docs/Glossary/MIME_type">media type</a> 。</p>
<p>在响应中,<span class="label info">Content-Type</span>标头告诉客户端实际返回的内容的内容类型。浏览器会在某些情况下进行MIME查找,并不一定遵循此标题的值; 为了防止这种行为,可以将标题 <a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/X-Content-Type-Options"><code>X-Content-Type-Options</code></a> 设置为 <strong>nosniff</strong>。</p>
<p>在请求中 (如<a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/POST"><code>POST</code></a> 或 <a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/PUT"><code>PUT</code></a>),客户端告诉服务器实际发送的数据类型</p>
<blockquote>
<p>详细内容请查看<a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Type"><span class="label default">这里</span></a></p>
</blockquote>
<hr>
### 下载文件的设置
<figure class="highlight reasonml"><table><tr><td class="code"><pre><span class="line">#获取文件</span><br><span class="line">File file = <span class="keyword">new</span> <span class="constructor">File(<span class="params">url</span>)</span>;</span><br><span class="line">String filename = file.get<span class="constructor">Name()</span>; </span><br><span class="line"></span><br><span class="line">#设置响应头和实体部分</span><br><span class="line">response.set<span class="constructor">ContentType(<span class="string">"application/x-msdownload"</span>)</span>;</span><br><span class="line">response.set<span class="constructor">Header(<span class="string">"Content-Disposition"</span>, <span class="string">"attachment;filename="</span> + <span class="params">filename</span>)</span>;</span><br><span class="line"></span><br><span class="line">特殊的传导机制,把文件传输到响应中,类似response.get<span class="constructor">OutputStream()</span>.write<span class="literal">()</span>功能;</span><br><span class="line"><span class="module-access"><span class="module"><span class="identifier">Files</span>.</span></span>copy(file.<span class="keyword">to</span><span class="constructor">Path()</span>, response.get<span class="constructor">OutputStream()</span>);</span><br></pre></td></tr></table></figure>
<h3 id="在线查看文件的设置">在线查看文件的设置</h3>
<p>感觉跟下载有点想像,就请求头和实体部分不同而已</p>
<figure class="highlight vala"><table><tr><td class="code"><pre><span class="line"><span class="meta">#获取文件和文件名</span></span><br><span class="line">File file = <span class="keyword">new</span> File(url);</span><br><span class="line">String filename = file.getName();</span><br><span class="line"></span><br><span class="line"><span class="meta">#设置响应头和实体部分</span></span><br><span class="line">response.setHeader(<span class="string">"Content-Disposition"</span>, <span class="string">"attachment;filename="</span> + filename); response.setContentType(<span class="string">"application/pdf;charset=UTF-8"</span>);</span><br><span class="line"></span><br><span class="line"><span class="meta">#把文件存储在缓存流中</span></span><br><span class="line">byte[] b = <span class="keyword">new</span> byte[fis.available()];</span><br><span class="line">FileInputStream fis = <span class="literal">null</span>;</span><br><span class="line"><span class="meta">#把缓虫区的字符流读入b中</span></span><br><span class="line">fis.read(b);</span><br><span class="line"><span class="meta">#往响应中写入数据</span></span><br><span class="line">response.getOutputStream().write(b);</span><br><span class="line">fis.close();</span><br></pre></td></tr></table></figure>
]]></content>
<tags>
<tag>Java</tag>
</tags>
</entry>
<entry>
<title>Install_Navicat_with_Docker</title>
<url>/2020/12/07/Install-Navicat-with-Docker/</url>
<content><![CDATA[<h1>Navicat无法连接到Docker上的mysql</h1>
<p>Docker上装的是mysql 8.0</p>
<p>想用Navicat连接的时候,发现连接不上了,龟龟🐢🐢<a id="more"></a></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">Error:1251 - Client does not support authentication protocol requested by server; consider upgrading MySQL client.</span><br></pre></td></tr></table></figure>
<p>网上大多数人说,是因为新的mysql的权限更改了和安全提升了,对密码使用了强加密的模式,所以导致第三方软件无法登陆mysql。</p>
<p>然后我根据大多数人的建议,进入docker容器中,进入mysql</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'password' PASSWORD EXPIRE NEVER;</span><br><span class="line">mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123';</span><br><span class="line">mysql> FLUSH PRIVILEGES;</span><br></pre></td></tr></table></figure>
<p>但是修改完了,我还是报上面1251的错误,实在是不知道如何搞,就重新装了低版本mysql 5.7的数据库,就可以连接成功了。</p>
<h3 id="其实不用改版本">其实不用改版本</h3>
<p>为何还报错,那是因为我用远程连接,上面的代码修改的是本机上的访问,通过查询数据库配置,如下</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">mysql> SELECT Host,User,plugin from user;</span><br><span class="line">+-----------+------------------+-----------------------+</span><br><span class="line">| Host | User | plugin |</span><br><span class="line">+-----------+------------------+-----------------------+</span><br><span class="line">| % | luoj | caching_sha2_password |</span><br><span class="line">| % | root | caching_sha2_password |</span><br><span class="line">| localhost | mysql.infoschema | caching_sha2_password |</span><br><span class="line">| localhost | mysql.session | caching_sha2_password |</span><br><span class="line">| localhost | mysql.sys | caching_sha2_password |</span><br><span class="line">| localhost | root | mysql_native_password |</span><br><span class="line">+-----------+------------------+-----------------------+</span><br><span class="line">6 rows in set (0.00 sec)</span><br></pre></td></tr></table></figure>
<p>可知我只改了localhost上的插件,而我要改的是那个Host为<code>%</code>的,<code>%</code>代表任何主机。所以自然报错了</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">mysql> ALTER USER 'root'@'%' IDENTIFIED BY 'lj123456' PASSWORD EXPIRE NEVER;</span><br><span class="line">mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'lj123456';</span><br><span class="line">mysql> FLUSH PRIVILEGES;</span><br></pre></td></tr></table></figure>
<p>通过如上的配置就可以啦</p>
<h4 id="遇到-this-is-incompatible-with-sql-mode-only-full-group-by-错误">遇到 "this is incompatible with sql_mode=only_full_group_by"错误</h4>
<p>这个问题更大</p>
<p>通过网上网友的说法,发现是<code>select @@sql_mode;</code>,也就是sql_mode在搞鬼,然后我进去docker的mysql.5.7(mysql_02)中修改</p>
<p><code>/etc/mysql/mysql.conf.d/mysqld.cnf </code>,添加了<code>sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION</code>;然后重启mysql,发现自动退出容器,后无法再登陆这个容器了,报错了。龟龟,现在连容器都进不去,如何修改阿,龟龟</p>
]]></content>
</entry>
<entry>
<title>Maven依赖问题</title>
<url>/2020/09/05/Maven%E4%BE%9D%E8%B5%96%E9%97%AE%E9%A2%98/</url>
<content><![CDATA[<p>由于我的maven镜像配置是aliyun的,所以,我的所有依赖包都会去aliyun仓库去找,但是,一直找不到两个包</p>
<p>通过<a href="https://maven.aliyun.com/mvn/search">aliyun仓库服务</a>,我确实找不到这两个包的依赖,所以自然无法自动下载</p>
<a id="more"></a>
<p>但是我的<code>pom.xml</code>文件里面也配备了仓库啊,阿里云里面没有,那么我的<code>pom.xml</code>配备的仓库应该有了吧</p>
<p>构建我的项目却还一直报缺少依赖的错误。</p>
<p>通过上网查看,原因是:</p>
<p>我在<code>/path/to/maven/config/settings.xml</code>中看到我的mirrors属性中配置如下👇</p>
<figure class="highlight dts"><table><tr><td class="code"><pre><span class="line"><span class="params"><mirror></span></span><br><span class="line"> <span class="params"><id></span>aliyun<span class="params"></id></span></span><br><span class="line"> <span class="meta">#这里的“*”表示只用这个仓库,其他仓库都不用,全部忽略</span></span><br><span class="line"> <span class="params"><mirrorOf></span>*<span class="params"></mirrorOf></span></span><br><span class="line"> <span class="params"><name></span>aliyun maven<span class="params"></name></span></span><br><span class="line"> <span class="params"><url></span>http:<span class="comment">//maven.aliyun.com/nexus/content/groups/public</url></span></span><br><span class="line"><span class="params"></mirror></span></span><br></pre></td></tr></table></figure>
<p>由于这个原因,所以导致后面pom.xml配置的东西都被忽略了,所以才找不到那些依赖包💩</p>
]]></content>
<categories>
<category>Java</category>
</categories>
<tags>
<tag>maven</tag>
</tags>
</entry>
<entry>
<title>Multipart的处理方法</title>
<url>/2020/10/21/Mutipart%E7%9A%84%E5%A4%84%E7%90%86%E6%96%B9%E6%B3%95/</url>
<content><![CDATA[<h2 id="处理Multipart的方法">处理Multipart的方法</h2>
<blockquote>
<p>关于StandardServletMultipartResolvert和CommonsMultipartResolver的两种使用方法</p>
</blockquote>
<h3 id="1-StandardServletMultipartResolvert的用法">1.StandardServletMultipartResolvert的用法</h3>
<a id="more"></a>
<p>需具备条件:servlet3.0+</p>
<ul>
<li>在springmvc容器中配置添加类对象</li>
</ul>
<figure class="highlight routeros"><table><tr><td class="code"><pre><span class="line"><bean <span class="attribute">id</span>=<span class="string">"multipartResolver"</span> <span class="attribute">class</span>=<span class="string">"org.springframework.web.multipart.support.StandardServletMultipartResolver"</span>></bean></span><br></pre></td></tr></table></figure>
<ul>
<li>在web.xml文件中的<code><servlet></code>中配置如下:</li>
</ul>
<figure class="highlight fortran"><table><tr><td class="code"><pre><span class="line"><multipart-config></span><br><span class="line"> <<span class="built_in">max</span>-<span class="keyword">file</span>-<span class="built_in">size</span>><span class="number">20848820</span></<span class="built_in">max</span>-<span class="keyword">file</span>-<span class="built_in">size</span>></span><br><span class="line"> <<span class="built_in">max</span>-request-<span class="built_in">size</span>><span class="number">418018841</span></<span class="built_in">max</span>-request-<span class="built_in">size</span>></span><br><span class="line"> <<span class="keyword">file</span>-<span class="built_in">size</span>-threshold><span class="number">1048576</span></<span class="keyword">file</span>-<span class="built_in">size</span>-threshold></span><br><span class="line"></multipart-config></span><br></pre></td></tr></table></figure>
<h3 id="2-CommonsMultipartResolver的用法">2.CommonsMultipartResolver的用法</h3>
<p>需具备的条件:导入两个额外的包:<a href="https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload"><strong>commons-fileupload</strong></a>和<a href="https://mvnrepository.com/artifact/commons-io/commons-io"><strong>commons-io</strong></a></p>
<figure class="highlight applescript"><table><tr><td class="code"><pre><span class="line"><bean <span class="built_in">id</span>=<span class="string">"multipartResolver"</span> <span class="built_in">class</span>=<span class="string">"org.springframework.web.multipart.commons.CommonsMultipartResolver"</span>></span><br><span class="line"> <<span class="keyword">property</span> <span class="built_in">name</span>=<span class="string">"maxUploadSize"</span> value=<span class="string">"20000000"</span>></<span class="keyword">property</span>></span><br><span class="line"> <<span class="keyword">property</span> <span class="built_in">name</span>=<span class="string">"defaultEncoding"</span> value=<span class="string">"UTF-8"</span>></<span class="keyword">property</span>></span><br><span class="line"></bean></span><br></pre></td></tr></table></figure>
<h3 id="处理数据">处理数据</h3>
<p>我觉得都一样,只不过解析出来的MultipartHttpServletRequest不一样而已,获取数值的方式都一样的</p>
<p>法一:解析request获取/直接映射到参数上</p>
<figure class="highlight mipsasm"><table><tr><td class="code"><pre><span class="line"><span class="comment">#解析request请求</span></span><br><span class="line"><span class="keyword">MultipartHttpServletRequest </span><span class="keyword">multipartRequest </span>= (<span class="keyword">MultipartHttpServletRequest) </span>request;</span><br><span class="line"><span class="comment">#这样就可以获取到MultipartFile了</span></span><br><span class="line">Map<String, <span class="keyword">MultipartFile> </span>fileMap = <span class="keyword">multipartRequest.getFileMap();</span></span><br></pre></td></tr></table></figure>
<p>法二:把数据直接封装到模型类中</p>
<figure class="highlight haxe"><table><tr><td class="code"><pre><span class="line">List<MultipartFile> files = <span class="keyword">new</span><span class="type">User</span>.getFiles();</span><br><span class="line"></span><br><span class="line"><span class="meta">#要提前封装好模型类并实现序列化 </span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">NewUser</span> <span class="keyword"><span class="keyword">implements</span> <span class="type">Serializable</span></span></span>{</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">static</span> final long serialVersionUID = <span class="number">1</span>L;</span><br><span class="line"> <span class="keyword">private</span> <span class="keyword">String</span> username;</span><br><span class="line"> <span class="keyword">private</span> List<MultipartFile> files;</span><br><span class="line"> </span><br><span class="line"> ....<span class="keyword">get</span>/<span class="keyword">set</span> method...</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>Java</category>
</categories>
</entry>
<entry>
<title>Mybatis Generator</title>
<url>/2020/09/04/Mybatis-Generator/</url>
<content><![CDATA[<h2 id="前言">#前言</h2>
<p>通过<code>mybatis</code>跟数据库做IO,很方便,但是每次要写的<code>mapper</code>和<code>DAO</code>包括<code>Bean</code>,东西实在是太多了😢。所以通过颜群老师的在线课堂,我了解了<span class="ljspan ljspan-reverse ljspan-blue"><a href="http://mybatis.org/generator/index.html">Mybatis Generator</a></span>,可以一次性生成<code>Dao</code>、<code>mapper</code>和与数据库表对应的<code>bean</code>😆,真的很爽诶。</p>
<a id="more"></a>
<hr>
<h2 id="配置">配置</h2>
<p>在<span class="ljspan ljspan-blue"><a href="http://mybatis.org/generator/quickstart.html">官方文档</a></span>上,相关配置写得很清楚哦</p>
<h3 id="1-导入依赖包">1.导入依赖包</h3>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line">#引入依赖包</span><br><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.mybatis.generator<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>mybatis-generator-core<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.3.5<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span> </span><br></pre></td></tr></table></figure>
<h3 id="2-编写MBG-mybatis-generator-文件">2.编写MBG(mybatis generator)文件</h3>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="meta"><!DOCTYPE <span class="meta-keyword">generatorConfiguration</span> <span class="meta-keyword">PUBLIC</span></span></span><br><span class="line"><span class="meta"> <span class="meta-string">"-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"</span></span></span><br><span class="line"><span class="meta"> <span class="meta-string">"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"</span>></span></span><br><span class="line"><span class="tag"><<span class="name">generatorConfiguration</span>></span></span><br><span class="line"> <span class="comment"><!--生成Mybatis3Simple形式的配置文件--></span></span><br><span class="line"> <span class="tag"><<span class="name">context</span> <span class="attr">id</span>=<span class="string">"simple"</span> <span class="attr">targetRuntime</span>=<span class="string">"MyBatis3Simple"</span>></span></span><br><span class="line"> <span class="comment"><!--配置数据库连接--></span></span><br><span class="line"> <span class="tag"><<span class="name">jdbcConnection</span> <span class="attr">driverClass</span>=<span class="string">"org.hsqldb.jdbcDriver"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">connectionURL</span>=<span class="string">"jdbc:hsqldb:mem:aname"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">userId</span>=<span class="string">"username"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">password</span>=<span class="string">"password"</span> /></span></span><br><span class="line"> <span class="comment"><!--配置数据库表生成的对应bean--></span></span><br><span class="line"> <span class="tag"><<span class="name">javaModelGenerator</span> <span class="attr">targetPackage</span>=<span class="string">"example.model"</span> <span class="attr">targetProject</span>=<span class="string">"src/main/java"</span>/></span></span><br><span class="line"> <span class="comment"><!--配置mapper--></span></span><br><span class="line"> <span class="tag"><<span class="name">sqlMapGenerator</span> <span class="attr">targetPackage</span>=<span class="string">"example.mapper"</span> <span class="attr">targetProject</span>=<span class="string">"src/main/resources"</span>/></span></span><br><span class="line"> <span class="comment"><!--配置dao--></span></span><br><span class="line"> <span class="tag"><<span class="name">javaClientGenerator</span> <span class="attr">type</span>=<span class="string">"XMLMAPPER"</span> <span class="attr">targetPackage</span>=<span class="string">"example.mapper"</span> <span class="attr">targetProject</span>=<span class="string">"src/main/java"</span>/></span></span><br><span class="line"> <span class="comment"><!--配置数据库表--></span></span><br><span class="line"> <span class="tag"><<span class="name">table</span> <span class="attr">schema</span>=<span class="string">"wxproject' tableName="</span><span class="attr">FooTable</span>" <span class="attr">domainObjectName</span>=<span class="string">"FooTable"</span> /></span></span><br><span class="line"> <span class="tag"></<span class="name">context</span>></span></span><br><span class="line"><span class="tag"></<span class="name">generatorConfiguration</span>></span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>生成的<code>mybatis</code>相关文件内容,都跟MBG文件👀有关</p>
</blockquote>
<hr>
<h2 id="实现">实现</h2>
<h3 id="运行MBG配置文件">运行MBG配置文件</h3>
<p>有很<a href="http://mybatis.org/generator/running/running.html">多种方式</a>,我使用<code>java</code>方法,直接调用测试运行或者<code>main</code>函数内与运行</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">List<String> warnings = <span class="keyword">new</span> ArrayList<String>();</span><br><span class="line"> <span class="keyword">boolean</span> overwrite = <span class="keyword">true</span>;</span><br><span class="line"> <span class="comment">//你的mbg文件,可以直接放在项目根目录中,这样就不用写路径了</span></span><br><span class="line"> File configFile = <span class="keyword">new</span> File(<span class="string">"generatorConfig.xml"</span>);</span><br><span class="line"> ConfigurationParser cp = <span class="keyword">new</span> ConfigurationParser(warnings);</span><br><span class="line"> Configuration config = cp.parseConfiguration(configFile);</span><br><span class="line"> DefaultShellCallback callback = <span class="keyword">new</span> DefaultShellCallback(overwrite);</span><br><span class="line"> MyBatisGenerator myBatisGenerator = <span class="keyword">new</span> MyBatisGenerator(config, callback, warnings);</span><br><span class="line"> myBatisGenerator.generate(<span class="keyword">null</span>);</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="Mybatis-Example">Mybatis Example</h2>
<p>刚开始接触到 <span class="ljspan ljspan-green">mybatis Example</span>的时候,我都是绕道走(甚至干脆不生成它),自己在mybatis生成的实例里面重新写方法,后面才发现它,大有用处😂,一起来看看吧!</p>
<figure class="highlight dart"><table><tr><td class="code"><pre><span class="line"><span class="built_in">int</span> countByExample(UserExample example) thorws SQLException 按条件计数</span><br><span class="line"><span class="built_in">int</span> deleteByPrimaryKey(Integer id) thorws SQLException 按主键删除</span><br><span class="line"><span class="built_in">int</span> deleteByExample(UserExample example) thorws SQLException 按条件查询</span><br><span class="line"><span class="built_in">String</span>/Integer insert(User record) thorws SQLException 插入数据(返回值为ID)</span><br><span class="line">User selectByPrimaryKey(Integer id) thorws SQLException 按主键查询</span><br><span class="line">ListselectByExample(UserExample example) thorws SQLException 按条件查询</span><br><span class="line">ListselectByExampleWithBLOGs(UserExample example) thorws SQLException 按条件查询(包括BLOB字段)。只有当数据表中的字段类型有为二进制的才会产生。</span><br><span class="line"><span class="built_in">int</span> updateByPrimaryKey(User record) thorws SQLException 按主键更新</span><br><span class="line"><span class="built_in">int</span> updateByPrimaryKeySelective(User record) thorws SQLException 按主键更新值不为<span class="keyword">null</span>的字段</span><br><span class="line"><span class="built_in">int</span> updateByExample(User record, UserExample example) thorws SQLException 按条件更新</span><br><span class="line"><span class="built_in">int</span> updateByExampleSelective(User record, UserExample example) thorws SQLException 按条件更新值不为<span class="keyword">null</span>的字段</span><br></pre></td></tr></table></figure>
<blockquote>
<p>很多关于 <span class="ljspan ljspan-green">mybatis Example</span>的方法吧</p>
</blockquote>
<h3 id="案例:">案例:</h3>
<p>Mybatis的逆向工程中会生成实例及实例对应的example,example用于添加条件,相当where后面的部分</p>
<figure class="highlight reasonml"><table><tr><td class="code"><pre><span class="line">xxxExample example = <span class="keyword">new</span> xxx<span class="constructor">Example()</span>;</span><br><span class="line">Criteria criteria = <span class="keyword">new</span> <span class="constructor">Example()</span>.create<span class="constructor">Criteria()</span>;</span><br><span class="line">example.</span><br></pre></td></tr></table></figure>
<blockquote>
<p>example和criteria有很多的方法可供使用</p>
</blockquote>
<figure class="highlight csharp"><table><tr><td class="code"><pre><span class="line">example.setOrderByClause(“字段名 ASC”); 添加升序排列条件,DESC为降序</span><br><span class="line">example.setDistinct(<span class="literal">false</span>) 去除重复,boolean型,<span class="literal">true</span>为选择不重复的记录。</span><br><span class="line">criteria.andXxxIsNull 添加字段xxx为<span class="literal">null</span>的条件</span><br><span class="line">criteria.andXxxIsNotNull 添加字段xxx不为<span class="literal">null</span>的条件</span><br><span class="line">criteria.andXxxEqualTo(<span class="keyword">value</span>) 添加xxx字段等于<span class="keyword">value</span>条件</span><br><span class="line">criteria.andXxxNotEqualTo(<span class="keyword">value</span>) 添加xxx字段不等于<span class="keyword">value</span>条件</span><br><span class="line">criteria.andXxxGreaterThan(<span class="keyword">value</span>) 添加xxx字段大于<span class="keyword">value</span>条件</span><br><span class="line">criteria.andXxxGreaterThanOrEqualTo(<span class="keyword">value</span>) 添加xxx字段大于等于<span class="keyword">value</span>条件</span><br><span class="line">criteria.andXxxLessThan(<span class="keyword">value</span>) 添加xxx字段小于<span class="keyword">value</span>条件</span><br><span class="line">criteria.andXxxLessThanOrEqualTo(<span class="keyword">value</span>) 添加xxx字段小于等于<span class="keyword">value</span>条件</span><br><span class="line">criteria.andXxxIn(List<?>) 添加xxx字段值在List<?>条件</span><br><span class="line">criteria.andXxxNotIn(List<?>) 添加xxx字段值不在List<?>条件</span><br><span class="line">criteria.andXxxLike(“%”+<span class="keyword">value</span>+”%”) 添加xxx字段值为<span class="keyword">value</span>的模糊查询条件</span><br><span class="line">criteria.andXxxNotLike(“%”+<span class="keyword">value</span>+”%”) 添加xxx字段值不为<span class="keyword">value</span>的模糊查询条件</span><br><span class="line">criteria.andXxxBetween(value1,value2) 添加xxx字段值在value1和value2之间条件</span><br><span class="line">criteria.andXxxNotBetween(value1,value2) 添加xxx字段值不在value1和value2之间条件</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="附加配置">附加配置</h2>
<p>针对<code>mybatis</code>,它还有一个配置文件<a href="http://mybatis.org/generator/afterRunning.html">MapperConfig.xml</a>,它对<span class="ljspan ljspan-black"><a href="https://mybatis.org/mybatis-3/zh/index.html">MyBatis</a> </span>行为的设置和属性信息有关,可以通过<span class="ljspan ljspan-reverse ljspan-black"><a href="https://mybatis.org/mybatis-3/zh/configuration.html#settings">配置参数</a></span>来设置生成mybatis相关文件的内容形式,比如<code>mapUnderscoreToCamelCase</code>开启<code>驼峰命名自动映射</code></p>
<hr>
<h2 id="注意事项">注意事项</h2>
<p>1.一般使用<code>mybatis generator</code>生成的<code>bean</code>,都是没有构造函数的;所以需要自己新建,但是如果有有参构造函数,就必须要有无参构造函数,这是必须的。</p>
<p>2.使用mybatis generator生成mapper.xml(也就是数据库语言),发现只有几个功能,而且关键的insertSelective方法没有,这就很尴尬了😖,我改了依赖包发现没有用,最后发现是在mbg的配置文件中<context>中的属性targetRuntime,从原来的MyBatis3Simple改为MyBatis3,就可以了。</p>
<p>3.💥记得在<code>SpringIoC</code>容器中添加<code>mapperscannerconfigurer</code>这个<code>bean</code>,不然无法使用<code>dao</code>层里面的接口,因为<code><context:component-scan></code>扫描不包括<code>dao</code>层。</p>
<hr>
<h2 id="常见问题">常见问题</h2>
<h4 id="1-MyBatis-Generator-生成器把其他数据库的同名表生成下来的问题"><strong>1.MyBatis Generator 生成器把其他数据库的同名表生成下来的问题</strong></h4>
<p>这是因为mysql不支持schema和catalog,所以需要在<jabcConnection>中添加属性“ <property name=“nullCatalogMeansCurrent” value=“true”/>”</p>
<p>😵我看不懂🐢🐢,反正加了就对了,既解决了问题,加了对程序也没啥影响。</p>
<p><a href="https://blog.csdn.net/qq_40233736/article/details/83314596">参考文档</a></p>
]]></content>
<categories>
<category>Java</category>
</categories>
<tags>
<tag>mybatis</tag>
<tag>Spring</tag>
</tags>
</entry>
<entry>
<title>Microsoft-Store打不开?</title>
<url>/2020/09/05/Microsoft-Store%E6%89%93%E4%B8%8D%E5%BC%80/</url>
<content><![CDATA[<p><strong>打不开microsoft的应用商城,window更新也没办法?</strong>,其实更新就可以了,只不过你的更新不是真正的更新🙌</p>
<blockquote>
<p>采用这个方法打开Microsoft Store,并不需要翻墙哦✔️</p>
</blockquote>
<a id="more"></a>
<h2 id="步骤">步骤</h2>
<p> 1.到<strong>服务</strong>⚙️里面打开<code>Windows</code>更新,就可以更新<code>Windows</code></p>
<p> 2.等待更新好了,重启系统💻,查看更新并尝试打开<code>Store</code>🏠,如果更新那里还是提示重启以完成重要更新,记得再重启</p>
<p> 3.这样,一般就可以打开<code>Store</code></p>
<h2 id="注意事项">注意事项</h2>
<ul>
<li>
<p>如果可以打开<code>Store</code>,但是图片加载不出来,<code>store</code>某些选项也打不开</p>
</li>
<li>
<p>打开系统自带**<code>IE</code>浏览器**,进入**<code>Internet</code>选项<strong>后,选择</strong>连接**栏目</p>
</li>
<li>
<p>点击<strong>局域网设置</strong>,进入设置页面以后,勾选上<strong>自动检测设置</strong>其他都不勾选</p>
</li>
<li>
<p>点击<strong>确定</strong>离开,就可以进入<code>Store</code>了</p>
</li>
</ul>
]]></content>
<categories>
<category>Windows</category>
</categories>
<tags>
<tag>Windows</tag>
</tags>
</entry>
<entry>
<title>PageHelper</title>
<url>/2020/10/15/PageHelper/</url>
<content><![CDATA[<p>没使用过分页之前,不觉得分页难,等到需要用到的时候,完全没有头绪,直到遇到<span class="ljspan ljspan-reverse ljspan-red">Mybatis Pagination</span> - <span class="ljspan ljspan-reverse ljspan-blue">PageHelper</span>才让我松了一口气,<span class="ljspan ljspan-reverse ljspan-blue">PageHelper</span>封装了很多分页的功能,判断前一页/后一页,第一页或最后一页;几个页面的数据封装在列表中,一次只显示这几个页面,快来看看吧😆<a id="more"></a></p>
<h3 id="配置">配置</h3>
<p><strong>引入依赖包</strong></p>
<figure class="highlight"><table><tr><td class="code"><pre><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>x.x.x</version></span><br><span class="line"></dependency></span><br></pre></td></tr></table></figure>
<p><strong>配置PageHelper</strong></p>
<blockquote>
<p>使用mybatis-config.xml配置,还可以使用Spring容器配置,详情请看<a href="https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/en/HowToUse.md">官方文档</a></p>
</blockquote>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment"><!-- </span></span><br><span class="line"><span class="comment"> In the configuration file, </span></span><br><span class="line"><span class="comment"> plugins location must meet the requirements as the following order:</span></span><br><span class="line"><span class="comment"> properties?, settings?, </span></span><br><span class="line"><span class="comment"> typeAliases?, typeHandlers?, </span></span><br><span class="line"><span class="comment"> objectFactory?,objectWrapperFactory?, </span></span><br><span class="line"><span class="comment"> plugins?, </span></span><br><span class="line"><span class="comment"> environments?, databaseIdProvider?, mappers?</span></span><br><span class="line"><span class="comment">--></span></span><br><span class="line"><span class="tag"><<span class="name">plugins</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">plugin</span> <span class="attr">interceptor</span>=<span class="string">"com.github.pagehelper.PageInterceptor"</span>></span></span><br><span class="line"> <span class="comment"><!-- config params as the following --></span></span><br><span class="line"> <span class="comment"><!--offset 等于 pageNum, limit 等于 pageSize--></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"RowBounds"</span> <span class="attr">value</span>=<span class="string">"true"</span>/></span></span><br><span class="line"> <span class="comment"><!--pageNum <= 0 等于 the first page, pageNum> pages(total pages)等于 the last page--></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"reasonable"</span> <span class="attr">value</span>=<span class="string">"true"</span>/></span></span><br><span class="line"> <span class="tag"><<span class="name">property</span> <span class="attr">name</span>=<span class="string">"param1"</span> <span class="attr">value</span>=<span class="string">"value1"</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">plugin</span>></span></span><br><span class="line"><span class="tag"></<span class="name">plugins</span>></span></span><br></pre></td></tr></table></figure>
<p>更多关于参数的配置,请参考<a href="https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/en/HowToUse.md">官方文档</a></p>
<hr>
<h3 id="使用">使用</h3>
<blockquote>
<p>我直接使用pageInfo对象来操作分页数据的</p>
</blockquote>
<figure class="highlight reasonml"><table><tr><td class="code"><pre><span class="line">/获取第<span class="number">1</span>页,<span class="number">10</span>条内容,默认查询总数count</span><br><span class="line"><span class="module-access"><span class="module"><span class="identifier">PageHelper</span>.</span></span>start<span class="constructor">Page(1, 10)</span>;</span><br><span class="line">List<User> <span class="built_in">list</span> = userMapper.select<span class="constructor">All()</span>;</span><br><span class="line"><span class="comment">//用PageInfo对结果进行包装</span></span><br><span class="line">PageInfo page = <span class="keyword">new</span> <span class="constructor">PageInfo(<span class="params">list</span>)</span>;</span><br><span class="line"><span class="comment">//这里的page是一个对象,可以通过引入fastjson包,</span></span><br><span class="line"><span class="comment">//直接解析对象为json对象返回页面</span></span><br><span class="line"><span class="comment">//这样就能一步到位,在前端获取到分页信息。</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//测试PageInfo全部属性</span></span><br><span class="line"><span class="comment">//PageInfo包含了非常全面的分页属性</span></span><br><span class="line"><span class="keyword">assert</span><span class="constructor">Equals(1, <span class="params">page</span>.<span class="params">getPageNum</span>()</span>);</span><br><span class="line"><span class="keyword">assert</span><span class="constructor">Equals(10, <span class="params">page</span>.<span class="params">getPageSize</span>()</span>);</span><br><span class="line"><span class="keyword">assert</span><span class="constructor">Equals(1, <span class="params">page</span>.<span class="params">getStartRow</span>()</span>);</span><br><span class="line"><span class="keyword">assert</span><span class="constructor">Equals(10, <span class="params">page</span>.<span class="params">getEndRow</span>()</span>);</span><br><span class="line"><span class="keyword">assert</span><span class="constructor">Equals(183, <span class="params">page</span>.<span class="params">getTotal</span>()</span>);</span><br><span class="line"><span class="keyword">assert</span><span class="constructor">Equals(19, <span class="params">page</span>.<span class="params">getPages</span>()</span>);</span><br><span class="line"><span class="keyword">assert</span><span class="constructor">Equals(1, <span class="params">page</span>.<span class="params">getFirstPage</span>()</span>);</span><br><span class="line"><span class="keyword">assert</span><span class="constructor">Equals(8, <span class="params">page</span>.<span class="params">getLastPage</span>()</span>);</span><br><span class="line"><span class="keyword">assert</span><span class="constructor">Equals(<span class="params">true</span>, <span class="params">page</span>.<span class="params">isFirstPage</span>()</span>);</span><br><span class="line"><span class="keyword">assert</span><span class="constructor">Equals(<span class="params">false</span>, <span class="params">page</span>.<span class="params">isLastPage</span>()</span>);</span><br><span class="line"><span class="keyword">assert</span><span class="constructor">Equals(<span class="params">false</span>, <span class="params">page</span>.<span class="params">isHasPreviousPage</span>()</span>);</span><br><span class="line"><span class="keyword">assert</span><span class="constructor">Equals(<span class="params">true</span>, <span class="params">page</span>.<span class="params">isHasNextPage</span>()</span>);</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>Java</category>
</categories>
</entry>
<entry>
<title>Request-and-Response</title>
<url>/2020/09/11/Request-and-Response/</url>
<content><![CDATA[<h2 id="Get请求">Get请求</h2>
<p><code>Get</code>请求✉️的参数是<code>Get</code>请求的附带信息,不再请求体内,而在请求体外,<code>Post</code>请求才是在请求体内</p>
<p>那为什么还用获取<code>Get</code>请求参数还需要用到<code>Request</code>对象呢❓</p>
<a id="more"></a>
<p>通过查询源码📜,知道原来获取<code>the query string or posted form data</code>都需要通过<code>Request</code>对象的<code>getParameter</code>方法来获取的,而如果时<code>Post</code>请求数据,则一般通过<code>Request</code>对象的<code>getInputStream</code>或<code>getReader</code>方法来实现</p>
<h2 id="使用HttpUrlConnection来实现Get-Post请求">使用HttpUrlConnection来实现Get/Post请求</h2>
<p>发现<code>Get</code>请求使用<code>connection</code>方法来实现发送请求📧需要开启和关闭,但是<code>Post</code>却不用,那到底是什么原因呢❓,原来<code>Post</code>请求有<code>DoInput/DoOutput</code>属性,这个属性允许这个连接向服务器自动提交数据和获取数据。所以,一般看到关闭缓存流🌊之类的,其实就在自动发送请求啦</p>
<h2 id="请求方法类型">请求方法类型</h2>
<p>请求的方法类型有<code>get</code>、<code>post</code>、<code>put</code>、<code>delete</code>等📬,除了在前端页面设置,一般都是在<code>controller</code>层设置它的类型</p>
]]></content>
<categories>
<category>Java</category>
</categories>
</entry>
<entry>
<title>SSM架构解析</title>
<url>/2020/09/05/SSM%E6%9E%B6%E6%9E%84%E8%A7%A3%E6%9E%90/</url>
<content><![CDATA[<h3 id="🔰SSM框架">🔰SSM框架</h3>
<p><code>SSM</code>框架可以分为三个部分来看待,第一部分是<code>springmvc</code>,另一部分为<code>spring</code>的<code>DI</code>和<code>IoC</code>,再一个就是<code>MyBatis</code>了</p>
<p>首先启动项目时,就是先加载<code>web.xml</code>;</p>
<p>监听器>过滤器><code>Servlet</code></p>
<p>所以监听器会先加载<code>Spring</code>容器的配置文件</p>
<a id="more"></a>
<p>然后过滤器把请求的内容设置为同意的字符编码之类的设置</p>
<p>最后才是<code>Servlet</code>拦截器拦截请求,到<code>SpringMVC</code>中处理</p>
<hr>
<h4 id="🍃Spring部分:">🍃Spring部分:</h4>
<p><a href="https://www.zhihu.com/question/23277575"><code>DI</code>和<code>IoC</code>的简单解释</a></p>
<p><code>DI</code>:依赖注入就是让对象之间的耦合性减少,让每个对象更加灵活,便于修改;</p>
<p><code>IoC</code>:就是把创建对象的主体又程序员转为<code>Spring</code>或其他控制反转容器</p>
<p><code>ApplicationContext</code>就是一个控制反转容器</p>
<p><code>ApplicationContext</code>里面都是一个个<code>bean</code>,也就是对象</p>
<p><code>bean</code>的<code>property</code>属性对应对象的setter方法注入实例化;而<code>constructor-arg</code>属性对应对象的构造器方法实例化</p>
<hr>
<h4 id="🌀Springmvc">🌀Springmvc</h4>
<p><img src="/assets/img/image-20200518131134856.png" alt="请求响应流程图"></p>
<p>当用户在浏览器点击链接或提交表单的时候,请求就开始工作了</p>
<p>请求的第一站会通过一个其前端控制器,<code>SSM</code>这里就是<code>DispacherServlet</code>;</p>
<p>然后第二站,<code>DispacherServlet</code>会将请求发送给<code>SpringMVC</code>控制器(<code>Controller</code>)。控制器是一个用于处理请求的<code>Spring</code>组件。一般都会有多个控制器,这时候,<code>DispacherServlet</code>就会查询一个会多个处理映射器来找到那个控制器;</p>
<p>第三站,到了控制器,请求会卸下器负载(也就是请求的信息)兵等待控制器处理</p>
<p>到了第四站,控制器在完成处理后,会产生一些信息,这些信息要返回给用户并在浏览器显示。这些信息被称为模型(<code>model</code>)。当然还有一个视图名来代表视图,所以控制器最后一件事就是将请求连同模型和视图名发送回<code>DispacherServlet</code></p>
<p>然后到了第五站,<code>DispacherServlet</code>有视图解析器,它将逻辑视图名匹配为一个特定的视图实现</p>
<p>然后就是第六站,<code>DispacherServlet</code>将模型数据渲染到视图上</p>
<p>第七步就是视图通过响应对象传递给客户端</p>
<hr>
<h4 id="☁️Mybatis">☁️Mybatis</h4>
<p>事务控制:就是让数据库的更新能够具备事务的四种原则:原子性、隔离性、一致性、持续性;这样就可以使数据库的更新不出现脏读幻读等情况。</p>
<p>数据源:一般用<code>C3P0</code>来管理,实现连接数据库可以一次性多次连接多次提交等</p>
<p>扫描器(<code>MapperScannerConfigurer</code>)扫描所有的<code>Dao</code>接口实现,加入到<code>IoC</code>容器中</p>
<p><code>SqlSessionFactory</code>可以配置<code>Spring</code>和<code>MyBatis</code>的整合</p>
]]></content>
<categories>
<category>Java</category>
</categories>
<tags>
<tag>SSM</tag>
</tags>
</entry>
<entry>
<title>SSM框架知识点</title>
<url>/2020/09/11/SSM%E6%A1%86%E6%9E%B6%E7%9F%A5%E8%AF%86%E7%82%B9/</url>
<content><![CDATA[<h2 id="SSM框架涉及到的知识点">SSM框架涉及到的知识点</h2>
<ol>
<li>
<p><strong>group id 和 artifact id</strong></p>
<p>创建maven项目,group id 和 artifact id都是必须要填写的,因为项目位置就是通过这两个id去查找的,group id 一般分为多个段,第一段为域,第二段为公司名称(这里就说两段而已)。<a id="more"></a>域又分为org、com、cn等;</p>
<p>而artifact id 一般为项目名称</p>
</li>
<li>
<p><strong>facet 定义了 java ee 项目的特性和要求</strong></p>
<p>一般创建一个maven项目,都没有web.xml文件,这是因为该项目还不是一个动态web项目,需要指定一下其特性,也就是下面得Project facets属性</p>
</li>
<li>
<p><strong>applicationContext配置</strong></p>
<p>属性配置中可用value来获取一些相对目录的数值或文件</p>
</li>
<li>
<p><strong><mvc:annotation-driven></strong></p>
<p><mvc:annotation-driven>标签其实就是分发请求给controller方法,它能够映射请求URL和参数给响应的controller方法。</p>
</li>
<li>
<p><strong><context:component-scan></strong></p>
<p><context:component-scan>则是扫描指定包下的类并注册这些包下的被注解标记的组件为Spring的bean</p>
</li>
<li>
<p><strong>jdbcUrl</strong></p>
<p><code>JDBC URL: jdbc:mysql://<host><port>/<database_name></code></p>
<p>默认端口3306,如果服务器使用默认端口则port可以省略</p>
<p>MySQL Connector/J Driver 允许在URL中添加额外的连接属性</p>
<p><code>jdbc:mysql://<host>:<port>/<database_name>?property1=value1&property2=value2</code></p>
</li>
<li>
<p><strong>SqlSessionFactoryBean</strong></p>
<p>正如SqlSessionFactoryBean的名字,它是生产SqlSessionFactory的工厂Bean;SqlSessionFactory是一种生产SqlSession的工厂;SqlSession是代表数据库连接客户端和数据库Server之间的会话信息;SqlSession实现发送sql语句,管理事务和获取mapper;</p>
<p>SqlSession是关联到具体数据库连接的,但是如果每次创建和销毁都直接操作物理连接的话,那么这个资源浪费很高,效率很低。</p>
<p>使用数据库连接池时,关闭SqlSession实例 ,其实只是把数据库连接对象(代表物理资源)放回到对象池中,并没有直接销毁,使用连接池技术极大提高了物理资源利用率,缩减了创建物理连接所需的时间、资源等等</p>
<p>相关知识点出处<a href="https://www.jianshu.com/p/f19a58938959">在这里</a></p>
</li>
<li>
<p><strong>关于mapper映射的详解</strong></p>
<p>还不是很懂接口和mapper映射之间如何做到关联的</p>
<p>通过 <a href="Mybatis%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E7%B2%BE%E9%80%9A.md">Mybatis从入门到精通</a> 可大概了解。dao层的接口和mapper映射是通过动态代理来实现的。只要在SpringIoC容器中实现mapperScannerConfigurer类就行,这个mapper其实解释起来比较复杂,因为spring帮忙做了很多事,首先就是调用接口可以直接调用到mapper.xml里面的数据库语句;这个就是mybatis里面的动态代理;但是mapper接口要实现这个功能,还需要实现类,这个实现类可以获取到sqlsessionfactory来获取session后调用mapper接口,然后mapperScannerConfigurer可以一次性扫描多个接口,并实现这个接口生成实现类</p>
<p>参考文档在<a href="http://mybatis.org/spring/zh/mappers.html">这里</a></p>
</li>
<li>
<p><strong>事务管理/声明式事务管理</strong></p>
<p>事务管理需要数据库的连接,所以一定要导入数据源;</p>
<p>声明式事务管理有两种,一种是基于tx和aop命名空间的xml配置文件;一种是基于@Transactional注解</p>
<p>相关参考文档在<a href="https://blog.csdn.net/donggua3694857/article/details/69858827">这里</a></p>
</li>
<li>
<p><strong>aop和tx在事务方面的理解</strong></p>
<p>对于tx在applicationContext中出现,我一直不理解它是何物,现在知道了</p>
<p><tx:advice>其实就是aop的通知,而<tx:attributes>和<tx:method>其实就是针对service里面的方法设置的事务管理属性,也不知道对不对。。。。。<strong>待续!!!</strong></p>
<p>我觉得是对的,哭了😭😭</p>
</li>
<li>
<p><strong><aop:poincut><strong>中的</strong>expresstion</strong></p>
<p>比如这一个<code>execution(* cn.lj.service..*(..))</code>,第一个<code>*</code>表示返回值,这里表示任意;然后是包service;然后是service下类的任意方法,就是那个<code>*</code>,最后<code>(..)</code>是所有参数</p>
<p>最靠近<code>(..)</code>的为方法名,靠近<code>.\*(..))</code>的为类名或者接口名,如上例的JoinPointObjP2.*(…))</p>
<p><a href="https://blog.csdn.net/kkdelta/article/details/7441829">相关内容链接</a></p>
</li>
<li>
<p><strong>启动项目失败,无法找到applicationContext.xml</strong></p>
<p>我觉得很奇怪,刚开始是因为resources文件夹没写对,然后修改以后还是不行,最后发现,我的项目之前是jar 类型而不是war类型,所以才一直不成功的</p>
</li>
<li>
<p><strong>Spring Aop</strong></p>
<p><aop:aspect>是面向切面编程;而<aop:advisor>则是进行事务管理,但二者的实现原理都是一样的</p>
</li>
<li>
<p><strong><mvc:annotation-driven></strong></p>
<p>这个东西是干嘛用的?其实讲起来挺麻烦的,简单点就是实现请求的映射,也就是完成对requestmapping这个注解的实现,同时还有请求参数等的设置(比如:@param)都是通过它来实现</p>
</li>
<li>
<p><strong>java properties file</strong></p>
<p>我想通过<code><context:property-placeholder /></code>动态引入一些数据库连接属性,但是一直报错,无法解析;最后发现原来是我的文件名写错了,因为一般java的属性文件都是以“properties”结尾的,但是我拼措了;</p>
<p><strong>!!!怎么说,发现spring里面很多配置的东西都需要特别注意名字</strong></p>
</li>
<li>
<p><strong>Spring单元测试</strong></p>
<p>使用spring的测试模块,需要导入spring-test包</p>
</li>
<li>
<p><strong>单元测试Mybatis</strong></p>
<p>记得在SpringIoC容器中添加mapperscannerconfigurer这个bean,不然无法使用dao层里面的接口,因为<code><context:component-scan></code>扫描不包括dao层。</p>
</li>
<li>
<p><strong>@Autowired</strong></p>
<p>spring可以实现控制反转,就是实例化对象,但是如果对象里面有属性呢?那就用注解@autowired 直接注入属性</p>
</li>
<li>
<p><strong>bean作用域singleton和prototype的区别</strong></p>
<p>singleton:容器在初始化时,就会创建对象;单例也支持延迟加载(就是只有在请求时再生成);</p>
<p>prototype:容器在初始化时,不创建对象,只是在每次使用时(每次容器获取对象时)再创建对象;并且每次获取对象都会创建一个新的对象;</p>
</li>
<li>
<p><strong>Bean的生命周期不同于IoC容器等的生命周期</strong></p>
<p>Bean的生命周期:创建—初始化(实例化)—销毁</p>
<p>容器生命周期:初始化—使用—销毁</p>
</li>
<li>
<p><strong>取余方法可以用来筛选数</strong></p>
<p>比如筛选“小于20”的数,就可以用取余方法,我是在使用任意对象取值时遇到的;如下:int value = random.nextInt()%20</p>
</li>
<li>
<p><strong>random对象</strong></p>
<p>取任意值的时候,放在方法里面的数,比如value,只会取“0到value-1”这个范围的数。</p>
</li>
<li>
<p><strong>graphics对象</strong>(图形上下文)</p>
<p>graphics是可以用来对几何图形的坐标转换,颜色管理和文本布局的操作的。比如在里面画线画点写字都可以,我是用来构建验证码的。image通过方法getGraphics()可获取到这个对象</p>
</li>
<li>
<p><strong>bufferimage对象</strong></p>
<p>这个对象只是image对象的子类,但是带有缓冲区,可以自由的操作修改,一般通过getGraphics()获取到图形的上下文对象后进行各个方面的修改。</p>
</li>
<li>
<p><strong>上传文件</strong>–(相关包:common-fileupload.jar)</p>
<p>请求request里面有multipartFiles,但是,一直取不到里面的值;然后通过debug看,requestl里面不止有它呢,还有其他很多。通过封装对象,把multipartFile封装到对象newuser中的属性(List<MultipartFile>)files中,然后返回newuser值后调用它的方法获取files[0],就可以获取里面MultipartFile类型的值;</p>
<p>关于之前request里面的值,仔细查看这个request,发现它是DefaultMultipartHttpServletRequest,所以只要把请求改为它,就可以获取到里面的MultipartFiles了</p>
</li>
<li>
<p><strong>上传下载路径设置</strong></p>
<p>利用请求<code>request.getServletContext().getRealPath("/upload/");</code>获取到得这个文件路径很奇怪,结果是<code>C:\Users\llj\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\demo2\upload\</code>所以我当初在项目里面找是找不到的,后面使用String直接设置,简单明了;</p>
</li>
<li>
<p><strong>下载要点</strong></p>
<p>下载比上传复杂点,都要设置ContentType和请求头的Content-Disposition属性,有两种方法:</p>
<p>法一:直接在响应中设置文件,需要使用到这个方法<em>Files.copy(要下载的文件的路径,响应的输出流)</em></p>
<p>法二:(使用Spring框架)返回值为ResponseEntity<byte[]></p>
</li>
<li>
<p><strong>spring配置redis</strong></p>
<p>使用1.8版本及以下版本,配置redistemplate时,用jedisConnectionFactory时,可以直接配置ip和port,poolconfig;但是高于1.8版本我就找不到这个东西了</p>
</li>
<li>
<p><strong>关于maven pom文件中 scope的分类</strong></p>
<p>网友关于这些分类的<a href="https://www.cnblogs.com/molao-doing/articles/Maven.html">解释</a></p>
<ul>
<li>默认是<strong>compile</strong>,表示被依赖需要参与当前项目的编译,测试、运行也一样参与其</li>
<li><strong>runtime</strong>表示依赖包无需参与项目的编译,但是测试和运行周期参与其中。(也就是跳过编译)</li>
<li><strong>test</strong>表示在一般的编译和运行时都不需要,只有在测试编译和运行阶段才用到。</li>
<li><strong>provided</strong>表示该依赖已经提供,旨在未提供时才被使用。</li>
<li><strong>system</strong>表示该依赖不会从maven仓库下载,而是从本地系统指定路径下寻找。</li>
<li><strong>import</strong>仅支持在<code><dependencyManagement></code>中的类型依赖项上使用。表示要在指定POM中用有效的依赖关系列表替换的依赖关系。</li>
</ul>
</li>
<li>
<p><strong><mvc:resource></strong></p>
<p>出现一个很奇怪的问题😓,为什么我的html文件调不了css文件呢?bootstrap的css文件可以访问,我自己写的common.css文件就不行?貌似不是,我在servlet容器中定义了<a href="mvc:default-servlet-handler">mvc:default-servlet-handler</a>了,而且bootstrap的css等文件也可以访问了,但是为何就那一个文件访问不了?图片也访问不了</p>
<p>所以我就只能在在Servlet容器中再设置<code><mvc:resource></code>这个静态资源直接映射了。这样的话,就需要全部设置我的静态资源了,但是这个<code><mvc:resource></code>有个好处,就是它可以设置在任何地方。任君设置。</p>
</li>
</ol>
]]></content>
<categories>
<category>SSM</category>
</categories>
<tags>
<tag>SSM</tag>
</tags>
</entry>
<entry>
<title>Java静态代理与动态代理</title>
<url>/2020/09/11/Java%E9%9D%99%E6%80%81%E4%BB%A3%E7%90%86%E4%B8%8E%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86/</url>
<content><![CDATA[<h2 id="动态代理是什么?">动态代理是什么?</h2>
<ul>
<li>先理解代理,静态代理,后面才能理解动态代理</li>
</ul>
<p>代理可以把代购🛍拿来相比,就是通过代购让你要买某些东西时,不用自己亲自去,避免很多步骤和不必要的麻烦。<a id="more"></a>代理就是这么回事,比如你要做某些事,但是完成它,过程比较繁琐又麻烦💫,这时候就可以通过代理,避过不必要的麻烦来获取它</p>
<p>代理需要具备的东西,如下图:</p>
<p><img src="/assets/img/%E4%BB%A3%E7%90%86%E5%92%8C%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86.png" alt="静态代理结构图"></p>
<p>代理类需要包含真实对象,同时需要实现接口,这个接口就是某些真实对象想要做的事,即方法,通过方法做想要做的事,这里所讲的就是<strong>静态代理</strong>的规则</p>
<p>但是<strong>静态代理</strong>有其弊端,因为如果你要做的事情多了,就需要不断实现接口和引入真实对象,这样的话,代理类就越来越膨胀,高藕合。不容易维护</p>
<p>而<strong>动态代理</strong>就是解决静态代理的弊端的,通过JDK的动态代理,它包含两个东西,一个是<strong>proxy</strong>,也就是代理类,只负责生成代理对象;一个是<strong>InvocationHandler</strong>,它的原型其实就是那个接口,它有一个<code>invoke()</code>方法,这是方法可以给真实对象添加功能,也就是业务增强(感觉这个方法可以自动执行,以完成业务增强功能);<code>invoke()</code>方法里面有个method参数,这是利用反射的原理,因为刚开始并不知道代理的是什么对象,所以用对象的方法来调用需要优化的方法,也就是<code>invoke()</code>方法。这里的<code>invoke()</code>方法其实还是不太懂😭😭</p>
]]></content>
<categories>
<category>Java</category>
</categories>
</entry>
<entry>
<title>Spring-AOP</title>
<url>/2020/11/18/Spring-AOP/</url>
<content><![CDATA[<h4 id="术语:">术语:</h4>
<p>通知(advice)、切点(pointcut)、连接点(joinpoint)、切面(aspect)</p>
<ul>
<li>
<p>通知:就是切面的工作,通知定义了切面是什么以及何时使用(应用于某个方法被调用之前?之后?之前和<a id="more"></a>之后都调用还是只有在方法抛出异常时调用)</p>
</li>
<li>
<p>连接点:应用可能有数以千记的时机应用通知。这些时机被称为连接点。连接点是在应用执行过程中能够插入切面的一个点。这个点可以是调用方法时、抛出异常时、甚至修改一个字段时。</p>
</li>
<li>
<p>切点:切点定义了切面在<strong>何处</strong>使用,切点的定义会匹配通知所要织入的一个或者多个连接点。一般用明确的类和方法名称,或者是利用正则表达式定义所匹配得类和方法名称来指定这些切点。</p>
</li>
<li>
<p>切面:切面是通知和切点得结合。通知和切点共同定义了切面得全部内容----它是什么,在何时和何处完成其功能。</p>
</li>
</ul>
<h4 id="Spring提供了四种类型的AOP支持">Spring提供了四种类型的AOP支持</h4>
<ul>
<li>基于代理的经典Spring AOP(已弃用)</li>
<li>纯POJO切面(声明式AOP)</li>
<li>@AspectJ注解驱动的切面(基于注解的AOP)</li>
<li>注入式AspectJ切面(适用于Spring 各版本,需要用到AspectJ来编写)</li>
</ul>
<blockquote>
<p>SpringAOP构建在动态代理基础之上,因此,Spring对AOP的支持局限于方法拦截</p>
</blockquote>
<blockquote>
<p>SpringAOP借助于AspectJ,使得它的AOP编写更加简单,更加方便,这里不是用使用AspectJ来写切面(AspectJ是Java语言的扩展,并不是纯Java语言),只是使用AspectJ来驱动而已。</p>
</blockquote>
<hr>
<h4 id="基于注解的AOP">基于注解的AOP</h4>
<ul>
<li><strong>AspectJ切面表达式</strong></li>
</ul>
<blockquote>
<p>在切点中定义</p>
</blockquote>
<p><img src="https://drek4537l1klr.cloudfront.net/walls5/Figures/04fig04.jpg" alt="img"></p>
<ul>
<li>
<p><strong>使用注解创建切面</strong></p>
<p><strong>使用注解来声明通知方法</strong></p>
</li>
</ul>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> concert;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.AfterReturning;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.AfterThrowing;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Aspect;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Before;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Aspect</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Audience</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Before("execution(** concert.Performance.perform(..))")</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">silenceCellPhones</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"Silencing cell phones"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Before("execution(** concert.Performance.perform(..))")</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">takeSeats</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"Taking seats"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@AfterReturning("execution(** concert.Performance.perform(..))")</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">applause</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"CLAP CLAP CLAP!!!"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@AfterThrowing("execution(** concert.Performance.perform(..))")</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">demandRefund</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"Demanding a refund"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li><strong>通过使用@Pointcut注解声明频繁使用的切点表达式</strong></li>
</ul>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> concert;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.AfterReturning;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.AfterThrowing;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Aspect;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Before;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Pointcut;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Aspect</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Audience</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Pointcut("execution(** concert.Performance.perform(..))")</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">performance</span><span class="params">()</span> </span>{}</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Before("performance()")</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">silenceCellPhones</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"Silencing cell phones"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Before("performance()")</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">takeSeats</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"Taking seats"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@AfterReturning("performance()")</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">applause</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"CLAP CLAP CLAP!!!"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="meta">@AfterThrowing("performance()")</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">demandRefund</span><span class="params">()</span> </span>{</span><br><span class="line"> System.out.println(<span class="string">"Demanding a refund"</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li><strong>将切面声明为Spring中的bean</strong></li>
</ul>
<blockquote>
<p>在Javaconfig中启用AspectJ注解的自动代理-----@EnableAspectJAutoProxy</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> concert;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Bean;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.ComponentScan;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.Configuration;</span><br><span class="line"><span class="keyword">import</span> org.springframework.context.annotation.EnableAspectJAutoProxy;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Configuration</span></span><br><span class="line"><span class="meta">@EnableAspectJAutoProxy</span> </span><br><span class="line"><span class="meta">@ComponentScan</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConcertConfig</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Bean</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> Audience <span class="title">audience</span><span class="params">()</span> </span>{ </span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> Audience();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li><strong>在xml中启用AspectJ注解</strong></li>
</ul>
<figure class="highlight"><table><tr><td class="code"><pre><span class="line"><?xml version=<span class="string">"1.0"</span> encoding=<span class="string">"UTF-8"</span>?></span><br><span class="line"><beans xmlns=<span class="string">"http://www.springframework.org/schema/beans"</span></span><br><span class="line"> xmlns:xsi=<span class="string">"http://www.w3.org/2001/XMLSchema-instance"</span></span><br><span class="line"> xmlns:context=<span class="string">"http://www.springframework.org/schema/context"</span></span><br><span class="line"> xmlns:aop=<span class="string">"http://www.springframework.org/schema/aop"</span> </span><br><span class="line"> xsi:schemaLocation=<span class="string">"http://www.springframework.org/schema/aop</span></span><br><span class="line"><span class="string"> http://www.springframework.org/schema/aop/spring-aop.xsd</span></span><br><span class="line"><span class="string"> http://www.springframework.org/schema/beans</span></span><br><span class="line"><span class="string"> http://www.springframework.org/schema/beans/spring-beans.xsd</span></span><br><span class="line"><span class="string"> http://www.springframework.org/schema/context</span></span><br><span class="line"><span class="string"> http://www.springframework.org/schema/context/spring-context.xsd"</span>></span><br><span class="line"></span><br><span class="line"> <context:component-scan base-<span class="keyword">package</span>=<span class="string">"concert"</span> /></span><br><span class="line"></span><br><span class="line"> <aop:aspectj-autoproxy /> </span><br><span class="line"></span><br><span class="line"> <bean <span class="class"><span class="keyword">class</span></span>=<span class="string">"concert.Audience"</span> /> </span><br><span class="line"></span><br><span class="line"></beans></span><br></pre></td></tr></table></figure>
<ul>
<li><strong>创建环绕通知</strong></li>
</ul>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> concert;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.ProceedingJoinPoint;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Around;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Aspect;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Pointcut;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Aspect</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Audience</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Pointcut("execution(** concert.Performance.perform(..))")</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">performance</span><span class="params">()</span> </span>{}</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Around("performance()")</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">watchPerformance</span><span class="params">(ProceedingJoinPoint jp)</span> </span>{</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> System.out.println(<span class="string">"Silencing cell phones"</span>);</span><br><span class="line"> System.out.println(<span class="string">"Taking seats"</span>);</span><br><span class="line"> jp.proceed();</span><br><span class="line"> System.out.println(<span class="string">"CLAP CLAP CLAP!!!"</span>);</span><br><span class="line"> } <span class="keyword">catch</span> (Throwable e) {</span><br><span class="line"> System.out.println(<span class="string">"Demanding a refund"</span>);</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>
<ul>
<li><strong>处理通知中的参数</strong></li>
</ul>
<blockquote>
<p>切点表达式导入参数</p>
</blockquote>
<p><img src="https://drek4537l1klr.cloudfront.net/walls5/Figures/04fig06_alt.jpg" alt="img"></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">package</span> soundsystem;</span><br><span class="line"><span class="keyword">import</span> java.util.HashMap;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Aspect;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Before;</span><br><span class="line"><span class="keyword">import</span> org.aspectj.lang.annotation.Pointcut;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Aspect</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">TrackCounter</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="keyword">private</span> Map<Integer, Integer> trackCounts =</span><br><span class="line"> <span class="keyword">new</span> HashMap<Integer, Integer>();</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Pointcut(</span></span><br><span class="line"><span class="meta"> "execution(* soundsystem.CompactDisc.playTrack(int)) " + </span></span><br><span class="line"><span class="meta"> "&& args(trackNumber)")</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">trackPlayed</span><span class="params">(<span class="keyword">int</span> trackNumber)</span> </span>{}</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Before("trackPlayed(trackNumber)")</span> </span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">countTrack</span><span class="params">(<span class="keyword">int</span> trackNumber)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> currentCount = getPlayCount(trackNumber);</span><br><span class="line"> trackCounts.put(trackNumber, currentCount + <span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getPlayCount</span><span class="params">(<span class="keyword">int</span> trackNumber)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> trackCounts.containsKey(trackNumber)</span><br><span class="line"> ? trackCounts.get(trackNumber) : <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<hr>
<h4 id="基于xml的AOP">基于xml的AOP</h4>
<ul>
<li><strong>创建切面,声明通知方法</strong></li>
</ul>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">aop:config</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">aop:aspect</span> <span class="attr">ref</span>=<span class="string">"audience"</span>></span> </span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">aop:before</span> </span></span><br><span class="line"><span class="tag"> <span class="attr">pointcut</span>=<span class="string">"execution(** concert.Performance.perform(..))"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">method</span>=<span class="string">"silenceCellPhones"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">aop:before</span> </span></span><br><span class="line"><span class="tag"> <span class="attr">pointcut</span>=<span class="string">"execution(** concert.Performance.perform(..))"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">method</span>=<span class="string">"takeSeats"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">aop:after-returning</span> </span></span><br><span class="line"><span class="tag"> <span class="attr">pointcut</span>=<span class="string">"execution(** concert.Performance.perform(..))"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">method</span>=<span class="string">"applause"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">aop:after-throwing</span> </span></span><br><span class="line"><span class="tag"> <span class="attr">pointcut</span>=<span class="string">"execution(** concert.Performance.perform(..))"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">method</span>=<span class="string">"demandRefund"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"></<span class="name">aop:aspect</span>></span></span><br><span class="line"><span class="tag"></<span class="name">aop:config</span>></span></span><br></pre></td></tr></table></figure>
<ul>
<li><strong>声明频繁使用的切点表达式</strong></li>
</ul>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">aop:config</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">aop:aspect</span> <span class="attr">ref</span>=<span class="string">"audience"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">aop:pointcut</span> </span></span><br><span class="line"><span class="tag"> <span class="attr">id</span>=<span class="string">"performance"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">expression</span>=<span class="string">"execution(** concert.Performance.perform(..))"</span> /></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">aop:before</span> </span></span><br><span class="line"><span class="tag"> <span class="attr">pointcut-ref</span>=<span class="string">"performance"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">method</span>=<span class="string">"silenceCellPhones"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">aop:before</span> </span></span><br><span class="line"><span class="tag"> <span class="attr">pointcut-ref</span>=<span class="string">"performance"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">method</span>=<span class="string">"takeSeats"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">aop:after-returning</span> </span></span><br><span class="line"><span class="tag"> <span class="attr">pointcut-ref</span>=<span class="string">"performance"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">method</span>=<span class="string">"applause"</span>/></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">aop:after-throwing</span> </span></span><br><span class="line"><span class="tag"> <span class="attr">pointcut-ref</span>=<span class="string">"performance"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">method</span>=<span class="string">"demandRefund"</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">aop:aspect</span>></span></span><br><span class="line"><span class="tag"></<span class="name">aop:config</span>></span></span><br></pre></td></tr></table></figure>
<ul>
<li><strong>声明环绕通知</strong></li>
</ul>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">aop:config</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">aop:aspect</span> <span class="attr">ref</span>=<span class="string">"audience"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">aop:pointcut</span></span></span><br><span class="line"><span class="tag"> <span class="attr">id</span>=<span class="string">"performance"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">expression</span>=<span class="string">"execution(** concert.Performance.perform(..))"</span> /></span></span><br><span class="line"></span><br><span class="line"> <span class="tag"><<span class="name">aop:around</span> </span></span><br><span class="line"><span class="tag"> <span class="attr">pointcut-ref</span>=<span class="string">"performance"</span></span></span><br><span class="line"><span class="tag"> <span class="attr">method</span>=<span class="string">"watchPerformance"</span>/></span></span><br><span class="line"> <span class="tag"></<span class="name">aop:aspect</span>></span></span><br><span class="line"><span class="tag"></<span class="name">aop:config</span>></span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>引入参数和引入方法等等比较高级的切面,咱先不说了,以后有机会再说吧</p>
</blockquote>
]]></content>
<tags>
<tag>Java</tag>
</tags>
</entry>
<entry>
<title>Spring与JDBC</title>
<url>/2020/11/18/Spring%E4%B8%8EJDBC/</url>
<content><![CDATA[<p>JDBC的执行流程:</p>
<p>首先你得先定义一条squary语句,然后才能够开始后面的语句</p>
<ol>
<li>引入datasource,通过datasource获取一个连接</li>
<li>通过这个连接,再获取一个事务(为何要经过事务<a id="more"></a>,我想事务的四个性质已经说的很明显了)</li>
<li>然后在事务中放入相关的squary语句,然后在事务中再设置参数绑定</li>
<li>执行事务</li>
<li>在此过程中,需要捕捉两次异常,一次在插入记录出错时捕捉它,一次在需要关闭语句和连接时捕捉它。</li>
</ol>
<p>相关代码如下:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> String SQL_INSERT_SPITTER =</span><br><span class="line"> <span class="string">"insert into spitter (username, password, fullname) values (?, ?, ?)"</span>;</span><br><span class="line"><span class="keyword">private</span> DataSource dataSource;</span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addSpitter</span><span class="params">(Spitter spitter)</span> </span>{</span><br><span class="line"> Connection conn = <span class="keyword">null</span>;</span><br><span class="line"> PreparedStatement stmt = <span class="keyword">null</span>;</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> conn = dataSource.getConnection(); </span><br><span class="line"> stmt = conn.prepareStatement(SQL_INSERT_SPITTER); </span><br><span class="line"> stmt.setString(<span class="number">1</span>, spitter.getUsername()); </span><br><span class="line"> stmt.setString(<span class="number">2</span>, spitter.getPassword());</span><br><span class="line"> stmt.setString(<span class="number">3</span>, spitter.getFullName());</span><br><span class="line"> stmt.execute(); </span><br><span class="line"> } <span class="keyword">catch</span> (SQLException e) {</span><br><span class="line"> <span class="comment">// do something...not sure what, though </span></span><br><span class="line"> } <span class="keyword">finally</span> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="keyword">if</span> (stmt != <span class="keyword">null</span>) { </span><br><span class="line"> stmt.close();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (conn != <span class="keyword">null</span>) {</span><br><span class="line"> conn.close();</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">catch</span> (SQLException e) {</span><br><span class="line"> <span class="comment">// I'm even less sure about what to do here</span></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>
<blockquote>
<p>但是JDBC有个缺点,就是它只能捕捉到SQLException异常,就是没办法分类,也就是说,只要是数据库方面出问题,就直接抛出SQLException异常,而不会分析是连接出错,还是语法出错等等等,这样你就无法知道到底是哪里出问题</p>
<p>但是我们现在可以使用Spring的数据访问异常,他就能够把异常分门别类,前提是需要使用Spring所支持的数据访问模板</p>
</blockquote>
<p>由此催生出了JDBC模板</p>
<table>
<thead>
<tr>
<th>模板类(org.springframework.*)</th>
<th>用 途</th>
</tr>
</thead>
<tbody>
<tr>
<td>jca.cci.core.CciTemplate</td>
<td>JCA CCI连接</td>
</tr>
<tr>
<td>jdbc.core.JdbcTemplate</td>
<td>JDBC连接</td>
</tr>
<tr>
<td>jdbc.core.namedparam.NamedParameterJdbcTemplate</td>
<td>支持命名参数的JDBC连接</td>
</tr>
<tr>
<td>jdbc.core.simple.SimpleJdbcTemplate</td>
<td>通过Java 5简化后的JDBC连接(Spring 3.1中已经废弃)</td>
</tr>
<tr>
<td>orm.hibernate3.HibernateTemplate</td>
<td>Hibernate 3.x以上的Session</td>
</tr>
<tr>
<td>orm.ibatis.SqlMapClientTemplate</td>
<td>iBATIS SqlMap客户端</td>
</tr>
<tr>
<td>orm.jdo.JdoTemplate</td>
<td>Java数据对象(Java Data Object)实现</td>
</tr>
<tr>
<td>orm.jpa.JpaTemplate</td>
<td>Java持久化API的实体管理器</td>
</tr>
</tbody>
</table>
<blockquote>
<p>Spring 支持的模板</p>
</blockquote>
<p>Spring的JDBC框架承担了资源管理和异常处理的工作,从而简化了JDBC代码,让我们只需编写从数据库读写数据的必需代码。</p>
<p>只有在你需要使用命名参数的时候,才需要使用<code>NamedParameterJdbcTemplate</code> 。,对于大多数的JDBC任务来说,<code>JdbcTemplate</code> 就是最好的可选方案</p>
<p>为了让<code>JdbcTemplate</code> 正常工作,只需要为其设置<code>DataSource</code> 就可以了,这使得在Spring中配置<code>JdbcTemplate</code> 非常容易</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Bean</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> JdbcTemplate <span class="title">jdbcTemplate</span><span class="params">(DataSource dataSource)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> JdbcTemplate(dataSource);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>在这里, DataSource是通过构造器参数注入进来的。这里所引用的dataSourcebean可以是javax.sql.DataSource的任意实现</p>
<p>现在,我们可以将jdbcTemplate装配到Repository中并使用它来访问数据库。例如,SpitterRepository使用了JdbcTemplate :</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Repository</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">JdbcSpitterRepository</span> <span class="keyword">implements</span> <span class="title">SpitterRepository</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> JdbcOperations jdbcOperations;</span><br><span class="line"> <span class="meta">@Inject</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="title">JdbcSpitterRepository</span><span class="params">(JdbcOperations jdbcOperations)</span> </span>{</span><br><span class="line"> <span class="keyword">this</span>.jdbcOperations = jdbcOperations;</span><br><span class="line"> }</span><br><span class="line">...</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>JdbcSpitterRepository类上使用了@Repository注解,这表明它将会在组件扫描的时候自动创建。它的构造器上使用了@Inject注解,因此在创建的时候,会自动获得一个JdbcOperations 对象。 JdbcOperations是一个接口,定义了JdbcTemplate所实现的操作。通过注入JdbcOperations,而不是具体的JdbcTemplate,能够保证JdbcSpitterRepository 通过 JdbcOperations接口达到与JdbcTemplate保持松耦合。</p>
<p>作为另外一种组件扫描和自动装配的方案,我们可以将JdbcSpitterRepository显式声明为Spring中的bean,如下所示:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Bean</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> SpitterRepository <span class="title">spitterRepository</span><span class="params">(JdbcTemplate jdbcTemplate)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> JdbcSpitterRepository(jdbcTemplate);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>在Repository中具备可用的JdbcTemplate后,我们可以极大地简化addSpitter()方法。基于JdbcTemplate 的 addSpitter()方法如下:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addSpitter</span><span class="params">(Spitter spitter)</span> </span>{</span><br><span class="line"> jdbcOperations.update(INSERT_SPITTER, </span><br><span class="line"></span><br><span class="line"> spitter.getUsername(),</span><br><span class="line"> spitter.getPassword(),</span><br><span class="line"> spitter.getFullName(),</span><br><span class="line"> spitter.getEmail(),</span><br><span class="line"> spitter.isUpdateByEmail());</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="使用JdbcTemplate来读取数据">使用JdbcTemplate来读取数据</h4>
<p>JdbcTemplate也简化了数据的读取操作。程序清单10.8展现了新版本的findOne()方法,它使用了JdbcTemplate的回调,实现根据ID查询Spitter,并将结果集映射为Spitter 对象。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> Spitter <span class="title">findOne</span><span class="params">(<span class="keyword">long</span> id)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> jdbcOperations.queryForObject( </span><br><span class="line"> SELECT_SPITTER_BY_ID, <span class="keyword">new</span> SpitterRowMapper(),</span><br><span class="line"> 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"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="class"><span class="keyword">class</span> <span class="title">SpitterRowMapper</span></span></span><br><span class="line"><span class="class"> <span class="keyword">implements</span> <span class="title">RowMapper</span><<span class="title">Spitter</span>> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> Spitter <span class="title">mapRow</span><span class="params">(ResultSet rs, <span class="keyword">int</span> rowNum)</span></span></span><br><span class="line"><span class="function"> <span class="keyword">throws</span> SQLException </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> Spitter( </span><br><span class="line"> rs.getLong(<span class="string">"id"</span>),</span><br><span class="line"> rs.getString(<span class="string">"username"</span>),</span><br><span class="line"> rs.getString(<span class="string">"password"</span>),</span><br><span class="line"> rs.getString(<span class="string">"fullName"</span>),</span><br><span class="line"> rs.getString(<span class="string">"email"</span>),</span><br><span class="line"> rs.getBoolean(<span class="string">"updateByEmail"</span>));</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>在这个 findOne()方法中使用了JdbcTemplate 的 queryForObject()方法来从数据库查询Spitter 。 queryForObject()方法有三个参数:</p>
<ul>
<li>
<p>String对象,包含了要从数据库中查找数据的SQL;</p>
</li>
<li>
<p>RowMapper对象,用来从ResultSet中提取数据并构建域对象(本例中为Spitter );</p>
</li>
<li>
<p>可变参数列表,列出了要绑定到查询上的索引参数值。</p>
</li>
</ul>
<p>真正奇妙的事情发生在SpitterRowMapper对象中,它实现了RowMapper接口。对于查询返回的每一行数据,JdbcTemplate 将会调用 RowMapper 的mapRow()方法,并传入一个ResultSet和包含行号的整数。在SpitterRowMapper 的 mapRow()方法中,我们创建了Spitter 对象并将 ResultSet中的值填充进去。</p>
<p>就像 addSpitter() 那样, findOne()方法也不用写JDBC模板代码。不同于传统的JDBC,这里没有资源管理或者异常处理代码。使用JdbcTemplate的方法只需关注于如何从数据库中获取Spitter对象即可。</p>
<blockquote>
<p>还可以在JdbcTemplate中使用Java 8的Lambda表达式或者JAVA 8 的方法引用,但是我不懂Lambda表达式也不懂方法引用😂</p>
</blockquote>
<h4 id="使用命名参数">使用命名参数</h4>
<p>上面的代码中,addSpitter()方法使用了索引参数。这意味着我们需要留意查询中参数的顺序,在将值传递给update()方法的时候要保持正确的顺序。如果在修改SQL时更改了参数的顺序,那我们还需要修改参数值的顺序。</p>
<p>除了这种方法之外,我们还可以使用命名参数。命名参数可以赋予SQL中的每个参数一个明确的名字,在绑定值到查询语句的时候就通过该名字来引用参数。</p>
<p>NamedParameterJdbcTemplate是一个特殊的JDBC模板类,它支持使用命名参数。在Spring中,NamedParameterJdbcTemplate的声明方式与常规的JdbcTemplate几乎完全相同:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Bean</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> NamedParameterJdbcTemplate <span class="title">jdbcTemplate</span><span class="params">(DataSource dataSource)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">new</span> NamedParameterJdbcTemplate(dataSource);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>在这里,我们将NamedParameterJdbcOperations ( NamedParameterJdbcTemplate所实现的接口)注入到Repository中,用它来替代JdbcOperations 。现在的 addSpitter()方法如下所示:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> String INSERT_SPITTER =</span><br><span class="line"> <span class="string">"insert into Spitter "</span> +</span><br><span class="line"> <span class="string">" (username, password, fullname, email, updateByEmail) "</span> +</span><br><span class="line"> <span class="string">"values "</span> +</span><br><span class="line"> <span class="string">" (:username, :password, :fullname, :email, :updateByEmail)"</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addSpitter</span><span class="params">(Spitter spitter)</span> </span>{</span><br><span class="line"> Map<String, Object> paramMap = <span class="keyword">new</span> HashMap<String, Object>();</span><br><span class="line"> paramMap.put(<span class="string">"username"</span>, spitter.getUsername()); </span><br><span class="line"> paramMap.put(<span class="string">"password"</span>, spitter.getPassword());</span><br><span class="line"> paramMap.put(<span class="string">"fullname"</span>, spitter.getFullName());</span><br><span class="line"> paramMap.put(<span class="string">"email"</span>, spitter.getEmail());</span><br><span class="line"> paramMap.put(<span class="string">"updateByEmail"</span>, spitter.isUpdateByEmail());</span><br><span class="line"></span><br><span class="line"> jdbcOperations.update(INSERT_SPITTER, paramMap); </span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<tags>
<tag>Java</tag>
</tags>
</entry>
<entry>
<title>Spring 注解分析</title>
<url>/2020/09/04/Spring-%E6%B3%A8%E8%A7%A3%E5%88%86%E6%9E%90/</url>
<content><![CDATA[<h3 id="Autowired">@Autowired</h3>
<p>🍃<code>Spring</code>可以实现控制反转,就是实例化对象,但是如果对象里面有属性呢?那就用注解<code>@autowired </code>直接注入属性(实例化的对象),这样就实现了解耦🙉,<code>Controller、Service、Dao</code>等分层就是基于此。</p>
<ul>
<li><code>bean</code>作用域<code>singleton</code>和<code>prototype</code>的区别</li>
</ul>
<p><code>singleton</code>:容器在初始化时,就会创建对象;单例也支持延迟加载(就是只有在请求时再生成);</p>
<a id="more"></a>
<p><code>prototype</code>:容器在初始化时,不创建对象,只是在每次使用时(每次容器获取对象时)再创建对象;并且每次获取对象都会创建一个新的对象;</p>
<blockquote>
<p><code>@Resource</code>—它其实跟<code>@Autowired</code>效果一样,只不过它是根据<code>name</code>来注入实例化对象的,而Autowired则根据<code>id</code></p>
</blockquote>
<hr>
<h3 id="ResponseBody">@ResponseBody</h3>
<p><code>@responseBody</code>注解的作用是将<code>controller</code>中的方法返回的数据,通过适当的转换器转换为指定的格式之后,写入到<code>response</code>对象的<code>body</code>区,通常用来返回<code>JSON</code>数据或者是<code>XML</code>数据😵</p>
<p>需要注意的是,在使用此注解之后不会再走<strong>视图处理器</strong>这个流程,而是直接将数据写入到<strong>输入流</strong>中😁,也就是说,只返回数据而不是页面,他的效果等同于通过<code>response</code>对象输出指定格式的数据。</p>
<hr>
<h3 id="测试三件套👺">测试三件套👺</h3>
<h4 id="Test、-ContextConfiguration、-Runwith"><em>@Test、@ContextConfiguration、@Runwith</em></h4>
<p>我想使用<code>@Test</code>测试来完成注解形式的<code>SpringIoC</code>,但是测试无法实现,使用<code>Java Application</code>就可以实现!原来测试初始化IoC容器可以用<code>@ContextConfiguration</code>这个注解,不管是<code>XML</code>形式还是注解形式的IoC容器。</p>
<p><code>@ContextConfiguration</code>和<code>@Runwith</code>二者一般不分开,一个是用于导入测试使用的测试库函数,一个用于加载配置文件,也就是加载配置<code>XML</code>文件或者<code>Java文件</code>(使用<code>@Configuration</code>标注配置<code>java</code>类文件),用以导入某些<code>Spring</code>容器的<code>bean</code>对象。</p>
<blockquote>
<p>详情请看:<strong>/demo2/src/main/java/cn/lj/test/addusertest.java</strong>🐾</p>
</blockquote>
<p>如果需要加载spring容器,可以在<code>@ContextConfiguration</code>中加载<code>Spring</code>容器后,用于实例化<code>Spring容器</code>对象</p>
<blockquote>
<p>示例:/wx/src/main/java/cn.lj.wx.utils.CreateUtils方法🐾</p>
</blockquote>
<hr>
<h3 id="Component">@Component</h3>
<p>新建一个<code>Utils</code>类🎸,有个属性<code>token</code>和两个方法,在其他类通过<code>@Autowired</code>注入这个类对象时,一直报没有这个bean对象,很奇怪,最后把属性token去掉就可以了。原来在引入<code>bean</code>对象时,需要配置好他的属性,所以只要属性设置好<code>Getter/Setter</code>方法就可以使用<code>Autowired</code>自动装配了</p>
<p>最好还是不要设置属性吧💅,或者直接使用<code>@Autowired</code>或<code>@Resource</code>注入属性(跟<code>Controller</code>、<code>Service</code>一样),就可以直接把这个类设为<code>component</code>类,让其他类可以调用。</p>
<hr>
<h3 id="Data、-Getter">@Data、@Getter</h3>
<p>省略对象get/set方法的编写,省略无参构造函数的编写,怎么做到呢?那当然要使用<span class="ljspan ljspan-blue"><a href="https://objectcomputing.com/resources/publications/sett/january-2010-reducing-boilerplate-code-with-project-lombok">lombok</a></span></p>
<h4 id="配置">配置</h4>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="comment"><!-- 注解Get/Set等方法 --></span></span><br><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.projectlombok<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>lombok<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.18.8<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">scope</span>></span>provided<span class="tag"></<span class="name">scope</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure>
<h4 id="下载安装lombok的插件">下载安装<code>lombok</code>的插件</h4>
<p>其实就是下载<span class="ljspan ljspan-blue"><a href="https://projectlombok.org/all-versions">lombok.jar</a></span>后,打开它,弹出安装界面,然后在打开的界面中指定你的eclipse安装的根目录后安装/更新,最后安装完成之后,请确认eclipse安装路径下是否多了一个lombok.jar包,并且其配置文件eclipse.ini中是否 添加了如下内容:-javaagent:path\to\lombok.jar</p>
<p>具体操作步骤可<a href="https://www.cnblogs.com/boonya/p/10691466.html">参考博主</a>的安装步骤</p>
]]></content>
<categories>
<category>Java</category>
</categories>
<tags>
<tag>SSM</tag>
<tag>annotation</tag>
</tags>
</entry>
<entry>
<title>Tomcat的下载和配置</title>
<url>/2020/09/08/Tomcat%E7%9A%84%E4%B8%8B%E8%BD%BD%E5%92%8C%E9%85%8D%E7%BD%AE/</url>
<content><![CDATA[<h2 id="前言">#前言</h2>
<p>在Linux上安装tomcat,其实跟window一样,配置JDK、配置环境变量等等,只不过配置路径和文件名不同而已😘</p>
<a id="more"></a>
<hr>
<h3 id="下载配置jdk">下载配置jdk</h3>
<p>很难,试过用apt-get/apt使用ppa源安装,失败;使用系统推荐的openjdk安装也失败;最后只能采用下载bin来解压安装,才能成功</p>
<div class="note default">
<h4 id="Note">Note:</h4><p>在oracle官网下载jdk时,可以直接搜索jdk archive来下载,不过需要登陆oracle账号!</p>
</div>
<blockquote>
<p>安装好jdk需要配置好环境变量</p>
</blockquote>
<p>如果只想配置用户变量,就在文件~/.bashrc中</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="built_in">export</span> JAVA_HOME=/path/to/java</span><br><span class="line"></span><br><span class="line"><span class="built_in">export</span> JRE_HOME=<span class="variable">${JAVA_HOME}</span>/jre</span><br><span class="line"></span><br><span class="line"><span class="built_in">export</span> CLASSPATH=.:<span class="variable">${JAVA_HOME}</span>/lib:<span class="variable">${JRE_HOME}</span>/lib</span><br><span class="line"></span><br><span class="line"><span class="built_in">export</span> PATH=.:<span class="variable">${JAVA_HOME}</span>/bin:<span class="variable">$PATH</span></span><br></pre></td></tr></table></figure>
<p>如果想直接设置为环境变量那便把上面的设置添加到/etc/profile文件中</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="comment">#测试java是否安装配置完成</span></span><br><span class="line"><span class="variable">$java</span> -version</span><br><span class="line">openjdk version <span class="string">"1.8.0_252"</span></span><br><span class="line">OpenJDK Runtime Environment (build 1.8.0_252-8u252-b09-1~16.04-b09)</span><br><span class="line">OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)</span><br><span class="line"><span class="comment">#有上面的文段证明安装完成</span></span><br></pre></td></tr></table></figure>
<hr>
<h3 id="下载配置tomcat">下载配置tomcat</h3>
<p>配置教程在<a href="https://blog.csdn.net/jenyzhang/article/details/70159769">这里</a></p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line">tar -xzvf apache-tomcat.xxx.tar.gz</span><br><span class="line"><span class="comment">#配置环境变量</span></span><br><span class="line">vim ~/.bashrc</span><br><span class="line"><span class="comment">#tomcat</span></span><br><span class="line"><span class="built_in">export</span> TOMCAT_HOME=/path/to/tomcat </span><br><span class="line"></span><br><span class="line"><span class="comment">#启动tomcat</span></span><br><span class="line"><span class="built_in">cd</span> /path/to/tomcat</span><br><span class="line">./bin/startup.sh</span><br><span class="line"></span><br><span class="line"><span class="comment">#测试tomcat配置成功与否,用浏览器登录下看看</span></span><br><span class="line">http://localhost:8080</span><br></pre></td></tr></table></figure>
<p>这里配置安装的tomcat还不是很完整,比如说,没有服务,每次开机都去tomcat文件夹去找,很麻烦,而且有些软件需要使用到systemctl来启动tomcat服务,比如OpenElis</p>
<p>解决办法:</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cd</span> /path/to/tomcat目录</span><br><span class="line"></span><br><span class="line"><span class="comment">#修改startup.sh</span></span><br><span class="line"></span><br><span class="line">vim ./startup.sh</span><br><span class="line"><span class="comment">#添加如下</span></span><br><span class="line"><span class="comment">#set java environment</span></span><br><span class="line"><span class="built_in">export</span> JAVA_HOME=/path/to/java</span><br><span class="line"></span><br><span class="line"><span class="built_in">export</span> JRE_HOME=<span class="variable">${JAVA_HOME}</span>/jre</span><br><span class="line"></span><br><span class="line"><span class="built_in">export</span> CLASSPATH=.:<span class="variable">${JAVA_HOME}</span>/lib:<span class="variable">${JRE_HOME}</span>/lib</span><br><span class="line"><span class="built_in">export</span> PATH=.:<span class="variable">${JAVA_HOME}</span>/bin:<span class="variable">$PATH</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#tomcat</span></span><br><span class="line"><span class="built_in">export</span> TOMCAT_HOME=/path/to/tomcat</span><br><span class="line"><span class="built_in">exec</span> <span class="string">"<span class="variable">$PRGDIR</span>"</span>/<span class="string">"<span class="variable">$EXECUTABLE</span>"</span> start <span class="string">"<span class="variable">$@</span>"</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">#注册tomcat服务</span></span><br><span class="line">sudo cp /path/to/tomcat/bin/catalina.sh /etc/init.d/tomcat</span><br><span class="line"><span class="comment">#修改catalina.sh</span></span><br><span class="line">vim catalina.sh</span><br><span class="line"><span class="comment">#添加如下</span></span><br><span class="line">JAVA_HOME=/usr/lib/jvm/java目录</span><br><span class="line">CATALINA_HOME=/path/to/tomcat</span><br><span class="line"></span><br><span class="line">在<span class="comment">#!/bash/sh下方直接添加</span></span><br><span class="line"></span><br><span class="line"><span class="comment">### BEGIN INIT INFO</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Provides: tomcat</span></span><br><span class="line"><span class="comment"># Required-Start: $remote_fs $network</span></span><br><span class="line"><span class="comment"># Required-Stop: $remote_fs $network</span></span><br><span class="line"><span class="comment"># Default-Start: 2 3 4 5</span></span><br><span class="line"><span class="comment"># Default-Stop: 0 1 6</span></span><br><span class="line"><span class="comment"># Short-Description: The tomcat Java Application Server</span></span><br><span class="line"></span><br><span class="line"><span class="comment">### END INIT INFO</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#重新注册tomcat服务</span></span><br><span class="line">sudo update-rc.d tomcat defaults</span><br><span class="line"></span><br><span class="line"><span class="comment">#现在就可以使用tomcat服务了</span></span><br><span class="line">sudo systemctl status tomcat </span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>linux</category>
</categories>
<tags>
<tag>tomcat</tag>
</tags>
</entry>
<entry>
<title>Ubuntu18.04设置开机自启动</title>
<url>/2020/09/08/Ubuntu18-04%E8%AE%BE%E7%BD%AE%E5%BC%80%E6%9C%BA%E8%87%AA%E5%90%AF%E5%8A%A8/</url>
<content><![CDATA[<div class="note info">
<h4 id="Note1">Note1:</h4><p>由于新版ubuntu不再使用<strong>initd</strong>管理系统,而改用<strong>systemd</strong>;</p><p>故用systemctl命令来替换了<strong>service</strong>和<strong>chkconfig</strong>的功能</p><p>系统开机启动,systemd默认读取<code>/etc/systemd/system</code>下的配置/该目录下的文件会链接<code>lib/systemd/system/</code>下的文件</p>
</div>
<a id="more"></a>
<div class="note info">
<h4 id="Note2">Note2:</h4><p>sh的脚本,脚本开头的#!+shell,这里的shell一般有sh和bash,而sh其实是‘bash --posix’的变体,二者是一样的,这么看来,sh其实是bash的一种标准😳</p>
</div>
<h2 id="开始配置">开始配置</h2>
<blockquote>
<p>我的自定义启动文件是rc-local.service,直接修改它</p>
</blockquote>
<h4 id="配置rc-local-service">配置rc-local.service</h4>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash"> SPDX-License-Identifier: LGPL-2.1+</span></span><br><span class="line"><span class="meta">#</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> This file is part of systemd.</span></span><br><span class="line"><span class="meta">#</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> systemd is free software; you can redistribute it and/or modify it</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> under the terms of the GNU Lesser General Public License as published by</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> the Free Software Foundation; either version 2.1 of the License, or</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> (at your option) any later version.</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> This unit gets pulled automatically into multi-user.target by</span></span><br><span class="line"><span class="meta">#</span><span class="bash"> systemd-rc-local-generator <span class="keyword">if</span> /etc/rc.local is executable.</span></span><br><span class="line">[Unit]</span><br><span class="line">Description=/etc/rc.local Compatibility</span><br><span class="line">Documentation=man:systemd-rc-local-generator(8)</span><br><span class="line">ConditionFileIsExecutable=/etc/rc.local</span><br><span class="line">After=network.target</span><br><span class="line"></span><br><span class="line">[Service]</span><br><span class="line">Type=forking</span><br><span class="line">ExecStart=/etc/rc.local start</span><br><span class="line">TimeoutSec=0</span><br><span class="line">RemainAfterExit=yes</span><br><span class="line">GuessMainPID=no</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash">这里是需要添加的部分</span></span><br><span class="line">[Install]</span><br><span class="line">WantedBy=multi-user.target</span><br><span class="line">Alias=rc-local.service</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>一般正常的启动文件主要分成三部分💦</p>
<p><em>[Unit]</em> 段: <span class="label info">启动顺序与依赖关系</span></p>
<p><em>[Service]</em> 段: <span class="label warning">启动行为,如何启动,启动类型</span></p>
<p><em>[Install]</em> 段: 定义如何安装这个配置文件,即<span class="label success">怎样做到开机启动</span></p>
<h4 id="配置rc-local">配置rc.local</h4>
<p>Ubuntu18.04默认没有<code>/etc/rc.local</code>这个文件,需要自己创建</p>
<p>如下👇:</p>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="comment"># !/bin/sh -e</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># rc.local</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># This script is executed at the end of each multiuser runlevel.</span></span><br><span class="line"><span class="comment"># Make sure that the script will "exit 0" on success or any other</span></span><br><span class="line"><span class="comment"># value on error.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># In order to enable or disable this script just change the execution</span></span><br><span class="line"><span class="comment"># bits.</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># By default this script does nothing.</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span> <span class="string">"this just a test"</span> > /home/luoj/testdir/text.txt</span><br><span class="line"></span><br><span class="line"><span class="built_in">exit</span> 0</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="设置开机自启动">设置开机自启动</h2>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="comment">#添加可执行权限</span></span><br><span class="line">sudo chmod +x /etc/rc.local</span><br><span class="line"><span class="comment">#添加rc-local.service软连接到/etc/systemd/system</span></span><br><span class="line">sudo systemctl <span class="built_in">enable</span> rc-local</span><br><span class="line"><span class="comment">#启动这个服务</span></span><br><span class="line">sudo systemctl start rc-local.service</span><br><span class="line"><span class="comment">#查看这个服务</span></span><br><span class="line">sudo systemctl status rc-local.service</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>linux</category>
</categories>
</entry>
<entry>
<title>apt-get用法</title>
<url>/2020/09/08/apt-get%E7%94%A8%E6%B3%95/</url>
<content><![CDATA[<h2 id="前言">#前言</h2>
<p>apt-get是ubuntu等系统独有的一个软件包安装工具,apt其实也是一样的,只不过,我习惯用apt-get。不适用于centos哦!💁</p>
<a id="more"></a>
<h2 id="命令:">命令:</h2>
<blockquote>
<p>下列是apt-get的命令选项</p>
</blockquote>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line">update - 取回更新的软件包列表信息 **<span class="comment">#只检查更新软件包,不更新软件**</span></span><br><span class="line"></span><br><span class="line">upgrade - 进行一次升级 **<span class="comment">#真正的更新软件**</span></span><br><span class="line"></span><br><span class="line">install - 安装新的软件包(注:软件包名称是 libc6 而非 libc6.deb)</span><br><span class="line"></span><br><span class="line">remove - 卸载软件包</span><br><span class="line"></span><br><span class="line">autoremove - 卸载所有自动安装且不再使用的软件包</span><br><span class="line"></span><br><span class="line">purge - 卸载并清除软件包的配置</span><br><span class="line"></span><br><span class="line"><span class="built_in">source</span> - 下载源码包文件</span><br><span class="line"></span><br><span class="line">build-dep - 为源码包配置所需的编译依赖关系</span><br><span class="line"></span><br><span class="line">dist-upgrade - 发布版升级,见 apt-get(8)</span><br><span class="line"></span><br><span class="line">dselect-upgrade - 根据 dselect 的选择来进行升级</span><br><span class="line"></span><br><span class="line">clean - 删除所有已下载的包文件</span><br><span class="line"></span><br><span class="line">autoclean - 删除已下载的旧包文件</span><br><span class="line"></span><br><span class="line">check - 核对以确认系统的依赖关系的完整性</span><br><span class="line"></span><br><span class="line">changelog - 下载指定软件包,并显示其changelog</span><br><span class="line"></span><br><span class="line">download - 下载指定的二进制包到当前目录</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="针对apt-get安装软件失败,网速慢的问题">针对apt-get安装软件失败,网速慢的问题</h2>
<blockquote>
<p>可通过更换apt-get镜像源来解决这个问题</p>
</blockquote>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="comment">#备份原始镜像源</span></span><br><span class="line"></span><br><span class="line">cp /etc/apt/source.list /etc/apt/source.list.old</span><br><span class="line"></span><br><span class="line"><span class="comment">#更换镜像源地址</span></span><br><span class="line"></span><br><span class="line">vim /etc/apt/source.list</span><br><span class="line"></span><br><span class="line">:%d <span class="comment">#清空内容</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#复制[清华镜像源](https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/)到/etc/apt/source.list文件中</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#更新一下配置</span></span><br><span class="line"></span><br><span class="line">sudo apt-get update</span><br></pre></td></tr></table></figure>
<hr>
<h2 id="apt-get安装程序包出现问题(卸载系统自带python3后出现的问题)">apt-get安装程序包出现问题(卸载系统自带python3后出现的问题)</h2>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="comment">#以下为错误内容,可能有多个或至少一个</span></span><br><span class="line">xxx.postinst: xxx: not found</span><br><span class="line">dpkg: 处理软件包 xxx (--configure)时出错:</span><br><span class="line"> 子进程 已安装 post-installation 脚本 返回错误状态 127</span><br><span class="line">在处理时有错误发生:</span><br><span class="line"> xxx</span><br><span class="line">E:Sub-process /usr/bin/dpkg returned an error code (1)</span><br><span class="line"></span><br><span class="line"><span class="comment">#解决办法:</span></span><br><span class="line">sudo mv /var/lib/dpkg/info /var/lib/dpkg/info_old</span><br><span class="line"></span><br><span class="line">sudo mkdir /var/lib/dpkg/info</span><br><span class="line"></span><br><span class="line"><span class="comment">#更新软件包并修复软件的依赖包</span></span><br><span class="line">sudo apt-get update && sudo apt-get -f install</span><br><span class="line"></span><br><span class="line">sudo mv /var/lib/dpkg/info/* /var/lib/dpkg/info_old</span><br><span class="line"></span><br><span class="line">sudo rm -rf /var/lib/dpkg/info </span><br><span class="line"></span><br><span class="line">sudo mv /var/lib/dpkg/info_old /var/lib/dpkg/info</span><br><span class="line"></span><br><span class="line"><span class="comment">#重新进入shell</span></span><br></pre></td></tr></table></figure>
<blockquote>
<p>最好不要卸载系统自带的python,最多卸载你之前使用apt-get安装的软件,不然可能会出现意想不到的问题😰</p>
</blockquote>
<h2 id="卸载软件-程序">卸载软件/程序</h2>
<blockquote>
<p>我觉得也可以用来删除其他通过apt-get安装的软件!</p>
</blockquote>
<h4 id="示例:完全卸载mariadb">示例:完全卸载mariadb</h4>
<figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="comment">#首先卸载mariadb并删除相关配置文件(datadir目录)</span></span><br><span class="line">sudo apt-get purge mariadb*</span><br><span class="line"></span><br><span class="line"><span class="comment">#删除没用的相关依赖包</span></span><br><span class="line">sudo apt-get automove </span><br><span class="line"></span><br><span class="line"><span class="comment">#验证mariadb服务是否还在</span></span><br><span class="line">sudo service mysql status</span><br><span class="line"></span><br><span class="line"><span class="comment">#如果还是不能够删除!!!</span></span><br><span class="line"><span class="comment">#就直接到apt软件包列表去删除</span></span><br><span class="line">/var/lib/dpkg/info</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>linux</category>
</categories>
</entry>
<entry>
<title>docker用法</title>
<url>/2020/09/08/docker%E7%94%A8%E6%B3%95/</url>
<content><![CDATA[<p><img src="/assets/img/Docker-wallpaper.jpg" alt=""></p>
<a id="more"></a>
<h2 id="镜像操作">镜像操作</h2>
<p>检索:docker search 关键字</p>
<p>拉取:docker pull 镜像名:tag</p>
<p>列表:docker images</p>
<p>删除:docker rmi image-id</p>
<h2 id="容器操作">容器操作</h2>
<p>根据镜像启动容器:docker run --name -container-name -d -image-name</p>
<p>(-d:后台运行;-p: -host-port; -container-port:端口映射; -it 运行交互模式的容器; -P 将所有的公开端口映射到随机端口上)</p>
<p>查看运行中的容器:docker ps (加-a,表示查看所以的容器)</p>
<p>停止运行中的容器:docker stop -container-id/-container-name</p>
<p>启动容器:docker start -container-id/-container-name</p>