-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
445 lines (214 loc) · 327 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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>IO基础知识总结</title>
<link href="/2023/07/20/io-ji-chu-zhi-shi-zong-jie/"/>
<url>/2023/07/20/io-ji-chu-zhi-shi-zong-jie/</url>
<content type="html"><![CDATA[<h1 id="1-IO流简介"><a href="#1-IO流简介" class="headerlink" title="1. IO流简介"></a>1. IO流简介</h1><p>IO即输入输出,IO流在Java中分为输入流和输出流,根据数据的处理方式又分为字节流和字符流。</p><p>Java IO流中的类都是从如下4个抽象类中派生出来的。</p><ul><li>InputStream/Reader:所有的输入流的基类,前者是字节输入流,后者是字符输入流。</li><li>OutputStream/Writer:所有输出流的基类,前者是字节输出流,后者是字符输出流。</li></ul><h1 id="2-字节流"><a href="#2-字节流" class="headerlink" title="2. 字节流"></a>2. 字节流</h1><h2 id="2-1-字节输入流InputStream"><a href="#2-1-字节输入流InputStream" class="headerlink" title="2.1 字节输入流InputStream"></a>2.1 字节输入流InputStream</h2><p>InputStream用于从文件读取数据(字节信息)到内存中</p><h2 id="2-2-字节输出流OutputStream"><a href="#2-2-字节输出流OutputStream" class="headerlink" title="2.2 字节输出流OutputStream"></a>2.2 字节输出流OutputStream</h2><p>OutputStream用于将数据(字节信息)写入到目的地(通常是文件)</p><h1 id="3-字符流"><a href="#3-字符流" class="headerlink" title="3. 字符流"></a>3. 字符流</h1><p>不管是文件读写还是网络发送接收,信息的最小存储单元都是字节。 那为什么 I/O 流操作要分为字节流操作和字符流操作呢?</p><ul><li>字符流是由 Java 虚拟机将字节转换得到的,这个过程还算是比较耗时。</li><li>如果我们不知道编码类型就很容易出现乱码问题。如果读取的文件中存在中文就容易出现乱码问题。</li></ul><p>因此,I/O 流就干脆提供了一个直接操作字符的接口,方便我们平时对字符进行流操作。如果音频文件、图片等媒体文件用字节流比较好,如果涉及到字符的话使用字符流比较好。</p><h1 id="4-字节缓冲流"><a href="#4-字节缓冲流" class="headerlink" title="4. 字节缓冲流"></a>4. 字节缓冲流</h1><p>IO 操作是很消耗性能的,缓冲流将数据加载至缓冲区,一次性读取/写入多个字节,从而避免频繁的 IO 操作,提高流的传输效率。</p><h2 id="4-1-字节缓冲输入流BufferedInputStream"><a href="#4-1-字节缓冲输入流BufferedInputStream" class="headerlink" title="4.1 字节缓冲输入流BufferedInputStream"></a>4.1 字节缓冲输入流BufferedInputStream</h2><p>BufferedInputStream先将读取到的字节存放在缓存区,从内部缓冲区单独读取字节,减少了IO次数,提高读取效率</p><h2 id="4-2-字节缓冲输出流BufferedOutputStream"><a href="#4-2-字节缓冲输出流BufferedOutputStream" class="headerlink" title="4.2 字节缓冲输出流BufferedOutputStream"></a>4.2 字节缓冲输出流BufferedOutputStream</h2><p>BufferedOutputStream先将要写入的字节存放在缓存区,从内部缓冲区单独写入字节,减少了IO次数,提高读取效率</p>]]></content>
<categories>
<category> Java </category>
</categories>
<tags>
<tag> IO </tag>
<tag> 笔记 </tag>
</tags>
</entry>
<entry>
<title>Java基础</title>
<link href="/2023/06/29/java-ji-chu/"/>
<url>/2023/06/29/java-ji-chu/</url>
<content type="html"><![CDATA[<h1 id="1-基础概念"><a href="#1-基础概念" class="headerlink" title="1.基础概念"></a>1.基础概念</h1><h2 id="1-1Java特点"><a href="#1-1Java特点" class="headerlink" title="1.1Java特点"></a>1.1Java特点</h2><ol><li>简单易学</li><li>面向对象(封装,继承,多态)</li><li>平台无关性( Java 虚拟机实现平台无关性,**.java文件–>.class–>二进制文件**)</li><li>支持多线程</li><li>可靠性(具备异常处理和自动内存管理机制)</li><li>安全性(Java 语言本身的设计就提供了多重安全防护机制如访问权限修饰符、限制程序直接访问操作系统资源)</li><li>。。。</li></ol><h2 id="1-2-JVM-vs-JDK-vs-JRE"><a href="#1-2-JVM-vs-JDK-vs-JRE" class="headerlink" title="1.2 JVM vs JDK vs JRE"></a>1.2 JVM vs JDK vs JRE</h2><h3 id="1-2-1-JVM"><a href="#1-2-1-JVM" class="headerlink" title="1.2.1 JVM"></a>1.2.1 JVM</h3><p>Java虚拟机(JVM)用于运行Java字节码,JVM是平台有关的,即它需要保证使用相同字节码在不同操作系统上得到相同的结果。<strong>字节码和不同系统的 JVM 实现是 Java 语言“一次编译,随处可以运行”的关键所在。</strong></p><h3 id="1-2-2-JDK-和-JRE"><a href="#1-2-2-JDK-和-JRE" class="headerlink" title="1.2.2 JDK 和 JRE"></a>1.2.2 JDK 和 JRE</h3><p>JDK(Java Development Kit)能够<strong>创建和编译</strong> Java 程序。其中包含了 JRE,同时还包含了编译 java 源码的编译器 javac 以及一些其他工具比如 javadoc(文档注释工具)、jdb(调试器)、jconsole(基于 JMX 的可视化监控⼯具)、javap(反编译工具)等等。</p><p>JRE(Java Runtime Environment) 是 Java <strong>运行时环境</strong>。它是运行已编译 Java 程序所需的所有内容的集合,主要包括 Java 虚拟机(JVM)、Java 基础类库(Class Library)。</p><p><strong>JDK包含JRE!!!</strong><br><img src="https://s1.ax1x.com/2023/06/29/pCwbmTI.png" alt="JDK包含JRE"></p><h2 id="1-3-什么是字节码-采用字节码的好处是什么"><a href="#1-3-什么是字节码-采用字节码的好处是什么" class="headerlink" title="1.3 什么是字节码?采用字节码的好处是什么?"></a>1.3 什么是字节码?采用字节码的好处是什么?</h2><p>在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以, Java 程序运行时相对来说还是高效的(不过,和 C++,Rust,Go 等语言还是有一定差距的),而且,由于字节码并不针对一种特定的机器,因此,Java 程序无须重新编译便可在多种不同操作系统的计算机上运行。</p><h2 id="1-4-为什么说-Java-语言“编译与解释并存”?"><a href="#1-4-为什么说-Java-语言“编译与解释并存”?" class="headerlink" title="1.4 为什么说 Java 语言“编译与解释并存”?"></a>1.4 为什么说 Java 语言“编译与解释并存”?</h2><p>高级编程语言主要分为两种:</p><ul><li>编译型:直接将源码编译为机器码,一步到位。这种方式执行速度较快,但是开发效率较低。代表性语言有C、C++、Go、Rust 等等。</li><li>解释型:需要通过解释器将源码解释为机器码。这种方式执行速度较慢,但是开发效率高。代表性语言有Python、JavaScript、PHP 等等。</li></ul><p>而Java 语言<strong>既具有编译型语言的特征,也具有解释型语言的特征</strong>。因为 Java 程序要经过先编译,后解释两个步骤,由 Java 编写的程序需要先经过编译步骤,生成字节码(.class 文件),这种字节码必须由 Java 解释器来解释执行。</p><h2 id="1-5-Java-和-C-的区别"><a href="#1-5-Java-和-C-的区别" class="headerlink" title="1.5 Java 和 C++ 的区别?"></a>1.5 Java 和 C++ 的区别?</h2><ul><li>Java 不提供指针来直接访问内存,程序内存更加安全</li><li>Java 的类是单继承的,C++ 支持多重继承;虽然 Java 的类不可以多继承,但是接口可以多继承</li><li>Java 有自动内存管理垃圾回收机制(GC),不需要手动释放无用内存</li><li>C ++同时支持方法重载和操作符重载,但是 Java 只支持方法重载</li></ul><h1 id="2-基本语法"><a href="#2-基本语法" class="headerlink" title="2. 基本语法"></a>2. 基本语法</h1><h2 id="2-1-标识符和关键字的区别是什么?"><a href="#2-1-标识符和关键字的区别是什么?" class="headerlink" title="2.1 标识符和关键字的区别是什么?"></a>2.1 标识符和关键字的区别是什么?</h2><p><strong>标识符就是一个名字,关键字是有特殊含义的标识符。</strong></p><h2 id="2-2-Java关键字"><a href="#2-2-Java关键字" class="headerlink" title="2.2 Java关键字"></a>2.2 Java关键字</h2><p><img src="https://s1.ax1x.com/2023/06/29/pCwLFqH.png" alt="Java关键字"></p><h2 id="2-3-自增自减运算符"><a href="#2-3-自增自减运算符" class="headerlink" title="2.3 自增自减运算符"></a>2.3 自增自减运算符</h2><p><strong>符号在前就先加/减,后赋值;符号在后就先赋值,后加/减。</strong></p><h2 id="2-4-移位运算符"><a href="#2-4-移位运算符" class="headerlink" title="2.4 移位运算符"></a>2.4 移位运算符</h2><ul><li><< :左移运算符,向左移若干位,高位丢弃,低位补零。x << 1,相当于 x 乘以2(不溢出的情况下)。</li><li>>> :带符号右移,向右移若干位,高位补符号位,低位丢弃。正数高位补 0,负数高位补 1。x >> 1,相当于 x 除以 2。</li><li>>>> :无符号右移,忽略符号位,空位都以 0 补齐。</li></ul><h2 id="2-5-基本类型和包装类型的区别?"><a href="#2-5-基本类型和包装类型的区别?" class="headerlink" title="2.5 基本类型和包装类型的区别?"></a>2.5 基本类型和包装类型的区别?</h2><p>-用途:除了定义一些常量和局部变量之外,我们在其他地方比如方法参数、对象属性中很少会使用基本类型来定义变量。并且,<strong>包装类型可用于泛型,而基本类型不可以</strong>。</p><ul><li>存储方式:基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中,基本数据类型的成员变量(未被 static 修饰 )存放在 Java 虚拟机的堆中。包装类型属于对象类型,我们知道几乎所有对象实例都存在于堆中。</li><li>占用空间:相比于包装类型(对象类型), 基本数据类型占用的空间往往非常小。</li><li>默认值:成员变量包装类型不赋值就是 null ,而基本类型有默认值且不是 null。</li><li>比较方式:对于基本数据类型来说,== 比较的是值。对于包装数据类型来说,== 比较的是对象的内存地址。所有整型包装类对象之间值的比较,全部使用 equals() 方法。</li></ul><h2 id="2-6-自动装箱与拆箱"><a href="#2-6-自动装箱与拆箱" class="headerlink" title="2.6 自动装箱与拆箱"></a>2.6 自动装箱与拆箱</h2><ul><li>装箱:将基本类型用它们对应的引用类型包装起来</li><li>拆箱:将包装类型转换为基本数据类型</li></ul><pre class=" language-java"><code class="language-java">Integer i <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//装箱</span><span class="token keyword">int</span> n <span class="token operator">=</span> i<span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//拆箱</span></code></pre><h1 id="3-变量"><a href="#3-变量" class="headerlink" title="3. 变量"></a>3. 变量</h1><h2 id="3-1-成员变量与局部变量的区别?"><a href="#3-1-成员变量与局部变量的区别?" class="headerlink" title="3.1 成员变量与局部变量的区别?"></a>3.1 成员变量与局部变量的区别?</h2><ul><li>语法形式:<ul><li>成员变量属于类,局部变量是代码块或方法中定义的变量或是方法的参数</li><li>成员变量可以被 public,private,static 等修饰符所修饰,而局部变量不能被访问控制修饰符及 static 所修饰</li><li>成员变量和局部变量都能被 final 所修饰</li></ul></li><li>存储方式:<ul><li>如果成员变量是使用 static 修饰的,那么这个成员变量是属于类的</li><li>如果没有使用 static 修饰,这个成员变量是属于实例的。而对象存在于堆内存,局部变量则存在于栈内存</li></ul></li><li>生存时间:成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动生成,随着方法的调用结束而消亡</li><li>默认值:从变量是否有默认值来看,成员变量如果没有被赋初始值,则会自动以类型的默认值而赋值(一种情况例外:被 final 修饰的成员变量也必须显式地赋值),而局部变量则不会自动赋值</li></ul><h2 id="3-2-静态变量的作用"><a href="#3-2-静态变量的作用" class="headerlink" title="3.2 静态变量的作用"></a>3.2 静态变量的作用</h2><p>静态变量也就是被 <strong>static</strong>修饰的变量。它可以<strong>被类的所有实例共享</strong>,无论一个类创建了多少个对象,它们都共享同一份静态变量。也就是说,<strong>静态变量只会被分配一次内存</strong>,即使创建多个对象,这样可以节省内存。</p><h2 id="3-3-字符型常量和字符串常量的区别"><a href="#3-3-字符型常量和字符串常量的区别" class="headerlink" title="3.3 字符型常量和字符串常量的区别?"></a>3.3 字符型常量和字符串常量的区别?</h2><ul><li>形式 : 字符常量是单引号引起的一个字符,字符串常量是双引号引起的 0 个或若干个字符。</li><li>含义 : 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址值(该字符串在内存中存放位置)。</li><li>占内存大小:字符常量只占 2 个字节; 字符串常量占若干个字节。</li></ul><h1 id="4-方法"><a href="#4-方法" class="headerlink" title="4. 方法"></a>4. 方法</h1><h2 id="4-1-静态方法为什么不能调用非静态成员"><a href="#4-1-静态方法为什么不能调用非静态成员" class="headerlink" title="4.1 静态方法为什么不能调用非静态成员?"></a>4.1 静态方法为什么不能调用非静态成员?</h2><p>静态方法是属于类的,在类加载的时候就会分配内存,可以通过类名直接访问。而非静态成员属于实例对象,只有在对象实例化之后才存在,需要通过类的实例对象去访问。在类的非静态成员不存在的时候静态方法就已经存在了,此时调用在内存中还不存在的非静态成员,属于非法操作。</p><h2 id="4-2-静态方法和实例方法有何不同?"><a href="#4-2-静态方法和实例方法有何不同?" class="headerlink" title="4.2 静态方法和实例方法有何不同?"></a>4.2 静态方法和实例方法有何不同?</h2><ul><li>调用方式</li></ul><p>在外部调用静态方法的时候,可以使用类名.方法名(推荐使用)或实例名.方法名的方式;而调用实例方法只能使用实例名.方法名的方式。所以<strong>使用静态方法的时候无需创建对象</strong>。</p><ul><li>访问类成员是否存在限制</li></ul><p>静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),不允许访问实例成员(即实例成员变量和实例方法),而实例方法不存在这个限制。</p><h2 id="4-3-重载和重写有什么区别?"><a href="#4-3-重载和重写有什么区别?" class="headerlink" title="4.3 重载和重写有什么区别?"></a>4.3 重载和重写有什么区别?</h2><ul><li>重载就是同样的一个方法能够根据输入数据的不同,做出不同的处理。</li><li>重写就是当子类继承自父类的相同方法,输入数据一样,但要做出有别于父类的响应时,就要覆盖父类方法。</li></ul><h1 id="5-基本数据类型"><a href="#5-基本数据类型" class="headerlink" title="5.基本数据类型"></a>5.基本数据类型</h1><h2 id="5-1-基本类型和包装类型的区别"><a href="#5-1-基本类型和包装类型的区别" class="headerlink" title="5.1 基本类型和包装类型的区别"></a>5.1 基本类型和包装类型的区别</h2><ul><li>成员变量包装类型不赋值就是 <code>null</code> ,而基本类型有默认值且不是 <code>null。</code></li><li>包装类型可用于泛型,而基本类型不可以。</li><li>基本数据类型的局部变量存放在 Java 虚拟机栈中的局部变量表中,基本数据类型的成员变量(未被 <code>static</code> 修饰 )存放在 Java 虚拟机的堆中。包装类型属于对象类型,我们知道几乎所有对象实例都存在于堆中。</li><li>比于对象类型, 基本数据类型占用的空间非常小。</li></ul><h1 id="6-面向对象基础"><a href="#6-面向对象基础" class="headerlink" title="6. 面向对象基础"></a>6. 面向对象基础</h1><h2 id="6-1-面向对象和面向过程的区别"><a href="#6-1-面向对象和面向过程的区别" class="headerlink" title="6.1 面向对象和面向过程的区别"></a>6.1 面向对象和面向过程的区别</h2><ul><li>面向过程把解决问题的过程拆解成方法,通过一个个方法去解决问题。</li><li>面向对象先抽象出对象,用对象去执行方法解决问题。</li></ul><p>面向对象相较于面向过程更<strong>易维护、易复用、易扩展。</strong></p><h2 id="6-2-对象实体与对象引用有何不同"><a href="#6-2-对象实体与对象引用有何不同" class="headerlink" title="6.2 对象实体与对象引用有何不同?"></a>6.2 对象实体与对象引用有何不同?</h2><ul><li>对象实例存放在内存中,对象引用存放在栈内存中。</li><li>一个对象引用可以指向0个或1个对象。</li><li>一个对象实例可以被n个引用指向。</li></ul><h2 id="6-3-对象的相等和引用相等的区别"><a href="#6-3-对象的相等和引用相等的区别" class="headerlink" title="6.3 对象的相等和引用相等的区别"></a>6.3 对象的相等和引用相等的区别</h2><ul><li>对象相等一般比较的是内存中存放的内容是否相等。</li><li>引用相等一般比较的是它们指向的内存地址是否相等。</li></ul><h2 id="6-4-如果一个类没有声明构造方法,该程序能正确执行吗"><a href="#6-4-如果一个类没有声明构造方法,该程序能正确执行吗" class="headerlink" title="6.4 如果一个类没有声明构造方法,该程序能正确执行吗?"></a>6.4 如果一个类没有声明构造方法,该程序能正确执行吗?</h2><p>如果一个类没有声明构造方法,也可以执行,因为一个类即使没有声明构造方法也会有<strong>默认的不带参数的构造方法</strong>。</p><h2 id="6-5-构造方法有哪些特点?是否可被-override"><a href="#6-5-构造方法有哪些特点?是否可被-override" class="headerlink" title="6.5 构造方法有哪些特点?是否可被 override?"></a>6.5 构造方法有哪些特点?是否可被 override?</h2><p>构造方法的特点:</p><ul><li>方法名与类名相同</li><li>没有返回值,且不能用void声明</li><li>生成类的对象时自动执行,无需调用</li></ul><p><strong>构造方法不能被重写,但是可以重载。</strong></p><h2 id="6-6-面向对象三大特征"><a href="#6-6-面向对象三大特征" class="headerlink" title="6.6 面向对象三大特征"></a>6.6 面向对象三大特征</h2><ul><li>封装</li><li>继承<ul><li>子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,<strong>只是拥有</strong></li><li>子类可以拥有自己属性和方法,即子类可以对父类进行扩展</li><li>子类可以用自己的方式实现父类的方法</li></ul></li><li>多态:一个对象具有多种的状态,具体表现为父类的引用指向子类的实例。<ul><li>对象类型和引用类型之间具有继承(类)/实现(接口)的关系</li><li>引用类型变量发出的方法调用的到底是哪个类中的方法,必须在程序运行期间才能确定</li><li>多态不能调用“只在子类存在但在父类不存在”的方法</li><li>如果子类重写了父类的方法,真正执行的是子类覆盖的方法,如果子类没有覆盖父类的方法,执行的是父类的方法</li></ul></li></ul><h2 id="6-7-接口和抽象类有什么共同点和区别?"><a href="#6-7-接口和抽象类有什么共同点和区别?" class="headerlink" title="6.7 接口和抽象类有什么共同点和区别?"></a>6.7 接口和抽象类有什么共同点和区别?</h2><p><strong>共同点:</strong></p><ul><li>都不能被实例化</li><li>都可以包含抽象方法</li><li>都可以有默认实现的方法</li></ul><p><strong>区别:</strong></p><ul><li>接口主要用于对类的行为进行约束,你实现了某个接口就具有了对应的行为。抽象类主要用于代码复用,强调的是所属关系。即抽象类<strong>里面定义的都是一个继承体系中的共性内容;<br>接口是功能的集合,是一个体系额外的功能,是暴露出来的规则。</strong></li><li>一个类只能继承一个类,但是可以实现多个接口</li><li>接口中的成员变量只能是 <code>public static final</code> 类型的,不能被修改且必须有初始值,而抽象类的成员变量默认 default,可在子类中被重新定义,也可被重新赋值</li></ul><h2 id="6-8-深拷贝和浅拷贝区别了解吗?"><a href="#6-8-深拷贝和浅拷贝区别了解吗?" class="headerlink" title="6.8 深拷贝和浅拷贝区别了解吗?"></a>6.8 深拷贝和浅拷贝区别了解吗?</h2><ul><li><strong>浅拷贝</strong> :浅拷贝会在堆上创建一个新的对象(区别于引用拷贝的一点),不过,如果原对象内部的属性是引用类型的话,浅拷贝会直接复制内部对象的引用地址,也就是说拷贝对象和原对象共用同一个内部对象。</li><li><strong>深拷贝</strong> :深拷贝会完全复制整个对象,包括这个对象所包含的内部对象。</li></ul><h1 id="7-Object"><a href="#7-Object" class="headerlink" title="7. Object"></a>7. Object</h1><h2 id="7-1-x3D-x3D-和equals-的区别"><a href="#7-1-x3D-x3D-和equals-的区别" class="headerlink" title="7.1 ==和equals()的区别"></a>7.1 ==和equals()的区别</h2><p>==</p><ul><li>对于基本数据类型,==比较的是值</li><li>对于引用数据类型,==比较的是对象的内存地址</li></ul><p>euqals()</p><ul><li>euqals()不能用于判断基本数据类型的变量,只能用来判断两个对象是否相等</li><li>euqals()方法存在于 <code>Object</code>类中,而 <code>Object</code>类是所有类的直接或间接父类,因此所有的类都有 <code>equals()</code>方法</li></ul><p>euqals()方法存在两种使用情况:</p><ul><li><strong>类没有重写euqals()方法</strong>:通过 <code>equals()</code>比较该类的两个对象时,等价于通过“==”比较这两个对象,使用的默认是 <code>Object</code>类 <code>equals()</code>方法</li></ul><ul><li><strong>类重写了 <code>equals()</code>方法</strong> :一般我们都重写 <code>equals()</code>方法来比较两个对象中的属性是否相等;若它们的属性相等,则返回 true(即,认为这两个对象相等)。</li></ul><h2 id="7-2-为什么要有hashCode?"><a href="#7-2-为什么要有hashCode?" class="headerlink" title="7.2 为什么要有hashCode?"></a>7.2 为什么要有hashCode?</h2><p>hashCode能够提高程序执行速度,但是实质上hashCode()和euqals()都是用于比较两个对象是否相等。</p><p><strong>那为什么不只使用hashCode()呢?</strong></p><p>因为两个对象的hashCode值相等并不代表两个对象就一定相等,因为哈希算法有可能刚好让多个对象传回相同的哈希值,这也称为哈希碰撞。因此我们一般比较对象相等时先hashCode()减少equals的使用次数,再euqals()确保两个对象真的相等。</p><h1 id="8-String"><a href="#8-String" class="headerlink" title="8.String"></a>8.String</h1><h2 id="8-1-String、StringBuffer、StringBuilder-的区别?"><a href="#8-1-String、StringBuffer、StringBuilder-的区别?" class="headerlink" title="8.1 String、StringBuffer、StringBuilder 的区别?"></a>8.1 String、StringBuffer、StringBuilder 的区别?</h2><ul><li><p>可变性</p><ul><li>String是不可变的</li><li>StringBuilder与StringBuffer都是继承自AbstractStringBuilder类,该类中提供了很多修改字符串的方法</li></ul></li><li><p>线程安全性</p><ul><li>String中的对象不可变(常量),线程安全</li><li>StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的</li><li>StringBuilder并没有对方法进行加同步锁,所以是非线程安全的</li></ul></li><li><p>性能</p></li><li><p>改变String对象时,都会生成新的String对象</p></li><li><p>StringBuffer的改变针对自身</p></li><li><p>StringBuilder相比StringBuffer有10%~15% 左右的性能提升,但存在多线程不安全的风险</p></li></ul><p><strong>总结:</strong></p><ol><li>少量数据用String</li><li>单线程操作大量数据用StringBuilder</li><li>多线程操作大量数据用StringBuffer</li></ol><h1 id="8-2-字符串拼接用“-”-还是-StringBuilder"><a href="#8-2-字符串拼接用“-”-还是-StringBuilder" class="headerlink" title="8.2 字符串拼接用“+” 还是 StringBuilder?"></a>8.2 字符串拼接用“+” 还是 StringBuilder?</h1><p>Java中支持以”+”来拼接字符串,但是本质上还是通过StringBuilder调用append()方法实现的。如果简单的拼接两者区别并不大,但是如果要在循环内拼接字符串的话:<strong>建议使用StringBuilder来拼接字符串,因为每使用一次”+”都会生成一个新的StringBuilder对象,这样会导致创建过多的StringBuilder对象。</strong></p><h1 id="8-3-String和Object的equals-方法有何区别?"><a href="#8-3-String和Object的equals-方法有何区别?" class="headerlink" title="8.3 String和Object的equals()方法有何区别?"></a>8.3 String和Object的equals()方法有何区别?</h1><p>String中的equals被重写过,用于比较String对象的字符串值是否相等;Object的equals比较的是对象的内存地址。</p><h1 id="9-泛型"><a href="#9-泛型" class="headerlink" title="9. 泛型"></a>9. 泛型</h1><h2 id="9-1-什么是泛型?为什么要使用泛型?"><a href="#9-1-什么是泛型?为什么要使用泛型?" class="headerlink" title="9.1 什么是泛型?为什么要使用泛型?"></a>9.1 什么是泛型?为什么要使用泛型?</h2><p>泛型,即<strong>参数化类型</strong>,就是将原来具体的类型参数化,在不创建新类型的情况下,通过泛型制定不同的类型来控制形参具体限制的类型。</p><h2 id="9-2-泛型的使用方式有哪几种?"><a href="#9-2-泛型的使用方式有哪几种?" class="headerlink" title="9.2 泛型的使用方式有哪几种?"></a>9.2 泛型的使用方式有哪几种?</h2><p><strong>泛型类、泛型接口、泛型方法</strong></p><ol><li>泛型类:</li></ol><pre class=" language-java"><code class="language-java"><span class="token comment" spellcheck="true">//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型</span><span class="token comment" spellcheck="true">//在实例化泛型类时,必须指定T的具体类型</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Generic</span><span class="token operator"><</span>T<span class="token operator">></span><span class="token punctuation">{</span> <span class="token keyword">private</span> T key<span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token function">Generic</span><span class="token punctuation">(</span>T key<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>key <span class="token operator">=</span> key<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> T <span class="token function">getKey</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> key<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><p>实例化泛型</p><pre class=" language-java"><code class="language-java">Generic<span class="token operator"><</span>Integer<span class="token operator">></span> genericInteger <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Generic</span><span class="token operator"><</span>Integer<span class="token operator">></span><span class="token punctuation">(</span><span class="token number">123456</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><ol start="2"><li>泛型接口</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">Generator</span><span class="token operator"><</span>T<span class="token operator">></span> <span class="token punctuation">{</span> <span class="token keyword">public</span> T <span class="token function">method</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><p>实现泛型接口,不指定类型</p><pre class=" language-java"><code class="language-java"><span class="token keyword">class</span> <span class="token class-name">GeneratorImpl</span><span class="token operator"><</span>T<span class="token operator">></span> <span class="token keyword">implements</span> <span class="token class-name">Generator</span><span class="token operator"><</span>T<span class="token operator">></span><span class="token punctuation">{</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> T <span class="token function">method</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> null<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><pre class=" language-java"><code class="language-java"><span class="token keyword">class</span> <span class="token class-name">GeneratorImpl</span><span class="token operator"><</span>T<span class="token operator">></span> <span class="token keyword">implements</span> <span class="token class-name">Generator</span><span class="token operator"><</span>String<span class="token operator">></span><span class="token punctuation">{</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> String <span class="token function">method</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"hello"</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><p>实现泛型接口,不指定类型</p><ol start="3"><li>泛型方法</li></ol><pre class=" language-java"><code class="language-java"> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token operator"><</span> E <span class="token operator">></span> <span class="token keyword">void</span> <span class="token function">printArray</span><span class="token punctuation">(</span> E<span class="token punctuation">[</span><span class="token punctuation">]</span> inputArray <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">for</span> <span class="token punctuation">(</span> E element <span class="token operator">:</span> inputArray <span class="token punctuation">)</span><span class="token punctuation">{</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">printf</span><span class="token punctuation">(</span> <span class="token string">"%s "</span><span class="token punctuation">,</span> element <span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre><p>使用</p><pre class=" language-java"><code class="language-java"><span class="token comment" spellcheck="true">// 创建不同类型数组:Integer, Double 和 Character</span>Integer<span class="token punctuation">[</span><span class="token punctuation">]</span> intArray <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">;</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> stringArray <span class="token operator">=</span> <span class="token punctuation">{</span> <span class="token string">"Hello"</span><span class="token punctuation">,</span> <span class="token string">"World"</span> <span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token function">printArray</span><span class="token punctuation">(</span> intArray <span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token function">printArray</span><span class="token punctuation">(</span> stringArray <span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><h1 id="10-反射"><a href="#10-反射" class="headerlink" title="10. 反射"></a>10. 反射</h1><h2 id="10-1-何为反射?"><a href="#10-1-何为反射?" class="headerlink" title="10.1 何为反射?"></a>10.1 何为反射?</h2><p>反射可以获取并调用任意一个类的所有属性和方法。</p><h2 id="10-2-反射的优缺点"><a href="#10-2-反射的优缺点" class="headerlink" title="10.2 反射的优缺点"></a>10.2 反射的优缺点</h2><ul><li>优点:反射能够提高代码的灵活性</li><li>缺点:存在安全问题(无视泛型参数的安全检查);性能稍差。不过这些影响都不大!</li></ul><h1 id="11-注解"><a href="#11-注解" class="headerlink" title="11. 注解"></a>11. 注解</h1><h2 id="11-1-何为注解?"><a href="#11-1-何为注解?" class="headerlink" title="11.1 何为注解?"></a>11.1 何为注解?</h2><p>注解可以看作是一种特殊的注释,主要用于修饰类、方法或变量,提供某些信息供程序在编译或者运行时使用。</p>]]></content>
<categories>
<category> Java </category>
</categories>
<tags>
<tag> 笔记 </tag>
</tags>
</entry>
<entry>
<title>Java集合(上)</title>
<link href="/2023/06/25/java-ji-he/"/>
<url>/2023/06/25/java-ji-he/</url>
<content type="html"><![CDATA[<h1 id="1-集合概览"><a href="#1-集合概览" class="headerlink" title="1. 集合概览"></a>1. 集合概览</h1><h2 id="1-1-Java集合概览"><a href="#1-1-Java集合概览" class="headerlink" title="1.1 Java集合概览"></a>1.1 Java集合概览</h2><p>Java集合主要包括两部分:Collection接口,用于存放单一元素;Map接口,用于存放键值对。</p><p>Java 集合框架如下图所示:<br><img src="https://s1.ax1x.com/2023/06/25/pCNnP4U.png" alt="Java集合框架概览"></p><h2 id="1-2-说说-List-Set-Queue-Map-四者的区别?"><a href="#1-2-说说-List-Set-Queue-Map-四者的区别?" class="headerlink" title="1.2 说说 List, Set, Queue, Map 四者的区别?"></a>1.2 说说 List, Set, Queue, Map 四者的区别?</h2><ul><li>List: 存储的元素是<strong>有序的、可重复的</strong>。</li><li>Set:存储的元素是<strong>无序的、不可重复的</strong>。</li><li>Queue: 按特定的排队规则来确定先后顺序,存储的元素是<strong>有序的、可重复的</strong>。</li><li>Map(用 key 来搜索的专家): 使用键值对(key-value)存储,类似于数学上的函数 y=f(x),”x” 代表 key,”y” 代表 value,<strong>key 是无序的、不可重复的,value 是无序的、可重复的,每个键最多映射到一个值。</strong></li></ul><h2 id="1-3-为什么要使用集合?"><a href="#1-3-为什么要使用集合?" class="headerlink" title="1.3 为什么要使用集合?"></a>1.3 为什么要使用集合?</h2><p>我们常使用数组来存储一组同类型的数据,但是在实际开发中,存储的数据类型多种多样且数量不确定。与数组相比,Java 集合提供了<strong>更灵活、更有效</strong>的方法来存储多个数据对象。Java 集合框架中的各种集合类和接口可以存储不同类型和数量的对象,同时还具有多样化的操作方式。相较于数组,Java 集合的优势在于它们的<strong>大小可变、支持泛型、具有内建算法</strong>等。总的来说,Java 集合提高了数据的存储和处理灵活性,可以更好地适应现代软件开发中多样化的数据需求,并支持高质量的代码编写。</p><h2 id="1-4-如何选用集合?"><a href="#1-4-如何选用集合?" class="headerlink" title="1.4 如何选用集合?"></a>1.4 如何选用集合?</h2><ul><li><p>需要根据键值获取元素值就选用Map接口下的集合</p><ul><li>需要排序TreeMap</li><li>无需排序HashMap</li><li>需要保证线程安全ConcurrentHashMap</li></ul></li><li><p>只存放元素选择Collection接口的集合</p><ul><li>需要保证元素唯一Set</li><li>无需保证元素唯一List</li></ul></li></ul><h1 id="2-List"><a href="#2-List" class="headerlink" title="2. List"></a>2. List</h1><h2 id="2-1-ArrayList-和-Array(数组)的区别?"><a href="#2-1-ArrayList-和-Array(数组)的区别?" class="headerlink" title="2.1 ArrayList 和 Array(数组)的区别?"></a>2.1 ArrayList 和 Array(数组)的区别?</h2><p>ArrayList内部基于动态数组实现,比Array更加灵活方便:</p><ul><li>ArrayList可以动态扩缩容,Array一旦创建就无法改变长度</li><li>ArrayList可以使用泛型来确保类型安全,Array不可以</li><li>ArrayList能存储<strong>任何类型的对象</strong>,对于基本数据类型,需要使用其包装类。Array对象和基本数据类型都可以存储</li><li>ArrayList提供了丰富的API,Array只能根据下标访问元素,修改麻烦</li><li>ArrayList创建时无需定义大小,Array需要定义大小</li></ul><h2 id="2-2-ArrayList-插入和删除元素的时间复杂度?"><a href="#2-2-ArrayList-插入和删除元素的时间复杂度?" class="headerlink" title="2.2 ArrayList 插入和删除元素的时间复杂度?"></a>2.2 ArrayList 插入和删除元素的时间复杂度?</h2><p>插入:</p><ul><li>头部插入:将所有元素依次后移一位,时间复杂度是 O(n)</li><li>尾部插入:当ArrayList的容量还没满时,直接插在尾部时间复杂度是 O(1);当容量已满需要扩容时,先扩容时间复杂度是O(n),再插入时间复杂度是 O(1),因此时间复杂度是 O(n)</li><li>指定位置插入:需要将目标位置之后的所有元素都向后移动一个位置,然后再把新元素放入指定位置。这个过程需要移动平均 n/2 个元素,因此时间复杂度为 O(n)</li></ul><p>删除:</p><ul><li>头部删除:将所有元素依次前移一位,时间复杂度是 O(n)</li><li>尾部删除:直接删除,时间复杂度是 O(1)</li><li>指定位置删除:需要将目标位置之后的所有元素都向前移动一个位置,然后再把新元素放入指定位置。这个过程需要移动平均 n/2 个元素,因此时间复杂度为 O(n)</li></ul><h2 id="2-3-LinkedList-插入和删除元素的时间复杂度?"><a href="#2-3-LinkedList-插入和删除元素的时间复杂度?" class="headerlink" title="2.3 LinkedList 插入和删除元素的时间复杂度?"></a>2.3 LinkedList 插入和删除元素的时间复杂度?</h2><ul><li>头尾插入/删除:修改头/尾节点指针修改,时间复杂度是 O(1)</li><li>指定位置插入/删除:需要先移动到指定位置,再修改指定节点的指针完成插入/删除,因此需要移动平均 n/2 个元素,时间复杂度为 O(n)</li></ul><h2 id="2-4-ArrayList-与-LinkedList-区别"><a href="#2-4-ArrayList-与-LinkedList-区别" class="headerlink" title="2.4 ArrayList 与 LinkedList 区别?"></a>2.4 ArrayList 与 LinkedList 区别?</h2><ul><li><strong>是否保证线程安全</strong>:ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全 <a href="https://blog.csdn.net/m0_58196614/article/details/126257857?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168782879816800227493346%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168782879816800227493346&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-126257857-null-null.142%5Ev88%5Econtrol_2,239%5Ev2%5Einsert_chatgpt&utm_term=Java%E4%B8%AD%E7%9A%84%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8&spm=1018.2226.3001.4187">Java线程安全详解</a></li><li><strong>底层数据结构</strong>: ArrayList 为数组, LinkedList为链表</li><li><strong>插入和删除是否受元素位置影响</strong>:区别与数组和链表同理</li><li><strong>是否支持快速访问</strong>:区别与数组和链表同理</li><li><strong>内存空间占用</strong>:ArrayList在list末尾会预留一定空间;LinkedList一个结点包括前驱、后继结点和数据三个部分</li></ul><p>在项目中一般是不会使用到 LinkedList 的,需要用到 LinkedList 的场景几乎都可以使用 ArrayList 来代替,并且,性能通常会更好!</p><h1 id="3-Map"><a href="#3-Map" class="headerlink" title="3. Map"></a>3. Map</h1><h2 id="3-1-HashMap-和-Hashtable-的区别"><a href="#3-1-HashMap-和-Hashtable-的区别" class="headerlink" title="3.1 HashMap 和 Hashtable 的区别"></a>3.1 HashMap 和 Hashtable 的区别</h2><ul><li><strong>线程是否安全:</strong>HashMap是非线程安全的,Hashtable是线程安全的(被synchronized修饰)</li><li><strong>效率:</strong>HashMap效率较高</li><li><strong>Null key和Null value的支持:</strong>HashMap可以存储空的键值而Hashtable不允许</li><li>。。。</li></ul>]]></content>
<categories>
<category> Java </category>
</categories>
<tags>
<tag> 笔记 </tag>
<tag> 集合 </tag>
</tags>
</entry>
<entry>
<title>Docker学习笔记</title>
<link href="/2023/05/26/docker-xue-xi-bi-ji/"/>
<url>/2023/05/26/docker-xue-xi-bi-ji/</url>
<content type="html"><![CDATA[<p>最近项目中应用到了Docker这项技术,在此记录一下。</p><h1 id="Docker能做什么?"><a href="#Docker能做什么?" class="headerlink" title="Docker能做什么?"></a>Docker能做什么?</h1><p>有了需求才会驱动我们去学习一门新的技术,那么Docekr能做什么呢?</p><p><strong>Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。</strong></p><p>这里与虚拟机技术做一个比较:</p><ul><li>传统虚拟机,虚拟出一整个硬件,一个虚拟机运行一个完整的操作系统,然后在这个系统上安装和运行软件</li><li>容器内的应用直接运行在宿主机中,这里需要注意容<strong>器没有自己的内核,也没有虚拟硬件,因此轻便许多!</strong></li><li>每个容器间相互隔离,每个容器内都有一个属于自己的文件系统,互不影响。这里让我感觉这地方的概念跟Anaconda中的虚拟环境挺像</li></ul><h1 id="基本概念"><a href="#基本概念" class="headerlink" title="基本概念"></a>基本概念</h1><p><img src="https://ts1.cn.mm.bing.net/th/id/R-C.1774676184117a7651da679303f7f2a5?rik=tD8GxVFzILxUTA&riu=http://www.yiibai.com/uploads/images/201706/0206/262150629_86976.png&ehk=b08QZOJOFKWBBfczWiSLKjdCb8XG5Ow2kHoxAUT2F/I=&risl=&pid=ImgRaw&r=0" alt="Docker架构"></p><p><strong>镜像(image)</strong></p><p>镜像可以理解为一个模板,我们可以通过这个模板来创建容器服务,通过一个镜像可以创建多个容器(镜像类似一个类,而容器可以看作是这个镜像创建出来的实例对象)</p><p><strong>容器(container)</strong></p><p>Docker利用容器就可以独立运行一个或者一组应用。</p><p><strong>仓库(repository)</strong></p><p>仓库就是存放镜像的地方,这里例举几个:</p><p>Docker Hub:<a href="https://hub.docker.com/">https://hub.docker.com/</a></p><p>阿里云:<a href="https://cr.console.aliyun.com/">https://cr.console.aliyun.com</a> </p><p>中科大:<a href="https://github.com/ustclug/mirrorrequest">https://github.com/ustclug/mirrorrequest</a></p><h1 id="常用命令"><a href="#常用命令" class="headerlink" title="常用命令"></a>常用命令</h1><p>详细命令可以去查官方文档:<a href="https://docs.docker.com/reference/">https://docs.docker.com/reference/</a></p><p>这里只列举部分常用的</p><h2 id="镜像命令"><a href="#镜像命令" class="headerlink" title="镜像命令"></a>镜像命令</h2><p><strong>docker images</strong> 查看所有本地主机上的镜像</p><p>用法:docker images [OPTIONS] [REPOSITORY[:TAG]]</p><p><img src="https://s1.ax1x.com/2023/05/26/p9bxSHg.md.png" alt="docker images"><br><strong>docker search</strong> 搜索镜像</p><p>用法:docker search [OPTIONS] TERM<br><img src="https://s1.ax1x.com/2023/05/26/p9bxvGR.png" alt="docker search"></p><p><strong>docker pull</strong> 下载镜像</p><p>用法:docker pull [OPTIONS] NAME[:TAG|@DIGEST]<br><img src="https://s1.ax1x.com/2023/05/26/p9bzEid.png" alt="docker pull"></p><p><strong>docker rmi</strong> 删除镜像<br>用法:docker rmi [OPTIONS] IMAGE [IMAGE…]</p><h2 id="容器命令"><a href="#容器命令" class="headerlink" title="容器命令"></a>容器命令</h2><p><strong>注意:有了镜像才可以创建容器,这里我们下载一个centos镜像来测试学习。</strong></p><pre class=" language-shell"><code class="language-shell">docker pull centos</code></pre><p><strong>新建容器并启动</strong></p><p>用法:docker run [OPTIONS] IMAGE [COMMAND] [ARG…]</p><pre class=" language-shell"><code class="language-shell"># 参数说明--name="Name" 容器名字-d 后台方式运行-it 交互式运行-p 指定容器端口 -p ip:主机端口:容器端口 -p 主机端口:容器端口 -p 容器端口 容器端口-P 随机指定端口</code></pre><p><strong>注意:这里有一个常见的坑。在后台启动容器时,如果没有一个前台进程,docker就会自动停止</strong></p><p><strong>退出容器</strong></p><pre class=" language-shell"><code class="language-shell">exit # 停止并退出ctrl+p+q #退出但不停止</code></pre><p><strong>列出所有运行的容器</strong><br>用法:docker ps [OPTIONS]<br><img src="https://s1.ax1x.com/2023/05/26/p9qPEvR.png" alt="docker ps"></p><p><strong>删除容器</strong><br>用法:docker rm [OPTIONS] CONTAINER [CONTAINER…]<br><img src="https://s1.ax1x.com/2023/05/26/p9qP7s1.png" alt="docker rm"></p><p><strong>启动和停止容器</strong></p><pre class=" language-shell"><code class="language-shell">docker start 容器id # 启动容器docker restart 容器id # 重启容器docker stop 容器id # 停止当前正在运行的容器docker kill 容器id # 强制停止当前容器</code></pre><h1 id="commit镜像"><a href="#commit镜像" class="headerlink" title="commit镜像"></a>commit镜像</h1><p>这里如果你学习过git的话就很容易理解了,这条命令可以将修改过的现有容器变为一个新的镜像来使用。</p><p>实战测试</p><pre class=" language-shell"><code class="language-shell"># 启动一个官方的tomcat# 发现官方的tomcat中没有webapps应用# 手动拷贝需要的基本文件后commit,以后就可以使用这个修改过的镜像</code></pre><p><img src="https://s1.ax1x.com/2023/05/30/p9jMK78.png" alt="commit"></p><h1 id="容器数据卷"><a href="#容器数据卷" class="headerlink" title="容器数据卷"></a>容器数据卷</h1><h2 id="什么是容器数据卷?"><a href="#什么是容器数据卷?" class="headerlink" title="什么是容器数据卷?"></a>什么是容器数据卷?</h2><p>首先这里有个需求,就是如果容器删除,容器中的数据就会随之丢失。我们希望<strong>数据可以持久化存储在本地!</strong></p><p>我们可以运用卷技术,将容器内的目录挂载到本地。</p><p><strong>总结起来就是容器的持久化和同步操作,且不同的容器之间也可以进行数据共享!</strong></p><h2 id="使用数据卷"><a href="#使用数据卷" class="headerlink" title="使用数据卷"></a>使用数据卷</h2><h3 id="方式一"><a href="#方式一" class="headerlink" title="方式一"></a>方式一</h3><blockquote><p>docker run -it -v 主机目录:容器内目录</p></blockquote><p>值得注意的是数据的挂载是双向的,也就是说不管你是在主机中对数据作出修改或是在容器中对数据作出修改,都会立马映射到另一端,也即两端自动同步。</p><h1 id="DockerFile"><a href="#DockerFile" class="headerlink" title="DockerFile"></a>DockerFile</h1><p>除了上述方式进行挂载外,我们还可以利用DockerFile进行挂载。<strong>Dockerfile就是用来构建docker镜像的文件,实质就是一段脚本!</strong></p><h3 id="方式二"><a href="#方式二" class="headerlink" title="方式二"></a>方式二</h3><p>在编写Dockerfile时将挂载数据卷的操作直接写进去,这里有详细的Dockerfile编写格式,本文这里就不再赘述了。</p><p>Dockerfile编写参考资料</p><ul><li><a href="https://docker.easydoc.net/doc/81170005/cCewZWoN/N9VtYIIi">https://docker.easydoc.net/doc/81170005/cCewZWoN/N9VtYIIi</a></li><li><a href="https://www.runoob.com/docker/docker-dockerfile.html">https://www.runoob.com/docker/docker-dockerfile.html</a></li></ul>]]></content>
<categories>
<category> 技术 </category>
</categories>
<tags>
<tag> Docker 容器化技术 </tag>
</tags>
</entry>
<entry>
<title>声纹识别论文阅读(七)</title>
<link href="/2023/05/17/sheng-wen-shi-bie-lun-wen-yue-du-qi/"/>
<url>/2023/05/17/sheng-wen-shi-bie-lun-wen-yue-du-qi/</url>
<content type="html"><![CDATA[<p>文章链接:<a href="https://arxiv.org/pdf/2110.03869.pdf">https://arxiv.org/pdf/2110.03869.pdf</a></p><h1 id="1-题目"><a href="#1-题目" class="headerlink" title="1.题目"></a>1.题目</h1><p><strong>SELF-SUPERVISED SPEAKER RECOGNITION WITH LOSS-GATED LEARNING</strong></p><h1 id="2-总结"><a href="#2-总结" class="headerlink" title="2.总结"></a>2.总结</h1><p>写完笔记之后最后填,概述文章的内容,以后查阅笔记的时候先看这一段。</p><h1 id="3-研究动机"><a href="#3-研究动机" class="headerlink" title="3.研究动机"></a>3.研究动机</h1><p>在自监督说话人识别中,使用伪标签作为监督信息对模型有着积极的效果。然而,现有研究发现,不是所有的伪标签都对模型有着积极的效果。且作者发现可靠的伪标签相比于不可靠的伪标签在网络建模时有着更快的速度。</p><h1 id="4-使用方法"><a href="#4-使用方法" class="headerlink" title="4.使用方法"></a>4.使用方法</h1><p>模型采用了一种<strong>two-stage</strong>的架构,如下图所示。</p><ul><li>StageⅠ采用对比学习训练来得到一个说话人编码器</li><li>StageⅡ首先通过聚类生成伪标签,然后反复训练分类网络</li></ul><p><img src="https://s1.ax1x.com/2023/05/17/p9W3Idf.jpg" alt="基于LGL的自监督学习说话人识别框架"></p><h2 id="4-1-StageⅠ"><a href="#4-1-StageⅠ" class="headerlink" title="4.1 StageⅠ"></a>4.1 StageⅠ</h2><p>StageⅠ采用了<strong>对比学习</strong>的方法来训练说话人编码器。这里需要注意的是本文中的<strong>positive pairs</strong>定义为来自于同一段语音的<strong>segments</strong>(即同一段语音被分割后的两段),<strong>negative pairs</strong>则是来自不同语音的<strong>segments。</strong></p><p><strong>这里其实对于对比学习还是依旧存在一点疑问,按照对比学习的方法,从同一个说话人的不同语音段分割出来的语音是属于negative pairs,这里让人感觉很别扭。博主查了一些相关资料,大致是这样解释的:对比学习的目的是判断是否是正负样本,本质上一个二分类的问题。它是在训练网络提取特征的能力(提取某一类型数据的通用特征),而并非有确切的目的(分类、分割、检测等)。当在没有标签的条件下得到一个不错的编码器之后,可以加上不同的任务头进一步去做下游任务,对应在本文中也就是StageⅡ阶段。</strong></p><h2 id="4-2-StageⅡ"><a href="#4-2-StageⅡ" class="headerlink" title="4.2 StageⅡ"></a>4.2 StageⅡ</h2><p>首先,StageⅡ使用StageⅠ训练好的编码器作为<strong>initial model</strong>提取说话人特征;然后,使用k-means聚类算法对这些说话人特征进行聚类以生成伪标签,在这里作者假设聚类后的每一个簇表示同一个说话人;接着,再用生成的伪标签训练编码器;最后,经过不断迭代直到模型收敛。这里需要注意的是每次迭代得到的分类编码器会生成新的伪标签,用于下一次迭代训练。</p><h2 id="4-3-LOSS-GATED-LEARNING"><a href="#4-3-LOSS-GATED-LEARNING" class="headerlink" title="4.3 LOSS-GATED LEARNING"></a>4.3 <strong>LOSS-GATED LEARNING</strong></h2><h1 id="5-结论"><a href="#5-结论" class="headerlink" title="5.结论"></a>5.结论</h1><ul><li>可靠的伪标签相比于不可靠的伪标签在网络建模时有着更快的速度</li><li>LGL策略可以有效选择可靠伪标签</li></ul><h1 id="6-参考资料"><a href="#6-参考资料" class="headerlink" title="6.参考资料"></a>6.参考资料</h1><ul><li><a href="https://www.bilibili.com/video/BV1aP4y1Z7pE/?spm_id_from=333.337.search-card.all.click">对比学习课程,草履虫都能学会的!</a></li><li><a href="https://www.bilibili.com/video/BV19S4y1M7hm/?spm_id_from=333.337.search-card.all.click">对比学习论文综述【论文精读】</a></li></ul>]]></content>
<categories>
<category> 论文 </category>
</categories>
<tags>
<tag> 论文阅读笔记 </tag>
<tag> 深度学习 </tag>
<tag> 人工智能 </tag>
</tags>
</entry>
<entry>
<title>声纹识别论文阅读(六)</title>
<link href="/2022/11/02/sheng-wen-shi-bie-lun-wen-yue-du-liu/"/>
<url>/2022/11/02/sheng-wen-shi-bie-lun-wen-yue-du-liu/</url>
<content type="html"><![CDATA[<h1 id="1-题目"><a href="#1-题目" class="headerlink" title="1.题目"></a>1.题目</h1><p>Dual Path Embedding Learning for Speaker Verification with Triplet Attention</p><h1 id="2-总结"><a href="#2-总结" class="headerlink" title="2.总结"></a>2.总结</h1><p>本文提出了一种非常新颖的方法,通过两条路径来学习不同的特征,再让它们交互来得到更加全面的特征。用巧妙的设计模拟出了相似于RNN的状态,使得特征能够不断的积累。除此之外还提出了TA模块,即将C、F、T三种特征两两配对,经过注意力机制后再度融合,强调了三个维度间特征的相互依赖性。</p><p>基于上述创新之处,构建出了DPNet。且达到了交换两条路径上的特征,并使特征不断积累的效果。</p><h1 id="3-研究目标"><a href="#3-研究目标" class="headerlink" title="3.研究目标"></a>3.研究目标</h1><p>在说话人识别任务当中存在很多优秀的模型,但是人们对于掺杂了变种结构的混合模型的研究较少。故作者提出了一种新的混合变体网络结构。</p><h1 id="4-使用方法"><a href="#4-使用方法" class="headerlink" title="4.使用方法"></a>4.使用方法</h1><p>该网络中主要有两点创新,一个是双路径嵌入学习,另一个是提出了基于注意力机制的三特征融合TA模块。</p><h2 id="4-1-双路径嵌入学习"><a href="#4-1-双路径嵌入学习" class="headerlink" title="4.1 双路径嵌入学习"></a>4.1 双路径嵌入学习</h2><p>双路径为<strong>残差路径</strong>和<strong>循环路径</strong>,这两个路径所提取的特征都被用来交换信息以提取更好的特征。</p><ul><li>残差路径使用的是常用的ResNet</li><li>循环路径设计为给当前层提供的特征为先前网络层的特征沿着网络深度的积累(类似RNN,我想这也是它被称为循环路径的原因吧)</li></ul><p>下面是DPNet的模型结构图<br><img src="https://s1.ax1x.com/2022/11/02/xHO77D.jpg" alt="DPNet"></p><ol><li>残差路径</li></ol><p>残差路径即Residual Block,其实我觉得这个路径确切点可以叫做残差循环路径,因为在它也包含了和循环路径中相同的结构。不过作者可能更想突出它残差网络的部分,所以命名为残差路径。它主要使用ResNet网络和TA模块(TA后面会有讲到)</p><ol start="2"><li>循环路径</li></ol><p>循环路径即Recurrent Block。它主要用来积累每一层的特征、与残差路径交换信息、在时序上达到对特征的<strong>再利用和再挖掘</strong>。需要注意的是再循环路径中用到的第一个卷积为point-wise convolution(还记得上一篇论文里面提到的depth-wise convolution么?<a href="https://gaonan98.github.io/2022/10/24/sheng-wen-shi-bie-lun-wen-yue-du-wu/">传送门</a>)</p><p><em>这里不得不吐槽一下,这是一篇2022年声纹顶会interspeech上的文章,但是在写作时他却用了不合适的符号。他将循环路径中的两个卷积分别分为Conv1和Conv2,但是在模型图的残差路径中已经存在一个Conv1。这让我看的时候愣逼了半天,不过也有可能是我理解有问题吧,希望是我理解有问题。。。除此之外在本文Conclusions这一章,出现了把outperform错写成ourperform的低级错误,希望这也是我没看懂的单词吧,/(ㄒoㄒ)/~~</em></p><p><strong>至此,我们可以看出DPNet的核心思想就是积累和交换两个路径上的特征,从而达到加强特征学习的效果。</strong></p><h2 id="4-2-Triplet-Attention-Module-TA"><a href="#4-2-Triplet-Attention-Module-TA" class="headerlink" title="4.2 Triplet Attention Module(TA)"></a>4.2 Triplet Attention Module(TA)</h2><p>这里作者提出了一种新的注意力模块,如下图<br><img src="https://s1.ax1x.com/2022/11/04/xqODnP.png" alt="TA"><br>它主要分为三个部分,分别提取了特征在CF、CT和FT上的特征,强调了特征之间的相互依赖性,最后再加以融合。</p><h1 id="5-结论"><a href="#5-结论" class="headerlink" title="5.结论"></a>5.结论</h1><ul><li>DPNet继承了残差网络和循环网络的优点,能够更好的实现对于特征的<strong>再利用和再发现</strong></li><li>DPNet的关键所在就是<strong>积累和交换</strong>两个路径下的特征</li><li>在CNN网络中沿着<strong>深度</strong>引入循环路径对于特征的再利用和再发现是非常有用的</li></ul><h1 id="6-额外笔记"><a href="#6-额外笔记" class="headerlink" title="6.额外笔记"></a>6.额外笔记</h1><h2 id="6-1-pointwise-convolution"><a href="#6-1-pointwise-convolution" class="headerlink" title="6.1 pointwise convolution"></a>6.1 pointwise convolution</h2><p>它与常规卷积非常相似,唯一不同的是它的<strong>卷积核大小为1*1*M</strong>,M为被卷积特征的通道数。如下图:<br><img src="https://img-blog.csdnimg.cn/20210323144720682.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjA2MDU3Mg==,size_16,color_FFFFFF,t_70" alt="pointwise convolution"></p><h1 id="7-参考资料"><a href="#7-参考资料" class="headerlink" title="7.参考资料"></a>7.参考资料</h1><ul><li><a href="https://blog.csdn.net/weixin_42060572/article/details/115123303?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166752201816782428682113%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166752201816782428682113&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-5-115123303-null-null.142%5Ev63%5Econtrol,201%5Ev3%5Econtrol_2,213%5Ev1%5Et3_esquery_v1&utm_term=pointwise%20convolution&spm=1018.2226.3001.4187">卷积网络基础知识</a></li></ul>]]></content>
<categories>
<category> 论文 </category>
</categories>
<tags>
<tag> 论文阅读笔记 </tag>
<tag> 深度学习 </tag>
<tag> 人工智能 </tag>
</tags>
</entry>
<entry>
<title>声纹识别论文阅读(五)</title>
<link href="/2022/10/24/sheng-wen-shi-bie-lun-wen-yue-du-wu/"/>
<url>/2022/10/24/sheng-wen-shi-bie-lun-wen-yue-du-wu/</url>
<content type="html"><![CDATA[<h1 id="1-题目"><a href="#1-题目" class="headerlink" title="1.题目"></a>1.题目</h1><p>DF-ResNet: Boosting Speaker Verification Performance with Depth-First Design</p><h1 id="2-总结"><a href="#2-总结" class="headerlink" title="2.总结"></a>2.总结</h1><p>在作者发现这一重要结论 <strong>(depth is more important than the width of networks for speaker verification task)</strong> 后,作者提出了一种新的但是却又完全基于标准的卷积网络的结构。该结构的设计基于深度优先的规则,虽然在提升网络的层数,但能保持复杂度不会大幅度上升,在此基础上取得了很好的效果。作者将其应用到了ResNet上构造出了DF-ResNet,并与ECAPA和ResNet做了比较,如下图。<br><img src="https://s1.ax1x.com/2022/10/30/xIcAFs.jpg" alt="Vox1-O EER vs. Model Size"></p><h1 id="3-研究目标"><a href="#3-研究目标" class="headerlink" title="3.研究目标"></a>3.研究目标</h1><p>作者通过研究发现对于说话人识别任务来说,深度相较于宽度对于网络来说是更加重要的。于是作者为了验证这个说法开始了一系列验证。</p><h1 id="4-使用方法"><a href="#4-使用方法" class="headerlink" title="4.使用方法"></a>4.使用方法</h1><p>作者提出了基于深度优先的规则来<strong>深化</strong>网络,下图展示了从ResNet18到DF-ResNet56的转换过程<img src="https://s1.ax1x.com/2022/10/30/xIclTJ.jpg" alt="ResNet18到DF-ResNet56的转换过程图"></p><ul><li>A图:原生ResNet的瓶颈模块</li><li>B图:用depthwise convolution来代替标准的卷积</li><li>C图:交换两个1×1卷积的位置,并将depthwise convolution的通道数增加到128</li><li>D图:加入一个单独的下采样层</li></ul><p><strong>深度优化设计规则:需要注意的是这并不是直接增加层数的数量,关键要义是神话网络的同时还要保证模型复杂度不能变化太大。</strong></p><p>下表为从ResNet18到DF-ResNet56各个过程中参数数量、FLOPs和模型效果数值<br><img src="https://s1.ax1x.com/2022/10/30/xIIzNT.jpg"></p><ol><li>basicblock → bottleneckblock</li></ol><p>在将ResNet18中的基本模块更换之后发现效果反而变差,所以可以看出这种瓶颈层对ResNet影响不大,这就有必要去重新设计它。</p><ol start="2"><li>conv2d → depthwise conv2d</li></ol><p>采用depthwise conv2d去代替普通的卷积(depthwise conv2采用一种特殊的<strong>组数等于通道数</strong>的组卷积)</p><ol start="3"><li>invert dimension</li></ol><p>这里将瓶颈层倒置,瓶颈层一般是为了加深深度减少参数量和计算量提出的一种结构,按理说倒置后会出现相反的结果。但是在这里参数量骤减、计算量降低了一点点,效果却只是差了一丢丢而已。这是因为除了倒置,还将中间第二层的卷积分为了128组,这才导致了参数量和计算量的减少。</p><ol start="4"><li>separate downsampling</li></ol><p>将一个单独的降采样层放在模块的最后进一步提取特征。</p><ol start="5"><li>increase layer number</li></ol><p>在利用depthwise conv2d减少参数量和计算量后,再不断加入层数优化网络。</p><h1 id="5-结论"><a href="#5-结论" class="headerlink" title="5.结论"></a>5.结论</h1><p>其实就是作者不断在文章中提到的这句话:</p><p><strong>depth is more important than the width of networks for speaker verification task.</strong></p><h1 id="6-额外笔记"><a href="#6-额外笔记" class="headerlink" title="6.额外笔记"></a>6.额外笔记</h1><h2 id="6-1-depthwise-conv2d"><a href="#6-1-depthwise-conv2d" class="headerlink" title="6.1 depthwise conv2d"></a>6.1 depthwise conv2d</h2><p>depthwise conv2d是一种特殊的<strong>分组卷积</strong>,那么什么又是分组卷积呢?其实最早在读AlexNet时,因为当时硬件资源有限,训练时卷积无法放到一个GPU里。于是作者将特征一分为二,放在两个GPU里分别进行卷积,直到最后处理完毕才将两份特征进行融合。</p><p>现如今我们的硬件资源已经得到了很大的提升,那么是否这种分组卷积的方法就没有必要再使用了呢?答案是否定的。下面我们来分析一下。(示意图不是很好,因为输出通道都是1,搞得我理解的时候刚开始出现了好大的偏差,<strong>以下图中未出现的C’均为输出通道</strong>)</p><ul><li>标准卷积</li></ul><p><img src="https://s1.ax1x.com/2022/10/31/xTYhBq.jpg" alt="标准卷积"></p><p><strong>输入特征尺寸:</strong> W×H×C</p><p><strong>卷积核尺寸:</strong> k×k×C</p><p><strong>特征图尺寸:</strong> W’×H’</p><p>参数量params=k²C <strong>注意这里是总的参数量</strong></p><p>运算量=k²CC’W’H’,这里只考虑浮点乘数量,不考虑浮点加数量</p><ul><li>分组卷积</li></ul><p><img src="https://s1.ax1x.com/2022/10/31/xTY4H0.jpg" alt="分组卷积"></p><p>分组卷积将输入的特征分为g组,同样的,卷积核也被分为g组,让他们分组做卷积,最后得到g组特征图。</p><p><strong>分组后输入特征尺寸(一组):</strong> W×H×(C/g)</p><p><strong>分组后卷积核尺寸(一组):</strong> k×k×(C/g)</p><p><strong>分组后特征图尺寸(一组):</strong> W’×H’</p><p>参数量params=k²×(C/g)×(C’/g)×g=(k²CC’)/g</p><p>运算量=k²(C/g)(C’/g)W’H’×g=(k²CW’H’)/g,这里只考虑浮点乘数量,不考虑浮点加数量</p><p>这样看来,我们用1/g的多的参数量和运算量得到了更多的特征!这就是它目前依旧存在,依旧坚挺的原因。它的优势在于<strong>减少了特征数量和运算量</strong>,那么效果如何呢?事实证明在某些情况下分组卷积的效果确实要比标准卷积要好,具体可以参照这里<a href="https://blog.yani.ai/filter-group-tutorial/">A Tutorial on Filter Groups (Grouped Convolution)</a></p><p>若要分析其原因,则是这种方法增加相邻层filter之间的对角相关性,而且能够减少训练参数,不容易过拟合。关于对角相关性,这篇博客里做出了解释,但是这<strong>只是实验结果,并没有明确说明是为什么。</strong> <a href="https://blog.csdn.net/dujuancao11/article/details/116425390">传送门</a></p><p>接下来终于可以讲depthwise conv2d了,其实它非常简单。当分组卷积中的g=1时,就是普通的卷积;当分组卷积中的g=C也即组数等于特征通道数时,就是我们所说的depthwise conv2d。</p><p>例如下图,三通的的输入特征分为三组分别进行卷积,得到结果后再进行堆叠。<br><img src="https://img-blog.csdnimg.cn/20200819230010459.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTA4Nzk3NDU=,size_16,color_FFFFFF,t_70#pic_center" alt="depthwise conv2d"></p><h1 id="7-参考资料"><a href="#7-参考资料" class="headerlink" title="7.参考资料"></a>7.参考资料</h1><ul><li><a href="https://www.cnblogs.com/ysszd/p/15420492.html">Depth-wise Convolution的理解</a></li><li><a href="https://zhuanlan.zhihu.com/p/382044471">常见的卷积神经网络</a></li><li><a href="https://www.freesion.com/article/41701212751/">RESNET-18网络图示理解</a></li><li><a href="https://blog.csdn.net/Aaron_neil/article/details/121097816?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-1-121097816-blog-100013956.pc_relevant_landingrelevant&spm=1001.2101.3001.4242.2&utm_relevant_index=3">卷积 - 3. 分组卷积 详解</a></li></ul>]]></content>
<categories>
<category> 论文 </category>
</categories>
<tags>
<tag> 论文阅读笔记 </tag>
<tag> 深度学习 </tag>
<tag> 人工智能 </tag>
</tags>
</entry>
<entry>
<title>声纹识别论文阅读(四)</title>
<link href="/2022/10/21/sheng-wen-shi-bie-lun-wen-yue-du-si/"/>
<url>/2022/10/21/sheng-wen-shi-bie-lun-wen-yue-du-si/</url>
<content type="html"><![CDATA[<h1 id="1-Title"><a href="#1-Title" class="headerlink" title="1.Title"></a>1.Title</h1><p>Attentive Feature Fusion for Robust Speaker Verification</p><h1 id="2-Summary"><a href="#2-Summary" class="headerlink" title="2.Summary"></a>2.Summary</h1><p>本文提出了一种基于注意力机制的动态权重融合方法<strong>AFF</strong>,并将其应用到了ResNet上,实验结果证明了该方法的有效性。它可以在提升少部分参数量的情况下,利用注意力机制挖掘出更好的特征,从而使模型达到一个更好的效果</p><h1 id="3-Research-Objective"><a href="#3-Research-Objective" class="headerlink" title="3.Research Objective"></a>3.Research Objective</h1><p>目前大部分特征融合策略采用的是<strong>相加或拼接</strong>的方式,而两种方式都是固定且没有学习能力的(这里我的理解是作者想把特征也当成权重来进行训练),这在一定程度上缺少了特征之间的交互。因此作者在现有模型上采用新的特征,从而提升模型效果。</p><h1 id="4-Method-s"><a href="#4-Method-s" class="headerlink" title="4.Method(s)"></a>4.Method(s)</h1><p>通过注意力机制来对提取到的特征做进一步的细化,如下图:<br><img src="https://s1.ax1x.com/2022/10/24/x2YI2T.jpg" alt="attention mechanisms"><br>可以看到,左图是将特征分为C(通道)和F(频率)、T(时间)两路,仅仅对通道做了全局池化后经过一系列卷积等操作后得到注意力图。右图则是将F(频率)和T(时间)各分两路进行类似的处理,处理更为细致,后面的实验结果也表明,CA的效果要比CAM略好一些。</p><p>而后作者将AAF应用到了残差网络当中,如下图:<br><img src="https://s1.ax1x.com/2022/10/24/x2Nufx.jpg" alt="ResNet-based attentive feature fusion"><br>其中有两种不同的方式:</p><ul><li><strong>Sequential:</strong>先整体融合,进入MS-CAM/CA后再分开融合。</li><li><strong>Parallel:</strong>兵分两路进入MS-CAM/CA分开融合。</li></ul><p><strong>注意:虽然说有时序和并行两种方式,但如果看整体的话其实它们都还是一个串行结构。</strong></p><h1 id="5-Evaluation"><a href="#5-Evaluation" class="headerlink" title="5.Evaluation"></a>5.Evaluation</h1><p>本文中提出的特征融合方案包括时序AFF和并行AFF,实验中证明它们可以有效代替传统的特征融合,并且这两种方案是<strong>动态可学习的</strong>。将其应用到一些baseline上可以显著提高模型的效果,唯一美中不足的是它还会轻微地提升模型参数量。</p><h1 id="6-Conclusion"><a href="#6-Conclusion" class="headerlink" title="6.Conclusion"></a>6.Conclusion</h1><p>作者有提到在说话人验证(SV)任务中,一些论文证明了分析特征的时域和频域特征是非常有必要的,我们不应该去平等的对待它们。由此也验证了本文中CA会比CAM效果好。</p><h1 id="7-Notes"><a href="#7-Notes" class="headerlink" title="7.Notes"></a>7.Notes</h1><h2 id="7-1-x-vector"><a href="#7-1-x-vector" class="headerlink" title="7.1 x-vector"></a>7.1 x-vector</h2><p>x-vector可接受任意长度的输入,转化为固定长度的特征表达。此外,在训练中引入了包含噪声和混响在内的数据增强策略,使得模型对于噪声和混响等干扰更加具有鲁棒性。<br>x-vector包含多层帧级别的TDNN层,一个统计池化层和两层句子级别的全连接层,以及一层softmax。其模型如下图:<br><img src="https://img-blog.csdnimg.cn/img_convert/e7ce4c9a783293546d1c4ef4e60968bf.png" alt="x-vector"></p><p>其中统计池化层是将前两层TDNN的输出结果池化后拼接起来得到句子级别的特征表达。图中的a和b分别为3秒滑动窗口的均值归一化和SAD,最后再经过一个softmax来输出说话热概率。</p><p><strong>x-vector的优势:</strong></p><ul><li>参数少,便于训练,收敛速度快</li><li>抽取特征的能力强</li><li>鲁棒性更强</li></ul><h2 id="7-2-ResNet"><a href="#7-2-ResNet" class="headerlink" title="7.2 ResNet"></a>7.2 ResNet</h2><p>ResNet是在2015年由何凯明提出的一种网络,该网络具有<strong>超级深的网络层数、新提出的残差模块</strong>。</p><p>在ResNet提出之前,所有网络都是由卷积层和池化层通过不同方法叠加而成的。一般来说,一个网络越深,越能提取到更深层次的特征,学习的效果也会越来越好。但是后来人们发现,当网络层数超过一定的层数后,网络会出现<strong>梯度消失、梯度爆炸以及退化</strong>现象。<br><img src="https://img-blog.csdnimg.cn/ecb0dabb6efb4a16bc7288bbf787e1ef.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAcXFfNDU2NDkwNzY=,size_20,color_FFFFFF,t_70,g_se,x_16" alt="残差网络"></p><h2 id="7-3-MFCC与Fbank"><a href="#7-3-MFCC与Fbank" class="headerlink" title="7.3 MFCC与Fbank"></a>7.3 MFCC与Fbank</h2><p>本文中所用的初始特征为Fbank,在在语音相关的任务中最常用的特征就是MFCC和Fbank。</p><ul><li>Fbank(Fileter Bank):人耳对声音频谱的响应是非线性的,Fbank就是一种前端处理算法,以类似于人耳的方式对音频进行处理,可以提高语音识别的性能。</li><li>MFCC(Mel-frequency cepstral coefficients):梅尔频率倒谱系数。梅尔频率是基于人耳听觉特性提出来的, 它与Hz频率成非线性对应关系。梅尔频率倒谱系数(MFCC)则是利用它们之间的这种关系,计算得到的Hz频谱特征。主要用于语音数据特征提取和降低运算维度。</li></ul><h1 id="8-Reference"><a href="#8-Reference" class="headerlink" title="8.Reference"></a>8.Reference</h1><ul><li><a href="http://t.zoukankan.com/zy230530-p-13657793.html">声纹识别算法阅读之x-vector</a></li><li><a href="https://zhuanlan.zhihu.com/p/365714663">零基础入门语音识别: 一文详解MFCC特征(附python代码)</a></li><li><a href="https://blog.csdn.net/qq_45649076/article/details/120494328">ResNet详解</a></li><li><a href="https://zhuanlan.zhihu.com/p/363153781?utm_source=wechat_session&utm_medium=social&utm_oi=906835117203419136&utm_campaign=shareopn">语音识别中的MFCC 与 Fbank特征的基本原理和python实现</a></li></ul>]]></content>
<categories>
<category> 论文 </category>
</categories>
<tags>
<tag> 论文阅读笔记 </tag>
<tag> 深度学习 </tag>
<tag> 人工智能 </tag>
</tags>
</entry>
<entry>
<title>python中的不定量参数传递</title>
<link href="/2022/10/13/python-zhong-de-bu-ding-liang-can-shu-chuan-di/"/>
<url>/2022/10/13/python-zhong-de-bu-ding-liang-can-shu-chuan-di/</url>
<content type="html"><![CDATA[<p>在阅读代码的时候碰到了函数中形如*args, **kwargs, **vars(args)的参数,不是很明白。故在这里记录学习一下。</p><p>*args 和 **kwargs 主要用于函数定义。其实这里写成什么样都无所谓,但是一般*args 和 **kwargs已经是约定俗成的写法,所以为了代码规范,大家一般都这样写。函数中的这样的形参意味着你可以将<strong>不定量</strong>的参数传递给一个函数。为什么要这样做呢?因为有时候我们并不确定需要传入哪些参数,所以这需要这样的写法。</p><p>这里我们总体看一看python中参数的传递方法,<strong>重点在4和5</strong>。</p><h2 id="python中参数传递的方法"><a href="#python中参数传递的方法" class="headerlink" title="python中参数传递的方法"></a>python中参数传递的方法</h2><ol><li><p>位置传递</p><pre class=" language-python"><code class="language-python"><span class="token keyword">def</span> <span class="token function">fun</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span>b<span class="token punctuation">,</span>c<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">return</span> a<span class="token operator">+</span>b<span class="token operator">*</span>c <span class="token keyword">print</span><span class="token punctuation">(</span>f<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">#7</span> <span class="token keyword">print</span><span class="token punctuation">(</span>f<span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">#5</span></code></pre><p>这里每个实参和形参的位置严格的一一对应,一旦位置有所偏差就会造成不同的结果。</p></li><li><p>关键字传递</p><pre class=" language-python"><code class="language-python"><span class="token keyword">def</span> <span class="token function">fun</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span>b<span class="token punctuation">,</span>c<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">return</span> a<span class="token operator">+</span>b<span class="token operator">*</span>c <span class="token keyword">print</span><span class="token punctuation">(</span>f<span class="token punctuation">(</span>a<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">,</span>b<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">,</span>c<span class="token operator">=</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">#7</span> <span class="token keyword">print</span><span class="token punctuation">(</span>f<span class="token punctuation">(</span>c<span class="token operator">=</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span>a<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">#7</span></code></pre><p>关键字传递是根据每个参数的名字传递参数,并不用遵守位置的对应关系。</p></li><li><p>参数默认值</p><pre class=" language-python"><code class="language-python"><span class="token keyword">def</span> <span class="token function">fun</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span>b<span class="token punctuation">,</span>c<span class="token operator">=</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">return</span> a<span class="token operator">+</span>b<span class="token operator">*</span>c <span class="token keyword">print</span><span class="token punctuation">(</span>f<span class="token punctuation">(</span>a<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">#7</span> <span class="token keyword">print</span><span class="token punctuation">(</span>f<span class="token punctuation">(</span>a<span class="token operator">=</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span>c<span class="token operator">=</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">#21</span></code></pre><p>有时在定义函数时会提前给参数赋一个默认值,如果调用函数时给参数赋其他值会覆盖默认值,否则函数会继续使用这个默认值。</p></li></ol><p><strong>注意!!!重点要来了!!!接下来的就是对于python中不定量参数传递的解析。</strong></p><ul><li>*类似于位置传参</li><li>**类似于关键字传参</li></ul><ol start="4"><li><strong>包裹传递</strong><pre class=" language-python"><code class="language-python"> <span class="token keyword">def</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">print</span><span class="token punctuation">(</span>type<span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">print</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span> func<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">#<class 'tuple'> (1, 4, 6)</span> func<span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span><span class="token number">6</span><span class="token punctuation">,</span><span class="token number">7</span><span class="token punctuation">,</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true">#class 'tuple'> (5, 6, 7, 1, 2, 3)</span></code></pre></li></ol><p>两次调用,尽管参数个数不同,都基于同一个func定义。在func的参数表中,所有的参数被args收集,根据位置合并成一个<strong>元组</strong>,args是包裹位置传递所用的元组名,以上是包裹位置传递的例子。</p><pre class=" language-python"><code class="language-python"> <span class="token keyword">def</span> <span class="token function">func</span><span class="token punctuation">(</span><span class="token operator">**</span>kwargs <span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">print</span> <span class="token punctuation">(</span>type<span class="token punctuation">(</span>kwargs<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">print</span> <span class="token punctuation">(</span>kwargs<span class="token punctuation">)</span> fun<span class="token punctuation">(</span>a<span class="token operator">=</span><span class="token string">"2"</span><span class="token punctuation">,</span>b<span class="token operator">=</span><span class="token string">"1"</span><span class="token punctuation">,</span>c<span class="token operator">=</span><span class="token string">"11"</span><span class="token punctuation">)</span> <span class="token comment" spellcheck="true"># <class 'dict'> {'a': '2', 'b': '1', 'c': '11'}</span></code></pre><p>与上面类似,kwargs是以一个<strong>字典</strong>的形式将参数传递给函数。</p><ol start="5"><li><strong>解包裹</strong></li></ol><p>*和**同样也可以用于调用函数。</p><pre class=" language-python"><code class="language-python"><span class="token keyword">def</span> <span class="token function">func</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span>b<span class="token punctuation">,</span>c<span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword">print</span> a<span class="token punctuation">,</span>b<span class="token punctuation">,</span>c args <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">)</span>func<span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">)</span> <span class="token comment" spellcheck="true"># 1,3,4</span> dict <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token string">'a'</span><span class="token punctuation">:</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token string">'b'</span><span class="token punctuation">:</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token string">'c'</span><span class="token punctuation">:</span><span class="token number">3</span><span class="token punctuation">}</span>func<span class="token punctuation">(</span><span class="token operator">**</span>dict<span class="token punctuation">)</span> <span class="token comment" spellcheck="true"># 1,2,3</span></code></pre><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ul><li><a href="https://blog.csdn.net/yilovexing/article/details/80577510">Python3 * 和 ** 运算符</a></li><li><a href="https://blog.csdn.net/sehun_sx/article/details/123858774">Python学习,python中参数传递的方法,你知道几种</a></li></ul>]]></content>
<categories>
<category> 编程 </category>
</categories>
<tags>
<tag> python </tag>
</tags>
</entry>
<entry>
<title>声纹识别论文阅读(三)</title>
<link href="/2022/10/07/sheng-wen-shi-bie-lun-wen-yue-du-san/"/>
<url>/2022/10/07/sheng-wen-shi-bie-lun-wen-yue-du-san/</url>
<content type="html"><![CDATA[<h2 id="1-Title"><a href="#1-Title" class="headerlink" title="1.Title"></a>1.Title</h2><p>AN ATTENTION-BASED BACKEND ALLOWING EFFICIENT FINE-TUNING OF TRANSFORMER MODELS FOR SPEAKER VERIFICATION</p><h2 id="2-Summary"><a href="#2-Summary" class="headerlink" title="2.Summary"></a>2.Summary</h2><p>本篇文章我没有读完,原因是觉得后续工作对我来说没有太大的帮助。本文主要讲的是利用预训练模型来提取声纹特征,在加以微调来改善模型。其实从微调可以看出,重点还是在前面,即基于强大的预训练模型来进行下游任务。这里提到了transformer,该模型自2017年提出以来一直火到了现在,足以见得其强大之处。也正是因为读到这篇论文,让我想再去研究研究transformer,因为之前只是大概了解了一下,并没有系统学习记录下来。</p><h2 id="3-Research-Objective"><a href="#3-Research-Objective" class="headerlink" title="3.Research Objective"></a>3.Research Objective</h2><p>在自监督学习中预先训练好的模型用于说话人验证任务的微调策略尚未充分探索。</p><h2 id="4-Method-s"><a href="#4-Method-s" class="headerlink" title="4.Method(s)"></a>4.Method(s)</h2><p>在本文中,作者分析了几种建立在预先训练模型之上的特征提取方法(发现预训练模型的较低层对说话人验证更有效,而顶层则侧重于语音信息)、正则化和学习速率调度器,以稳定微调过程并进一步提高性能。</p><p>通过与一些分类器、特征提取器进行联合微调可以进一步提高性能,但是这样做会导致大规模的后端以及模型的过拟合,使训练变得相当麻烦(涉及到时间以及处理过拟合等问题)</p><p>因此有人提出了一种两阶段的微调策略:就是首先<strong>冻结预先训练好的参数,重新开始优化随机初始化的特征提取器后端,然后联合训练两个模型</strong>,这能够使训练更加的稳定。最后也能在VoxCeleb数据集上得到不错的效果。但是这样的方法同样也存在弊端,那就是它的计算成本很高,它需要预训练模型多次迭代来初始化后端,然后才能通过联合训练的方式最大限度发挥该体系的能力。</p><p>于是作者通过引入一个轻量级后端并设计适当的微调策略,研究了如何在说话人确认任务中最大限度地发挥预处理模型的能力。该后端完全基于注意力,不包含卷积层且每个帧的时间位置仅通过每个Transformer模型的固有机制进行编码(例如位置嵌入)</p><h2 id="5-Evaluation"><a href="#5-Evaluation" class="headerlink" title="5.Evaluation"></a>5.Evaluation</h2><p>后续可以考虑使用transformer作为特征提取器,虽然目前这种做法好像还是挺多的,算不上创新,不过效果应该会好一点。可以在基于这个的基础上加以改造试试。</p><h2 id="6-Conclusion"><a href="#6-Conclusion" class="headerlink" title="6.Conclusion"></a>6.Conclusion</h2><p>验证了transformer在提取说话人特征方面的强大能力。</p><h2 id="7-Notes"><a href="#7-Notes" class="headerlink" title="7.Notes"></a>7.Notes</h2><h3 id="7-1-预训练"><a href="#7-1-预训练" class="headerlink" title="7.1 预训练"></a>7.1 预训练</h3><p>在这里看到一句话很好的解释了预训练的概念:预训练就是使用大量的数据,从中提取出该类数据的<strong>共性特征</strong>,从而减轻后续模型对<strong>特定任务</strong>的的学习负担。</p><p><strong>预训练的本质</strong></p><ul><li>模型参数不再是随机初始化,而是通过一些任务进行预训练</li><li>将整体训练拆分为共性学习和特性学习两个阶段</li></ul><p>上述两句话分别从模型和数据的角度解释了预训练的本质。举一个通俗的例子,若要让一个人去学习概率论。与一个文科生相比,显然是让一个学习过高等数学和线性代数的工科生学习概率论更为容易,而学习过的高等数学和线性代数对应到这里就是预训练的结果。平常我们也是采用一些优秀的预训练模型再加以微调,从而在我们自己特定的任务上得到较好的效果。</p><h3 id="7-2-Transformer"><a href="#7-2-Transformer" class="headerlink" title="7.2 Transformer"></a>7.2 Transformer</h3><p>transformer这个模型值得单开一篇,这里附上链接:<a href="https://gaonan98.github.io/2022/10/19/qiang-da-de-transformer/">传送门</a></p><h3 id="7-3-下采样"><a href="#7-3-下采样" class="headerlink" title="7.3 下采样"></a>7.3 下采样</h3><p>文中有提到下采样这个概念,经过查询,发现与之对应的还有上采样。</p><p>用到采样的目的其实是为了均衡数据,下采样是将多的数据减少,而上采样是将少的数据增加。看资料介绍大多数时候是针对特征进行上下采样,例如我们常说的池化层有时候也称为下采样层。</p><h2 id="8-Referen"><a href="#8-Referen" class="headerlink" title="8.Referen"></a>8.Referen</h2><ul><li><a href="https://blog.csdn.net/weixin_48192256/article/details/120937144">预训练解读</a></li><li><a href="https://blog.csdn.net/Tink1995/article/details/105080033?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166588496516782427410190%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166588496516782427410190&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-105080033-null-null.142%5Ev56%5Epc_search_v3,201%5Ev3%5Econtrol_2&utm_term=Transformer&spm=1018.2226.3001.4187">史上最小白之Transformer详解</a></li><li><a href="https://blog.csdn.net/Tink1995/article/details/105012972">史上最小白之Attention详解</a></li></ul>]]></content>
<categories>
<category> 论文 </category>
</categories>
<tags>
<tag> 论文阅读笔记 </tag>
<tag> 深度学习 </tag>
<tag> 人工智能 </tag>
</tags>
</entry>
<entry>
<title>声纹识别论文阅读(二)</title>
<link href="/2022/10/05/sheng-wen-shi-bie-lun-wen-yue-du-er/"/>
<url>/2022/10/05/sheng-wen-shi-bie-lun-wen-yue-du-er/</url>
<content type="html"><![CDATA[<h2 id="1-Title"><a href="#1-Title" class="headerlink" title="1.Title"></a>1.Title</h2><p>In defence of metric learning for speaker recognition</p><h2 id="2-Summary"><a href="#2-Summary" class="headerlink" title="2.Summary"></a>2.Summary</h2><p>在本文中,作者对VoxCeleb数据集上最流行的说话人识别损失函数进行了广泛评估。感觉创新不是很够,只是任务量很足。光跑代码的时间就花了两年多一点。</p><h2 id="3-Research-Objective"><a href="#3-Research-Objective" class="headerlink" title="3.Research Objective"></a>3.Research Objective</h2><ol><li>vanilla triplet 损失函数与基于分类的损失函数相比更有竞争性。</li><li>作者提出的度量学习训练的网络优于目前最先进的方法。</li></ol><h2 id="4-Problem-Statement"><a href="#4-Problem-Statement" class="headerlink" title="4.Problem Statement"></a>4.Problem Statement</h2><p>解决对从未见过的说话人进行<strong>开放集识别</strong>,使最终的嵌入能够将信息浓缩到一个紧凑的语料级表示中,使其在相同说话人中有较小的距离,在不同说话人中有较大的距离。这也是度量学习的目标。</p><h2 id="5-Method-s"><a href="#5-Method-s" class="headerlink" title="5.Method(s)"></a>5.Method(s)</h2><p>在相同条件下比较不同损失函数的性能。</p><h2 id="6-Evaluation"><a href="#6-Evaluation" class="headerlink" title="6.Evaluation"></a>6.Evaluation</h2><p>无</p><h2 id="7-Conclusion"><a href="#7-Conclusion" class="headerlink" title="7.Conclusion"></a>7.Conclusion</h2><p>GE2E和原型网络显示出优于流行的基于分类的方法的性能。</p><h2 id="8-Notes"><a href="#8-Notes" class="headerlink" title="8.Notes"></a>8.Notes</h2><h3 id="8-1-度量学习"><a href="#8-1-度量学习" class="headerlink" title="8.1 度量学习"></a>8.1 度量学习</h3><p>度量学习又叫做相似度学习,其基本原理是根据不同的任务来自主学习出针对某个特定任务的度量距离函数。比如在一个分类任务中,当我们拿到目标的特征后,通过某种方法得到向量间的距离,通过函数进行优化,将距离小(特征相近)的目标拉近,距离大(特征不相近)的目标拉远。这就是一个度量学习的过程。</p><h3 id="8-2-损失函数"><a href="#8-2-损失函数" class="headerlink" title="8.2 损失函数"></a>8.2 损失函数</h3><p><strong>什么是损失函数?</strong></p><p>损失函数(loss function)就是用来度量模型的预测值f(x)与真实值Y的差异程度的运算函数,它是一个非负实值函数,通常使用L(Y, f(x))来表示,损失函数越小,模型的鲁棒性就越好。</p><p><strong>为什么要用损失函数?</strong></p><p>损失函数使用主要是在模型的训练阶段,每个批次的训练数据送入模型后,通过前向传播输出预测值,然后损失函数会计算出预测值和真实值之间的差异值,也就是损失值。得到损失值之后,模型通过反向传播去更新各个参数,来降低真实值与预测值之间的损失,使得模型生成的预测值往真实值方向靠拢,从而达到学习的目的。</p><p><strong>softmax</strong></p><ul><li>softmax损失函数的本质是将一个k维的任意实数向量x映射成另一个k维的实数向量,其中,输出向量中的每个元素的取值范围都是(0,1),即softmax损失函数输出每个类别的预测概率。</li><li>softmax损失函数具有类间可分性,被广泛用于分类、分割、人脸识别、图像自动标注和人脸验证等问题中,其特点是类间距离的优化效果非常好,但类内距离的优化效果比较差。因此它常与对比损失或中心损失组合使用(本文提到它常与PLDA结合使用),以增强区分能力。</li></ul><p><strong>本文中的几种损失函数</strong></p><ul><li>triplet loss:<ul><li>triplet:一个三元组,这个三元组是这样构成的:从训练数据集中随机选一个样本,该样本称为Anchor,然后再随机选取一个和Anchor (记为x_a)属于同一类的样本和不同类的样本,这两个样本对应的称为Positive (记为x_p)和Negative (记为x_n),由此构成一个三元组。<br><img src="https://s1.ax1x.com/2022/10/05/xlI2yq.jpg" alt="triplet loss"></li><li>triplet loss:针对三元组中的每个元素(样本),训练一个参数共享或者不共享的网络,得到三个元素的特征表达,分别记为:f(x_a)、f(x_p)、f(x_n)。通过学习,让x_a和x_p特征表达之间的距离尽可能小,而x_a和x_n的特征表达之间的距离尽可能大,并且要让x_a与x_n之间的距离和x_a与x_p之间的距离之间有一个最小的间隔。</li></ul></li><li>GE2E:没看太懂,尬了。<ul><li>GE2E loss包含softmax和contrast两种具体形式,每种形式的目标不仅仅是增大样本与所属说话人中心的cosine得分,同时减小样本与非所属说话人中心cosine得分。</li><li>GE2E计算consine得分时,采用相似矩阵计算形式,一次性计算所有consine得分,<strong>相比TE2T,可显著加速计算</strong></li></ul></li></ul><h2 id="9-Reference"><a href="#9-Reference" class="headerlink" title="9.Reference"></a>9.Reference</h2><ul><li><a href="https://blog.csdn.net/xiaopihaierletian/article/details/53463253">度量学习</a></li><li><a href="https://zhuanlan.zhihu.com/p/261059231">损失函数</a></li><li><a href="https://blog.csdn.net/qq_36620489/article/details/78833478">triplet loss 原理</a></li><li><a href="https://zhuanlan.zhihu.com/p/339630443">GE2E——简单高效的Speaker Verification损失函数</a></li></ul>]]></content>
<categories>
<category> 论文 </category>
</categories>
<tags>
<tag> 论文阅读笔记 </tag>
<tag> 深度学习 </tag>
<tag> 人工智能 </tag>
</tags>
</entry>
<entry>
<title>笔记模板</title>
<link href="/2022/10/03/bi-ji-mo-ban/"/>
<url>/2022/10/03/bi-ji-mo-ban/</url>
<content type="html"><![CDATA[<h1 id="1-题目"><a href="#1-题目" class="headerlink" title="1.题目"></a>1.题目</h1><p>文章标题</p><h1 id="2-总结"><a href="#2-总结" class="headerlink" title="2.总结"></a>2.总结</h1><p>写完笔记之后最后填,概述文章的内容,以后查阅笔记的时候先看这一段。</p><h1 id="3-研究动机"><a href="#3-研究动机" class="headerlink" title="3.研究动机"></a>3.研究动机</h1><p>作者的研究目标</p><h1 id="4-使用方法"><a href="#4-使用方法" class="headerlink" title="4.使用方法"></a>4.使用方法</h1><p>解决问题的方法/算法是什么?</p><h1 id="5-结论"><a href="#5-结论" class="headerlink" title="5.结论"></a>5.结论</h1><p>作者给了哪些strong conclusion, 又给了哪些weak conclusion?</p><h1 id="6-额外笔记"><a href="#6-额外笔记" class="headerlink" title="6.额外笔记"></a>6.额外笔记</h1><p>在这些框架外额外需要记录的笔记。</p><h1 id="7-参考资料"><a href="#7-参考资料" class="headerlink" title="7.参考资料"></a>7.参考资料</h1><p>参考资料</p>]]></content>
<categories>
<category> 论文 </category>
</categories>
<tags>
<tag> 论文阅读笔记 </tag>
</tags>
</entry>
<entry>
<title>声纹识别论文阅读(一)</title>
<link href="/2022/09/28/sheng-wen-shi-bie-lun-wen-yue-du-yi/"/>
<url>/2022/09/28/sheng-wen-shi-bie-lun-wen-yue-du-yi/</url>
<content type="html"><![CDATA[<h2 id="1-Title"><a href="#1-Title" class="headerlink" title="1.Title"></a>1.Title</h2><p>ECAPA-TDNN Emphasized Channel Attention, Propagation and Aggregation</p><h2 id="2-Summary"><a href="#2-Summary" class="headerlink" title="2.Summary"></a>2.Summary</h2><p>本文提出的ECAPA-TDNN是一个基于TDNN的说话人嵌入提取器,主要用于说话人验证。在原有x-vector架构的基础上,进一步加强了通道注意(使网络只关注它认为重要的帧)、特征聚集和传播的能力(利用残差连接收集浅层特征)。</p><h2 id="3-Research-Objective"><a href="#3-Research-Objective" class="headerlink" title="3.Research Objective"></a>3.Research Objective</h2><p>说话人验证</p><h2 id="4-Problem-Statement"><a href="#4-Problem-Statement" class="headerlink" title="4.Problem Statement"></a>4.Problem Statement</h2><p><strong>x-vector存在一些局限性</strong></p><p>作者在ECAPA-TDNN架构中纳入了潜在的解决方案。</p><h2 id="5-Method-s"><a href="#5-Method-s" class="headerlink" title="5.Method(s)"></a>5.Method(s)</h2><h3 id="1-Channel-and-context-dependent-statistics-pooling"><a href="#1-Channel-and-context-dependent-statistics-pooling" class="headerlink" title="1. Channel- and context-dependent statistics pooling"></a>1. Channel- and context-dependent statistics pooling</h3><p>将时间注意力机制进一步扩展到通道维度可能是有益的,这使网络能够更多地关注那些不在相同或相似的时间实例上激活的说话人特征。</p><h3 id="2-1-Dimensional-Squeeze-Excitation-Res2Blocks"><a href="#2-1-Dimensional-Squeeze-Excitation-Res2Blocks" class="headerlink" title="2. 1-Dimensional Squeeze-Excitation Res2Blocks"></a>2. 1-Dimensional Squeeze-Excitation Res2Blocks</h3><p>提出ECAPA-TDNN架构的SE-Res2Block,模型结构如下:<br><img src="https://img-blog.csdnimg.cn/f44fb22d24f946a080492c986d39bef0.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMDQ4NTcx,size_16,color_FFFFFF,t_70" alt="SE-Res2Block"><br>它能够通过在内部构建层次化的残差连接来处理<strong>多尺度特征</strong>。这个模块的整合提高了性能,同时大大减少了模型参数的数量。</p><h3 id="3-Multi-layer-feature-aggregation-and-summation"><a href="#3-Multi-layer-feature-aggregation-and-summation" class="headerlink" title="3. Multi-layer feature aggregation and summation"></a>3. Multi-layer feature aggregation and summation</h3><p>作者认为更加浅层的特征图也可以用于说话人特征的提取,所以将所有SE-Res2Block的输出特征图连接起来进行多层特征的聚合,模型结构如下:<br><img src="https://s1.ax1x.com/2022/10/03/xMXz7t.jpg" alt="拓扑结构"></p><h2 id="6-Evaluation"><a href="#6-Evaluation" class="headerlink" title="6.Evaluation"></a>6.Evaluation</h2><p>该系统采用EER和MinDCF来进行评估</p><h2 id="7-Conclusion"><a href="#7-Conclusion" class="headerlink" title="7.Conclusion"></a>7.Conclusion</h2><p>在VoxCeleb和VoxSRC 2019评估集上,EER有比baseline平均19%的相对改进。</p><h2 id="8-Notes"><a href="#8-Notes" class="headerlink" title="8.Notes"></a>8.Notes</h2><h3 id="8-1-TDNN"><a href="#8-1-TDNN" class="headerlink" title="8.1 TDNN"></a>8.1 TDNN</h3><p>TDNN相当于一维CNN,它的<strong>共享权重被限制在单一的维度上</strong>,没有池化层,适用于语音和时间序列的信号处理。</p><p><img src="https://img-blog.csdnimg.cn/20190225171328291.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzE0OTYyMTc5,size_16,color_FFFFFF,t_70" alt="TDNN"></p><p>以上为TDNN网络结构模型,其中各色线的<strong>权重相同</strong>,相当于把<strong>权重延时</strong>。隐藏层和输出层之间也可以采用该方法,这样整体的权重就大大减少。便于训练。而xvector是基于TDNN结构的,大致相似,故这里再不做过多介绍。</p><p>TDNN网络优点:</p><ul><li>网络是多层的,每层对特征有较强的抽象能力(感觉现在网络大部分层数都很深,所以觉得这也不算个优点)</li><li>能表达语音特征在时间上的关系(在送入隐藏层时根据时延大小送入多帧)</li><li>权值具有时间不变性(训练快)</li><li>学习过程中不要求对所学的标记进行精确的时间定位 !!!(不懂)</li><li>通过共享权值,方便学习</li></ul><h3 id="8-2-SE-BLOCK"><a href="#8-2-SE-BLOCK" class="headerlink" title="8.2 SE-BLOCK"></a>8.2 SE-BLOCK</h3><p><img src="https://s1.ax1x.com/2022/09/28/xe6TFe.png" alt="SE模块"></p><p>以上为SE模块的结构图,可以看到它主要分为三个部分:压缩、激励、和Scale操作。</p><ol><li>压缩:这里采用了一个平均池化,将特征的维度从W×H×C压缩到了1×1×C。H和W压缩成一维后,相当于这一维参数获得了之前H×W全局的视野,感受区域更广。</li><li>激励:这里又加入了全连接层对每个通道的重要性进行预测,得到不同channel的重要性大小后再作用到之前的feature map的对应channel上,再进行后续操作。</li><li>Scale操作:在得到1×1×C向量之后,就可以对原来的特征图进行scale操作了。很简单, <strong>就是通道权重相乘,</strong> 原有特征向量为W×H×C, <strong>将SE模块计算出来的各通道权重值分别和原特征图对应通道的二维矩阵相乘</strong> ,得出的结果输出。</li></ol><p>总结:SE模块主要为了提升模型对<strong>channel特征</strong>的敏感性,这个模块是轻量级的,而且可以应用在现有的网络结构中,只需要增加较少的计算量就可以带来性能的提升。</p><h3 id="8-3-Aggregate-and-Propagate-features"><a href="#8-3-Aggregate-and-Propagate-features" class="headerlink" title="8.3 Aggregate and Propagate features"></a>8.3 Aggregate and Propagate features</h3><ul><li>Aggregate:类似CNN中的convolution,就是用周边节点的feature更新下一层的hidden feature。对应到卷积中感觉就像是利用卷积核不断地把特征聚集到一起。</li><li><em>Propagate:暂时理解为特征经过不断处理后的层层递进。</em></li></ul><h3 id="8-4-Bottleneck-layer"><a href="#8-4-Bottleneck-layer" class="headerlink" title="8.4 Bottleneck layer"></a>8.4 Bottleneck layer</h3><p>Bottleneck layer又称之为瓶颈层,使用的是1*1的卷积神经网络。之所以称之为瓶颈层,是因为长得比较像一个瓶颈。</p><p><img src="https://s1.ax1x.com/2022/09/28/xe6Oyt.png" alt=" Bottleneck layer"></p><p>如上图所示,经过 1×1 的网络,中间那个看起来比较细。像一个瓶颈一样。使用 1×1 网络的一大好处就是可以大幅减少计算量。</p><h3 id="8-5-余弦距离"><a href="#8-5-余弦距离" class="headerlink" title="8.5 余弦距离"></a>8.5 余弦距离</h3><p>余弦距离(Cosine Distance)也可以叫余弦相似度。 几何中夹角余弦可用来衡量两个向量方向的差异,机器学习中借用这一概念来衡量样本向量之间的差异。相比距离度量,余弦相似度更加注重两个向量在方向上的差异,而非距离或长度上。<br><img src="https://pica.zhimg.com/v2-0f183692bb435c1113b620b3f01d212e_1440w.jpg?source=172ae18b" alt="余弦距离"><br>余弦取值范围为[ − 1 , 1 ] [-1,1][−1,1],求得两个向量的夹角,并得出夹角对应的余弦值,此余弦值就可以用来表示这两个向量的相似性。夹角越小,趋近于0度,余弦值越接近于1,它们的方向更加吻合,则越相似;当两个向量的方向完全相反夹角余弦取最小值-1;当余弦值为0时,两向量正交,夹角为90度。<strong>余弦相似度与向量的幅值无关,只与向量的方向相关。</strong></p><p>这里有一个疑问:<strong>余弦距离的这种比较方法和那种既比较方向又比较长度的方法有什么差异?</strong></p><h3 id="8-6-statistics-pooling-layer"><a href="#8-6-statistics-pooling-layer" class="headerlink" title="8.6 statistics pooling layer"></a>8.6 statistics pooling layer</h3><p>首先需要知道池化层(pooling layer)的作用:</p><ul><li>池化是<strong>缩小</strong>高、长方向上的空间的 <strong>运算</strong> 。池化层是具有这种功能的一个深度学习的层</li><li>对输入的特征图进行 <strong>压缩</strong> ,一方面使特征图变小,<strong>简化</strong>网络计算复杂度;一方面进行特征压缩,<strong>提取主要特征</strong></li></ul><p>而statistics pooling layer的作用也是相似的,只不过采用的中间算法略有不同。</p><h3 id="8-7-VAD(Voice-Activity-Detection)"><a href="#8-7-VAD(Voice-Activity-Detection)" class="headerlink" title="8.7 VAD(Voice Activity Detection)"></a>8.7 VAD(Voice Activity Detection)</h3><p>语音活性检测 (Voice activity detection,VAD), 也称为 speech activity detection or speech detection, 是一项用于语音处理的技术,目的是检测语音信号是否存在。</p><h3 id="8-8-空洞卷积(Dilated-Convolution)"><a href="#8-8-空洞卷积(Dilated-Convolution)" class="headerlink" title="8.8 空洞卷积(Dilated Convolution)"></a>8.8 空洞卷积(Dilated Convolution)</h3><p>Dilated Convolution(空洞卷积/膨胀卷积)是在标准的 convolution map 里注入空洞,以此来扩大感受野。空洞卷积与普通的卷积相比:除了卷积核的大小以外,还有一个扩张率(dilation rate)参数,主要用来表示膨胀的大小。在普通卷积中,可以认为它的dilated rate = 1。</p><p><strong>适用情况:在图像需要全局信息、语音文本需要较长的sequence信息依赖的问题。</strong></p><p>对比传统卷积,空洞卷积的感受野是呈指数级别的增长,例如下图对比:</p><ul><li>传统卷积</li></ul><p><img src="https://img-blog.csdnimg.cn/ff0cf2d24941478cb074eed4d910aa51.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAUG9sYXJpc19U,size_12,color_FFFFFF,t_70,g_se,x_16##pic_center" alt="传统卷积"></p><ul><li>空洞卷积<br><img src="https://img-blog.csdnimg.cn/ed54032199684d98a8f9f40af17cbb52.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBAUG9sYXJpc19U,size_12,color_FFFFFF,t_70,g_se,x_16##pic_center" alt="空洞卷积"></li></ul><p>那为什么要增大感受野呢?</p><p>感受野的定义为经过卷积后对应区域的大小,为了保证所利用的信息是全局的,不仅仅是局部信息,我们应该去增大感受野。<strong>但是这里还存在一些问题:</strong></p><ul><li>空洞卷积中间有一部分为空的,所以它一定会丢失一部分信息</li><li>需要更具处理对象尺寸大小来选择合适的dilation rate</li></ul><h3 id="8-9-BatchNormal(批正则化)"><a href="#8-9-BatchNormal(批正则化)" class="headerlink" title="8.9 BatchNormal(批正则化)"></a>8.9 BatchNormal(批正则化)</h3><ol><li>为什么要引入批正则化?</li></ol><p>因为每一批的数据的数据分布会有差别,为了能够使每一批的数据分布相同,所以才要进行批归一化。</p><ol start="2"><li>批正则化的优缺点:</li></ol><ul><li>优点:能够使得每批的数据分布一致,同时能够避免梯度消失</li><li>缺点:<ul><li>当批的大小较小时,计算得到的均值和方差不准确,使归一化的效果变差,导致模型的性能下降</li><li>当批的大小较大时,内存可能不足</li></ul></li></ul><h2 id="9-Reference"><a href="#9-Reference" class="headerlink" title="9.Reference"></a>9.Reference</h2><ul><li><a href="https://blog.csdn.net/qq_14962179/article/details/87926351%E2%80%B8">语音识别——TDNN时延神经网络</a></li><li><a href="https://blog.csdn.net/qq_42617455/article/details/108165206">SE模块详解</a></li><li><a href="https://zhuanlan.zhihu.com/p/347049194">卷积神经网络学习笔记——SENet</a></li><li><a href="https://zhuanlan.zhihu.com/p/98692254">介绍Bottleneck layer结构</a></li></ul>]]></content>
<categories>
<category> 论文 </category>
</categories>
<tags>
<tag> 论文阅读笔记 </tag>
<tag> 深度学习 </tag>
<tag> 人工智能 </tag>
</tags>
</entry>
<entry>
<title>spring学习笔记</title>
<link href="/2022/08/31/spring-xue-xi-bi-ji/"/>
<url>/2022/08/31/spring-xue-xi-bi-ji/</url>
<content type="html"><![CDATA[<h1 id="1、Spring"><a href="#1、Spring" class="headerlink" title="1、Spring"></a>1、Spring</h1><h2 id="1-1、简介"><a href="#1-1、简介" class="headerlink" title="1.1、简介"></a>1.1、简介</h2><p>Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。</p><p>官网:<a href="https://spring.io/">https://spring.io/</a></p><p><strong>maven依赖</strong></p><pre class=" language-xml"><code class="language-xml"><span class="token comment" spellcheck="true"><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-webmvc<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>5.2.0.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span><span class="token comment" spellcheck="true"><!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.springframework<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>spring-jdbc<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>5.2.0.RELEASE<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span></code></pre><h2 id="1-2、优点"><a href="#1-2、优点" class="headerlink" title="1.2、优点"></a>1.2、优点</h2><ul><li>Spring是一个开源免费的框架(容器)</li><li>Spring是一个轻量级的、非入侵式的框架</li><li><strong>控制反转(IOC)、面向切面编程(AOP) (都是重点)</strong></li><li>支持事务的处理,对框架整合的支持</li></ul><p><strong>总结:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架</strong></p><h2 id="1-3、组成"><a href="#1-3、组成" class="headerlink" title="1.3、组成"></a>1.3、组成</h2><p><img src="https://img2018.cnblogs.com/blog/1010726/201909/1010726-20190908042152777-1895820426.png" alt="七大模块"></p><p>先大概看看总体模块有哪些,具体细节可以参照<a href="https://blog.csdn.net/tiantian929/article/details/122944553">这里</a></p><h1 id="2、IOC理论推导"><a href="#2、IOC理论推导" class="headerlink" title="2、IOC理论推导"></a>2、IOC理论推导</h1><p>我们先用原来的方式写一段代码:</p><ol><li>UserDao接口</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">package</span> com<span class="token punctuation">.</span>lut<span class="token punctuation">.</span>dao<span class="token punctuation">;</span><span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">UserDao</span> <span class="token punctuation">{</span> <span class="token keyword">void</span> <span class="token function">getUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><ol><li>UserDao的实现类</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserDaoImpl</span> <span class="token keyword">implements</span> <span class="token class-name">UserDao</span><span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">getUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"默认获取用户数据"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><ol start="3"><li>UserService接口</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">UserService</span> <span class="token punctuation">{</span> <span class="token keyword">void</span> <span class="token function">getUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><ol start="4"><li>UserService的实现类</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserServiceImpl</span> <span class="token keyword">implements</span> <span class="token class-name">UserService</span><span class="token punctuation">{</span> <span class="token keyword">private</span> UserDao userDao <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UserDaoImpl</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">getUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> userDao<span class="token punctuation">.</span><span class="token function">getUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><ol start="5"><li>测试</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyTest</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">// 用户实际调用的是业务层,dao层用户不需要接触</span> UserServiceImpl userService <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">UserServiceImpl</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> userService<span class="token punctuation">.</span><span class="token function">getUser</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><p>在之前的业务中,用户的需求可能会影响我们原来的代码,因此我们需要根据用户的需求去改代码。类似上面的代码,如果修改的代码量大,修改一次的成本会十分昂贵。</p><p>使用一个set接实现,已经发生了革命性的变化!</p><pre class=" language-java"><code class="language-java"> <span class="token keyword">private</span> UserDao userDao<span class="token punctuation">;</span> <span class="token comment" spellcheck="true">// 利用set进行动态实现值的注入</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setUserDao</span><span class="token punctuation">(</span>UserDao userDao<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>userDao <span class="token operator">=</span> userDao<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre><p>service层直接调用dao层方法,由于dao层有多个实现,如果在service实现类中直接将dao实例化,则后期更换数据库则需要修改代码,而使用set方法,用户可以自己设置需要使用的dao层实现类,代码可扩展性增强,控制权交由用户来处理。</p><ul><li>之前,需要程序员去创建对象,创建何种对象的控制权在开发人员身上</li><li>使用了set注入后,程序不再有主动性,而是被动接受对象</li></ul><p>这种思想从本质上解决了问题,程序员不用再去管理、考虑对象的创建。系统耦合性大大降低,可以更加专注于业务的实现。客户需要用什么对象,自己去调用就ok。<strong>这就是IOC的原型。</strong></p><p><strong>IOC本质:所谓控制反转,本质就是获得依赖对象的方式反转了。</strong></p><p><strong>控制反转是一种通过描述并通过第三方去上产或获取特定对象的方式。在spring中实现控制反转的是IOC容器,其实现方式是依赖注入。</strong></p><h1 id="3、Hellospring"><a href="#3、Hellospring" class="headerlink" title="3、Hellospring"></a>3、Hellospring</h1><ol><li>编写实体类</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Hello</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> String str<span class="token punctuation">;</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> String <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"Hello{"</span> <span class="token operator">+</span> <span class="token string">"str='"</span> <span class="token operator">+</span> str <span class="token operator">+</span> <span class="token string">'\''</span> <span class="token operator">+</span> <span class="token string">'}'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> String <span class="token function">getStr</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> str<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setStr</span><span class="token punctuation">(</span>String str<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>str <span class="token operator">=</span> str<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><ol start="2"><li>配置文件</li></ol><pre class=" language-xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>beans</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/beans<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--使用spring创建对象,在spring中这些都称为Bean--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>hello<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.lut.pojo.Hello<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>str<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Spring<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>bean</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>beans</span><span class="token punctuation">></span></span></code></pre><ol start="3"><li>测试</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyTest</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">// 获取spring的上下文对象</span> ApplicationContext context <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ClassPathXmlApplicationContext</span><span class="token punctuation">(</span><span class="token string">"beans.xml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">// 现在所有对象都在spring中管理,要使用直接从里面取出来就可以</span> Hello hello <span class="token operator">=</span> <span class="token punctuation">(</span>Hello<span class="token punctuation">)</span> context<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token string">"hello"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>hello<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><p><strong>小结</strong></p><ul><li>Hello 对象是谁创建的? <strong>hello 对象是由Spring创建的</strong></li><li>Hello 对象的属性是怎么设置的? <strong>hello 对象的属性是由Spring容器设置的</strong></li></ul><p>这个过程就叫<strong>控制反转</strong> :</p><p>控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , <strong>对象是由Spring来创建</strong>的</p><p>反转 : 程序本身不创建对象 , 而变成<strong>被动的接收对象。</strong></p><p><strong>依赖注入 : 就是利用set方法来进行注入的。</strong></p><p><strong>IOC是一种编程思想,由主动的编程变成被动的接收</strong></p><h1 id="4、IOC创建对象的方式"><a href="#4、IOC创建对象的方式" class="headerlink" title="4、IOC创建对象的方式"></a>4、IOC创建对象的方式</h1><ol><li>默认使用无参构造创建对象</li><li>如何使用有参构造创建对象?</li></ol><p>个人更偏向第三种。。。</p><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--第一种,下标赋值--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>user<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.lut.pojo.User<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>constructor-arg</span> <span class="token attr-name">index</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>0<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>楠怪<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>bean</span><span class="token punctuation">></span></span></code></pre><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--第二种,通过类型创建--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>user<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.lut.pojo.User<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>constructor-arg</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>java.lang.String<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>nanguai<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>bean</span><span class="token punctuation">></span></span></code></pre><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--第三种,直接通过参数名来设置--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>user<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.lut.pojo.User<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>constructor-arg</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>NANGUAI<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>bean</span><span class="token punctuation">></span></span></code></pre><p><strong>总结:在配置文件加载的时候,容器中管理的所有对象就已经实例化了!</strong></p><h1 id="5、Spring配置"><a href="#5、Spring配置" class="headerlink" title="5、Spring配置"></a>5、Spring配置</h1><h2 id="5-1、别名"><a href="#5-1、别名" class="headerlink" title="5.1、别名"></a>5.1、别名</h2><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--别名设置--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>alias</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>user<span class="token punctuation">"</span></span> <span class="token attr-name">alias</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>user2<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span></code></pre><h2 id="5-2、bean的配置"><a href="#5-2、bean的配置" class="headerlink" title="5.2、bean的配置"></a>5.2、bean的配置</h2><ul><li>id:容器中Bean的唯一标识符,Spring容器对Bean的配置、管理通过该属性完成,装配Bean时根据id值获取对象。</li><li>name:Spring容器可以通过该属性对容器中的Bean进行配置和管理,name属性可以为Bean指定多个名称,每个名称之间用逗号或分号隔开。</li><li>class:指定Bean的具体实现类,使用对象所在类的全路径。</li></ul><h2 id="5-3、import"><a href="#5-3、import" class="headerlink" title="5.3、import"></a>5.3、import</h2><p>import一般用于团队开发,它可以将多个配置文件,导入合并为一个。最后使用的时候,只用最后合并的那一个就可以了。</p><h1 id="6、依赖注入"><a href="#6、依赖注入" class="headerlink" title="6、依赖注入"></a>6、依赖注入</h1><h2 id="6-1、构造器注入"><a href="#6-1、构造器注入" class="headerlink" title="6.1、构造器注入"></a>6.1、构造器注入</h2><p>这个前面已经讲过,这里就不再赘述。</p><h2 id="6-2-Set方式注入【重点】"><a href="#6-2-Set方式注入【重点】" class="headerlink" title="6.2 Set方式注入【重点】"></a>6.2 Set方式注入【重点】</h2><ul><li>依赖注入:Set注入<ul><li>依赖:bean对象的创建依赖于容器</li><li>注入:bean对象中的所有属性,由容器来注入</li></ul></li></ul><p>【环境搭建】</p><ol><li>复杂类型</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Address</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> String address<span class="token punctuation">;</span> <span class="token keyword">public</span> String <span class="token function">getAddress</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> address<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setAddress</span><span class="token punctuation">(</span>String address<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>address <span class="token operator">=</span> address<span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><ol start="2"><li>真实测试对象</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Student</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> String name<span class="token punctuation">;</span> <span class="token keyword">private</span> Address address<span class="token punctuation">;</span> <span class="token keyword">private</span> String<span class="token punctuation">[</span><span class="token punctuation">]</span> books<span class="token punctuation">;</span> <span class="token keyword">private</span> List<span class="token operator"><</span>String<span class="token operator">></span> hobbys<span class="token punctuation">;</span> <span class="token keyword">private</span> Map<span class="token operator"><</span>String<span class="token punctuation">,</span> String<span class="token operator">></span> card<span class="token punctuation">;</span> <span class="token keyword">private</span> Set<span class="token operator"><</span>String<span class="token operator">></span> games<span class="token punctuation">;</span> <span class="token keyword">private</span> String wife<span class="token punctuation">;</span> <span class="token keyword">private</span> Properties info<span class="token punctuation">;</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token comment" spellcheck="true">// 以下是get、set、toString方法</span><span class="token punctuation">}</span></code></pre><ol start="3"><li>beans.xml</li></ol><pre class=" language-xml"><code class="language-xml"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>student<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.lut.pojo.Student<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--第一种,普通值注入,value--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>楠怪<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>bean</span><span class="token punctuation">></span></span></code></pre><ol start="4"><li>测试类</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyTest</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span> ApplicationContext context <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ClassPathXmlApplicationContext</span><span class="token punctuation">(</span><span class="token string">"beans.xml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> Student student <span class="token operator">=</span> <span class="token punctuation">(</span>Student<span class="token punctuation">)</span> context<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token string">"student"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>student<span class="token punctuation">.</span><span class="token function">getAddress</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><ol start="5"><li>完善注入</li></ol><pre class=" language-xml"><code class="language-xml"><span class="token comment" spellcheck="true"><!--第二种,bean注入--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>address<span class="token punctuation">"</span></span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>address<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token comment" spellcheck="true"><!--数组--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>books<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>array</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>value</span><span class="token punctuation">></span></span>红楼梦<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>value</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>value</span><span class="token punctuation">></span></span>西游记<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>value</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>value</span><span class="token punctuation">></span></span>水浒传<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>value</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>value</span><span class="token punctuation">></span></span>三国演义<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>value</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>array</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>property</span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--list--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>hobbys<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>list</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>value</span><span class="token punctuation">></span></span>唱<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>value</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>value</span><span class="token punctuation">></span></span>跳<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>value</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>value</span><span class="token punctuation">></span></span>rap<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>value</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>value</span><span class="token punctuation">></span></span>篮球<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>value</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>list</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>property</span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--Map--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>card<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>map</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>entry</span> <span class="token attr-name">key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>身份证<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>1243234<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>entry</span> <span class="token attr-name">key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>银行卡<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>3435343<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>map</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>property</span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--Set--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>games<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>set</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>value</span><span class="token punctuation">></span></span>LOL<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>value</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>value</span><span class="token punctuation">></span></span>COC<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>value</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>set</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>property</span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--null--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>wife<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>null</span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>property</span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--Properties--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>info<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>props</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>prop</span> <span class="token attr-name">key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>学号<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>17424334<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>prop</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>prop</span> <span class="token attr-name">key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>性别<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>男<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>prop</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>prop</span> <span class="token attr-name">key</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>姓名<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>小明<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>prop</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>props</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>property</span><span class="token punctuation">></span></span></code></pre><h2 id="6-3、其他方式"><a href="#6-3、其他方式" class="headerlink" title="6.3、其他方式"></a>6.3、其他方式</h2><p>采用p命名和c命名,简化了property和constructor-arg的赋值。在使用之前需要进行配置:</p><pre class=" language-xml"><code class="language-xml">p命名xmlns:p="http://www.springframework.org/schema/pc命名xmlns:c="http://www.springframework.org/schema/c</code></pre><p>使用:</p><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--p命名空间注入,可以直接注入属性的值:propertiy--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>user<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.lut.pojo.User<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">p:</span>age</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>24<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">p:</span>name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>楠怪<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token comment" spellcheck="true"><!--c命名空间注入,通过构造器注入:construct-args--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>bean</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>user2<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.lut.pojo.User<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">c:</span>age</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>18<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">c:</span>name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>nanguai<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span></code></pre><h2 id="6-4、bean的作用域"><a href="#6-4、bean的作用域" class="headerlink" title="6.4、bean的作用域"></a>6.4、bean的作用域</h2><table><thead><tr><th align="center">作用域</th><th align="center">描述</th></tr></thead><tbody><tr><td align="center">singleton</td><td align="center">在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,bean作用域范围的默认值。</td></tr><tr><td align="center">prototype</td><td align="center">每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()。</td></tr><tr><td align="center">request</td><td align="center">每次HTTP请求都会创建一个新的Bean,该作用域仅适用于web的Spring WebApplicationContext环境。</td></tr><tr><td align="center">session</td><td align="center">同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境。</td></tr></tbody></table><h1 id="7、Bean的自动装配"><a href="#7、Bean的自动装配" class="headerlink" title="7、Bean的自动装配"></a>7、Bean的自动装配</h1><ul><li>自动装配是Spring满足bean依赖的一种方式</li><li>Spring会在上下文中自动寻找,并自动给bean配置属性</li></ul><p>在spring种有三种装配方式:</p><ol><li>在xml中显示装配</li></ol><p>这里有篇博客举了很容易理解的例子,可以来看一下,<a href="https://blog.csdn.net/qq_38969734/article/details/123947285?ops_request_misc=&request_id=&biz_id=102&utm_term=%E8%87%AA%E5%8A%A8%E8%A3%85%E9%85%8Dbean&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-3-123947285.nonecase&spm=1018.2226.3001.4187">传送门</a></p><ol start="2"><li>在Java中显示装配</li><li><strong>隐式自动装配bean</strong></li></ol><h2 id="7-1、注解实现自动装配"><a href="#7-1、注解实现自动装配" class="headerlink" title="7.1、注解实现自动装配"></a>7.1、注解实现自动装配</h2><p><strong>自动装配所用注解</strong><br><img src="https://img-blog.csdnimg.cn/img_convert/eab4752496991d194e94f03d3d698fec.png" alt="自动装配所用注解"></p><p>使用注解须知:</p><ol><li>导入约束,context约束</li><li>配置注解支持:</li></ol><pre class=" language-xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8"?></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>beans</span> <span class="token attr-name">xmlns</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/beans<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>xsi</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>http://www.w3.org/2001/XMLSchema-instance<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>context</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/context<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xsi:</span>schemaLocation</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--开启注解的支持--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span><span class="token namespace">context:</span>annotation-config</span><span class="token punctuation">/></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>beans</span><span class="token punctuation">></span></span></code></pre><ol start="3"><li><strong>@Autowired</strong>直接在属性上使用即可。(也可以在set方法上使用)</li><li>使用Autowired可以不用编写set方法,前提是自动装配的属性在IOC容中存在,且符合名字byName</li><li>如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解@Autowired完成的时候,我们可以使用@Qualifier(value = “xxx”)去配置自动装配,指定一个唯一的bean对象注入。</li></ol><pre class=" language-java"><code class="language-java"> <span class="token annotation punctuation">@Autowired</span> <span class="token annotation punctuation">@Qualifier</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"dog222"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> Dog dog<span class="token punctuation">;</span></code></pre><ol start="6"><li>@Resource注解</li></ol><pre class=" language-java"><code class="language-java"> <span class="token annotation punctuation">@Resource</span><span class="token punctuation">(</span>name <span class="token operator">=</span> <span class="token string">"dog222"</span><span class="token punctuation">)</span> <span class="token keyword">private</span> Dog dog<span class="token punctuation">;</span></code></pre><p><strong>@Autowired 与@Resource的区别:</strong></p><ul><li>@Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。</li><li>@Autowired默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用。</li><li>@Resource默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。</li></ul><h1 id="8、使用注解开发"><a href="#8、使用注解开发" class="headerlink" title="8、使用注解开发"></a>8、使用注解开发</h1><p>学习之后发现使用配置文件和注解开发都各有好处,但是如果项目比较大比较复杂,还是建议去使用配置文件开发。这里把spring的一部分注解贴出来,需要的时候再去看,<a href="https://blog.csdn.net/MobiusStrip/article/details/110211808?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166210659816782417071731%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166210659816782417071731&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-2-110211808-null-null.142%5Ev44%5Epc_ran_alice&utm_term=spring%E6%B3%A8%E8%A7%A3%E5%BC%80%E5%8F%91&spm=1018.2226.3001.4187">传送门</a></p><h1 id="9、代理模式"><a href="#9、代理模式" class="headerlink" title="9、代理模式"></a>9、代理模式</h1><p>代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。</p><p>优点:</p><p>(1)职责清晰<br>真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。</p><p>(2)代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。</p><p>(3)高扩展性</p><p>缺点:</p><ul><li>一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率变低。</li></ul><h1 id="9-1、静态代理"><a href="#9-1、静态代理" class="headerlink" title="9.1、静态代理"></a>9.1、静态代理</h1><p>角色分析:</p><ul><li>抽象角色:一般使用抽象类或者接口</li><li>真实角色:被代理的角色</li><li>代理角色:代理真实角色,代理后我们一般还会做些附属操作</li><li>客户:访问代理角色的人</li></ul><p>代码步骤:</p><ol><li>接口</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">Rent</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">rent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><ol start="2"><li>真实角色</li></ol><pre class=" language-java"><code class="language-java"><span class="token comment" spellcheck="true">// 房东</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Host</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">rent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"房东租房"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><ol start="3"><li>代理角色</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Proxy</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> Host host<span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token function">Proxy</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">Proxy</span><span class="token punctuation">(</span>Host host<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>host <span class="token operator">=</span> host<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">rent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token function">seeHouse</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> host<span class="token punctuation">.</span><span class="token function">rent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">fare</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token function">hetong</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment" spellcheck="true">// 看房</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">seeHouse</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"看房子"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment" spellcheck="true">// 收中介费</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">fare</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"收中介费"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment" spellcheck="true">// 签合同</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">hetong</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"签合同"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><ol start="4"><li>客户端访问代理角色</li></ol><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Client</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span>String<span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span> Host host <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Host</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">// 代理</span> Proxy proxy <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Proxy</span><span class="token punctuation">(</span>host<span class="token punctuation">)</span><span class="token punctuation">;</span> proxy<span class="token punctuation">.</span><span class="token function">rent</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><h2 id="9-2、动态代理"><a href="#9-2、动态代理" class="headerlink" title="9.2、动态代理"></a>9.2、动态代理</h2><p>下面链接当中的图示感觉非常的明确,自我理解动态代理就是代理类和实现类都会去实现接口,而程序的运行则是通过代理类调用实现类进行。第一眼看上去好像是写了很多重复的代码、做了许多无用的工作。代理类好像和实现类并没有什么区别,但是其实如果秉承着不要改动源码的精神,后续的改动可以在代理类中实现,而不用去修改实现类,很好的隐藏和保护了实现类,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性。</p><ul><li>动态代理和静态代理角色一样</li><li>动态代理的代理类是动态生成的</li><li>动态代理分为两大类<ul><li>基于接口:JDK动态代理</li><li>基于类:cglib</li><li>Java字节码实现:javasist</li></ul></li></ul><p>详细资料:<a href="https://blog.csdn.net/jiankunking/article/details/52143504?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166242916816780357235352%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166242916816780357235352&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-52143504-null-null.142%5Ev46%5Epc_ran_alice&utm_term=Java%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86&spm=1018.2226.3001.4187">Java JDK 动态代理(AOP)使用及实现原理分析</a></p><h1 id="10、AOP"><a href="#10、AOP" class="headerlink" title="10、AOP"></a>10、AOP</h1><h2 id="10-1、什么是AOP"><a href="#10-1、什么是AOP" class="headerlink" title="10.1、什么是AOP"></a>10.1、什么是AOP</h2><p>在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。</p><h2 id="10-2、Spring在AOP中的作用"><a href="#10-2、Spring在AOP中的作用" class="headerlink" title="10.2、Spring在AOP中的作用"></a>10.2、Spring在AOP中的作用</h2><p><strong>提供声明事务,允许用户自定义切面</strong></p><ul><li>横切关注点:跨越引用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但我们需要关注的部分,就是横切关注点,如日志,安全,缓存,事务等。</li><li>切面:横切:关注点被关注点模块化的特殊对象,即,它是一个类。</li><li>通知:切面必须要完成的工作,即,它是类中的一个方法。</li><li>目标:被通知对象。</li><li>代理:向目标对象对应通知之后创建的对象。</li><li>切入点:切面通知执行的“地点”的定义。</li><li>连接点:与切入点匹配的执行点。</li></ul><h2 id="10-3、使用Sprig实现AOP"><a href="#10-3、使用Sprig实现AOP" class="headerlink" title="10.3、使用Sprig实现AOP"></a>10.3、使用Sprig实现AOP</h2><p>【依赖包】</p><pre class=" language-xml"><code class="language-xml"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.aspectj<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>aspectjweaver<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>1.9.4<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>scope</span><span class="token punctuation">></span></span>runtime<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>scope</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span></code></pre><p>方式一:使用Spring的API接口</p><p>方式二:自定义类实现</p><p>方式三:使用注解实现</p><h1 id="11、声明式事务"><a href="#11、声明式事务" class="headerlink" title="11、声明式事务"></a>11、声明式事务</h1><h2 id="11-1、事务"><a href="#11-1、事务" class="headerlink" title="11.1、事务"></a>11.1、事务</h2><ul><li>把一组业务当作一个业务来做:要么都成功,要么都失败</li><li>确保完整性和一致性</li></ul><p>事务ACID原则:</p><ul><li>原子性</li><li>一致性</li><li>隔离性<ul><li>多个业务可能操作同一个资源,防止数据损坏</li></ul></li><li>持久性<ul><li>事务一旦提交,无论系统发生什么问题,结果都不会再被影响,被持久化的写到存储器中</li></ul></li></ul><h2 id="11-2、Spring"><a href="#11-2、Spring" class="headerlink" title="11.2、Spring"></a>11.2、Spring</h2><ul><li>声明式事务:AOP</li><li>编程式事务:在代码中进行事务的管理</li></ul><p>思考:</p><p>为什么需要事务?</p><p><strong>如果不配置事务,可能会存在数据提交不一致</strong></p>]]></content>
<categories>
<category> 编程 </category>
</categories>
<tags>
<tag> Java </tag>
<tag> spring </tag>
</tags>
</entry>
<entry>
<title>mybatis学习笔记</title>
<link href="/2022/08/20/mybatis-xue-xi-bi-ji/"/>
<url>/2022/08/20/mybatis-xue-xi-bi-ji/</url>
<content type="html"><![CDATA[<h1 id="1、简介"><a href="#1、简介" class="headerlink" title="1、简介"></a>1、简介</h1><h2 id="1-1、什么是mybatis"><a href="#1-1、什么是mybatis" class="headerlink" title="1.1、什么是mybatis"></a>1.1、什么是mybatis</h2><p><img src="https://s1.ax1x.com/2022/08/20/vsfkGT.png" alt="mybatis的标志"></p><ul><li>MyBatis 是一款优秀的<strong>持久层框架</strong>。</li><li>它支持自定义 SQL、存储过程以及高级映射。</li><li>MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。</li><li>MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。</li></ul><p>获取地址及文档</p><ul><li>maven仓库:</li></ul><pre class=" language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.mybatis<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>mybatis<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>x.x.x<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span></code></pre><ul><li>GitHub:<a href="https://github.com/mybatis/mybatis-3">https://github.com/mybatis/mybatis-3</a></li><li>中文文档:<a href="https://mybatis.org/mybatis-3/zh/index.html">https://mybatis.org/mybatis-3/zh/index.html</a></li></ul><h2 id="1-2、持久化"><a href="#1-2、持久化" class="headerlink" title="1.2、持久化"></a>1.2、持久化</h2><p>数据持久化</p><ul><li>持久化就是将程序的数据在持久状态和瞬时状态转化的过程。</li><li>内存:<strong>断电即失</strong>。</li><li>目前数据持久化的方法有:数据库(jdbc)和io文件持久化。</li></ul><p><strong>那么为撒子需要持久化呢?</strong></p><ul><li>有一些东西值得永久的保存下来,你懂的。</li><li>内存太贵。</li></ul><h2 id="1-3、持久层"><a href="#1-3、持久层" class="headerlink" title="1.3、持久层"></a>1.3、持久层</h2><ul><li>完成持久化工作的代码块。</li><li>层界限明显。</li></ul><h2 id="1-3、为什么用mybatis?"><a href="#1-3、为什么用mybatis?" class="headerlink" title="1.3、为什么用mybatis?"></a>1.3、为什么用mybatis?</h2><ul><li><strong>不要问,问就是方便!!!</strong></li><li>优点:<ul><li>简单易学</li><li>灵活</li><li>sql和代码的分离,提高了可维护性</li><li>提供映射标签,支持对象与数据库的ORM字段关系映射</li><li>提供对象关系映射标签,支持对象关系组建维护</li><li>提供xml标签,支持编写动态sql</li></ul></li></ul><h1 id="2、第一个mybatis程序"><a href="#2、第一个mybatis程序" class="headerlink" title="2、第一个mybatis程序"></a>2、第一个mybatis程序</h1><p>大致过程如下:</p><p>搭建环境–>导入mybatis–>编写代码–>测试</p><h2 id="2-1、搭建环境"><a href="#2-1、搭建环境" class="headerlink" title="2.1、搭建环境"></a>2.1、搭建环境</h2><p>搭建数据库</p><pre class=" language-sql"><code class="language-sql"><span class="token keyword">create</span> <span class="token keyword">table</span> <span class="token keyword">user</span><span class="token punctuation">(</span> id <span class="token keyword">int</span> <span class="token keyword">auto_increment</span> <span class="token keyword">primary</span> <span class="token keyword">key</span><span class="token punctuation">,</span> name <span class="token keyword">varchar</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span> <span class="token boolean">null</span><span class="token punctuation">,</span> pwd <span class="token keyword">varchar</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span> <span class="token boolean">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">insert</span> <span class="token keyword">into</span> <span class="token keyword">user</span> <span class="token punctuation">(</span>id<span class="token punctuation">,</span> name<span class="token punctuation">,</span> pwd<span class="token punctuation">)</span> <span class="token keyword">values</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token string">'张三'</span><span class="token punctuation">,</span><span class="token number">1234</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token string">'李四'</span><span class="token punctuation">,</span><span class="token number">4356</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token string">'王麻子'</span><span class="token punctuation">,</span><span class="token number">3234</span><span class="token punctuation">)</span></code></pre><p>新建项目</p><p>1.新建一个maven项目</p><p>2.删除src目录</p><p>3.导入maven依赖</p><pre class=" language-xml"><code class="language-xml"><span class="token comment" spellcheck="true"><!--导入依赖--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependencies</span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--mysql驱动--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>mysql<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>mysql-connector-java<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>5.1.46<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--mybatis--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.mybatis<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>mybatis<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>3.5.2<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--junit--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>junit<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>junit<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>4.12<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>scope</span><span class="token punctuation">></span></span>test<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>scope</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependencies</span><span class="token punctuation">></span></span></code></pre><h2 id="2-2创建模块"><a href="#2-2创建模块" class="headerlink" title="2.2创建模块"></a>2.2创建模块</h2><ul><li>编写mybatis的核心配置文件</li></ul><pre class=" language-xml"><code class="language-xml"><span class="token prolog"><?xml version="1.0" encoding="UTF-8" ?></span><span class="token doctype"><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"></span><span class="token comment" spellcheck="true"><!--核心配置文件--></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>configuration</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>environments</span> <span class="token attr-name">default</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>development<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>environment</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>development<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>transactionManager</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>JDBC<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dataSource</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>POOLED<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>driver<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.mysql.jdbc.Driver<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>url<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>jdbc:mysql://localhost:3306/mybatis?useSSL<span class="token punctuation">=</span>false&useUnicode<span class="token punctuation">=</span>true&characterEncoding<span class="token punctuation">=</span>UTF-8<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>username<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>root<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>property</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>password<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>123456<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dataSource</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>environment</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>environments</span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--每一个mapper.xml都需要在核心配置文件中注册!!!--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>mappers</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>mapper</span> <span class="token attr-name">resource</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com/lut/dao/UserMapper.xml<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>mappers</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>configuration</span><span class="token punctuation">></span></span></code></pre><ul><li>编写mybatis工具类</li></ul><pre class=" language-java"><code class="language-java"><span class="token keyword">package</span> com<span class="token punctuation">.</span>lut<span class="token punctuation">.</span>utils<span class="token punctuation">;</span><span class="token keyword">import</span> org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>ibatis<span class="token punctuation">.</span>io<span class="token punctuation">.</span>Resources<span class="token punctuation">;</span><span class="token keyword">import</span> org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>ibatis<span class="token punctuation">.</span>session<span class="token punctuation">.</span>SqlSession<span class="token punctuation">;</span><span class="token keyword">import</span> org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>ibatis<span class="token punctuation">.</span>session<span class="token punctuation">.</span>SqlSessionFactory<span class="token punctuation">;</span><span class="token keyword">import</span> org<span class="token punctuation">.</span>apache<span class="token punctuation">.</span>ibatis<span class="token punctuation">.</span>session<span class="token punctuation">.</span>SqlSessionFactoryBuilder<span class="token punctuation">;</span><span class="token keyword">import</span> java<span class="token punctuation">.</span>io<span class="token punctuation">.</span>IOException<span class="token punctuation">;</span><span class="token keyword">import</span> java<span class="token punctuation">.</span>io<span class="token punctuation">.</span>InputStream<span class="token punctuation">;</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MybatisUtils</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">static</span> SqlSessionFactory sqlSessionFactory<span class="token punctuation">;</span> <span class="token keyword">static</span> <span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token comment" spellcheck="true">// 使用mybatis第一步:获取SqlSessionFactory对象</span> String resource <span class="token operator">=</span> <span class="token string">"mybatis-config.xml"</span><span class="token punctuation">;</span> InputStream inputStream <span class="token operator">=</span> Resources<span class="token punctuation">.</span><span class="token function">getResourceAsStream</span><span class="token punctuation">(</span>resource<span class="token punctuation">)</span><span class="token punctuation">;</span> sqlSessionFactory <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SqlSessionFactoryBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span>inputStream<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">IOException</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span> e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment" spellcheck="true">// 既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例</span> <span class="token comment" spellcheck="true">// SqlSession 提供了在数据库执行 SQL 命令所需的所有方法</span> <span class="token keyword">public</span> <span class="token keyword">static</span> SqlSession <span class="token function">getSqlSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">return</span> sqlSessionFactory<span class="token punctuation">.</span><span class="token function">openSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><h2 id="2-3、编写代码"><a href="#2-3、编写代码" class="headerlink" title="2.3、编写代码"></a>2.3、编写代码</h2><ul><li>实体类</li></ul><pre class=" language-java"><code class="language-java"><span class="token keyword">package</span> com<span class="token punctuation">.</span>lut<span class="token punctuation">.</span>pojo<span class="token punctuation">;</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">int</span> id<span class="token punctuation">;</span> <span class="token keyword">private</span> String name<span class="token punctuation">;</span> <span class="token keyword">private</span> String pwd<span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token function">User</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token function">User</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">,</span> String name<span class="token punctuation">,</span> String pwd<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>id <span class="token operator">=</span> id<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token keyword">this</span><span class="token punctuation">.</span>pwd <span class="token operator">=</span> pwd<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getId</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> id<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setId</span><span class="token punctuation">(</span><span class="token keyword">int</span> id<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>id <span class="token operator">=</span> id<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> String <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setName</span><span class="token punctuation">(</span>String name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> String <span class="token function">getPwd</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> pwd<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setPwd</span><span class="token punctuation">(</span>String pwd<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span><span class="token punctuation">.</span>pwd <span class="token operator">=</span> pwd<span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token annotation punctuation">@Override</span> <span class="token keyword">public</span> String <span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"User{"</span> <span class="token operator">+</span> <span class="token string">"id="</span> <span class="token operator">+</span> id <span class="token operator">+</span> <span class="token string">", name='"</span> <span class="token operator">+</span> name <span class="token operator">+</span> <span class="token string">'\''</span> <span class="token operator">+</span> <span class="token string">", pwd='"</span> <span class="token operator">+</span> pwd <span class="token operator">+</span> <span class="token string">'\''</span> <span class="token operator">+</span> <span class="token string">'}'</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">}</span></code></pre><ul><li>Mapper接口</li></ul><pre class=" language-java"><code class="language-java"><span class="token keyword">package</span> com<span class="token punctuation">.</span>lut<span class="token punctuation">.</span>mapper<span class="token punctuation">;</span><span class="token keyword">import</span> com<span class="token punctuation">.</span>lut<span class="token punctuation">.</span>pojo<span class="token punctuation">.</span>User<span class="token punctuation">;</span><span class="token keyword">import</span> java<span class="token punctuation">.</span>util<span class="token punctuation">.</span>List<span class="token punctuation">;</span><span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">UserMapper</span> <span class="token punctuation">{</span> List<span class="token operator"><</span>User<span class="token operator">></span> <span class="token function">getUserList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><ul><li>接口实现类(mapper配置文件)</li></ul><pre class=" language-java"><code class="language-java"><span class="token operator"><</span><span class="token operator">?</span>xml version<span class="token operator">=</span><span class="token string">"1.0"</span> encoding<span class="token operator">=</span><span class="token string">"UTF-8"</span> <span class="token operator">?</span><span class="token operator">></span><span class="token operator"><</span><span class="token operator">!</span>DOCTYPE mapper PUBLIC <span class="token string">"-//mybatis.org//DTD Mapper 3.0//EN"</span> <span class="token string">"http://mybatis.org/dtd/mybatis-3-mapper.dtd"</span><span class="token operator">></span><span class="token operator"><</span><span class="token operator">!</span><span class="token operator">--</span>namespace绑定一个dao<span class="token operator">/</span>mapper接口<span class="token operator">--</span><span class="token operator">></span><span class="token operator"><</span>mapper namespace<span class="token operator">=</span><span class="token string">"com.lut.dao.UserDao"</span><span class="token operator">></span> <span class="token operator"><</span><span class="token operator">!</span><span class="token operator">--</span>sql语句<span class="token operator">--</span><span class="token operator">></span> <span class="token operator"><</span>select id<span class="token operator">=</span><span class="token string">"getUserList"</span> resultType<span class="token operator">=</span><span class="token string">"com.lut.pojo.User"</span><span class="token operator">></span> select <span class="token operator">*</span> from mybatis<span class="token punctuation">.</span>user <span class="token operator"><</span><span class="token operator">/</span>select<span class="token operator">></span><span class="token operator"><</span><span class="token operator">/</span>mapper<span class="token operator">></span></code></pre><h2 id="2-4测试"><a href="#2-4测试" class="headerlink" title="2.4测试"></a>2.4测试</h2><ul><li>junit测试</li></ul><pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Test</span> <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token comment" spellcheck="true">// 第一步:获取SqlSession对象</span> SqlSession sqlSession <span class="token operator">=</span> MybatisUtils<span class="token punctuation">.</span><span class="token function">getSqlSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">// 第二步:执行SQL</span> UserMapper userMapper <span class="token operator">=</span> sqlSession<span class="token punctuation">.</span><span class="token function">getMapper</span><span class="token punctuation">(</span>UserMapper<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span> List<span class="token operator"><</span>User<span class="token operator">></span> userList <span class="token operator">=</span> userDao<span class="token punctuation">.</span><span class="token function">getUserList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>User user <span class="token operator">:</span> userList<span class="token punctuation">)</span> <span class="token punctuation">{</span> System<span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment" spellcheck="true">// 关闭SqlSession</span> sqlSession<span class="token punctuation">.</span><span class="token function">close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre><h1 id="3、小结"><a href="#3、小结" class="headerlink" title="3、小结"></a>3、小结</h1><p>现在来总结一下mybatis的大致使用流程:</p><ol><li><p>利用maven搭建好mybatis环境,导入需要用到的依赖。</p></li><li><p>配置mybatis的核心配置文件,该文件主要是用来获取数据库连接实例的数据源以及决定事务作用域和控制方式的事务管理器。(目前只理解前半部分。。。)这这里需要注意mysql的版本,由版本的不同会导致mysql驱动的不同。</p><ol><li>mysql 8.0以下版本驱动:<strong>com.mysql.jdbc.Driver</strong></li><li>mysql 8.0及以上版本驱动:<strong>com.mysql.cj.jdbc.Driver</strong></li></ol></li><li><p>编写工具类,封装获取SqlSession实例的一系列步骤。(<strong>SqlSession 提供了在数据库执行 SQL 命令所需的所有方法</strong>)</p></li><li><p>编写代码。首先是实体类的编写,对照着数据库中的数据来编写。然后是mapper接口类的编写,将需要用到的功能函数写在该接口类中。最后由mapper配置文件(相当于一个接口库实现类)来实现这些功能,这样做到了Java和sql语言的分离。</p></li><li><p>最后在使用junit来测试即可。</p></li></ol><p><strong>注意:</strong></p><ul><li>在进行增、删、改的操作时还需要在sqlSession关闭前进行提交。</li></ul><h1 id="4、配置解析"><a href="#4、配置解析" class="headerlink" title="4、配置解析"></a>4、配置解析</h1><h2 id="4-1、核心配置文件"><a href="#4-1、核心配置文件" class="headerlink" title="4.1、核心配置文件"></a>4.1、核心配置文件</h2><ul><li>mybatis-config</li><li>MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。</li></ul><pre class=" language-xml"><code class="language-xml">configuration(配置)properties(属性)settings(设置)typeAliases(类型别名)typeHandlers(类型处理器)objectFactory(对象工厂)plugins(插件)environments(环境配置)environment(环境变量)transactionManager(事务管理器)dataSource(数据源)databaseIdProvider(数据库厂商标识)mappers(映射器)</code></pre><h2 id="4-2、环境配置(environments)"><a href="#4-2、环境配置(environments)" class="headerlink" title="4.2、环境配置(environments)"></a>4.2、环境配置(environments)</h2><p>MyBatis 可以配置成适应多种环境</p><p><strong>不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。</strong></p><p>需要学会的是配置多套运行环境。</p><p>MyBatis默认的事务管理器就是JDBC,默认的连接池是POOLED。</p><h2 id="4-3、属性(properties)"><a href="#4-3、属性(properties)" class="headerlink" title="4.3、属性(properties)"></a>4.3、属性(properties)</h2><p>我们可以通过properties属性来实现引用配置文件。这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素(db. properties)的子元素中设置。</p><p>db.properties</p><pre class=" language-properties"><code class="language-properties"><span class="token attr-name">driver</span><span class="token punctuation">=</span><span class="token attr-value">com.mysql.jdbc.Driver</span><span class="token attr-name">url</span><span class="token punctuation">=</span><span class="token attr-value">jdbc:mysql://localhost:3306/mybatis?useSSL=false&;useUnicode=true&;characterEncoding=UTF-8</span><span class="token attr-name">username</span><span class="token punctuation">=</span><span class="token attr-value">root</span><span class="token attr-name">password</span><span class="token punctuation">=</span><span class="token attr-value">123456</span></code></pre><p><strong>注意!</strong><br><img src="https://s1.ax1x.com/2022/08/21/vycA58.md.png" alt="核心配置文件属性书写顺序"></p><p>编写一个配置文件,并在核心配置文件中引入。</p><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--引入外部配置文件--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>properties</span> <span class="token attr-name">resource</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>db.properties<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span></code></pre><ul><li>可以直接引入外部配置文件(推荐)</li><li>还可以在其中增加一些属性配置</li><li>若两个文件使用同一个字段,则优先使用外部配置文件</li></ul><h2 id="4-4、类型别名(typeAliases)"><a href="#4-4、类型别名(typeAliases)" class="headerlink" title="4.4、类型别名(typeAliases)"></a>4.4、类型别名(typeAliases)</h2><ul><li>类型别名可为 Java 类型设置一个缩写名字。</li><li>它仅用于 XML 配置,意在降低冗余的全限定类名书写。</li></ul><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--给实体类起别名--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>typeAliases</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>typeAlias</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.lut.pojo.User<span class="token punctuation">"</span></span> <span class="token attr-name">alias</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>User<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>typeAliases</span><span class="token punctuation">></span></span></code></pre><p>也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:</p><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--给实体类起别名--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>typeAliases</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>package</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.lut.pojo<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>typeAliases</span><span class="token punctuation">></span></span></code></pre><p>且它的默认别名就会变为这个类的类名,<strong>且首字母小写。</strong></p><p>在实体类比较少的时候可以使用第一种方式,在实体类较多的情况下建议采用第二种方式!</p><h2 id="4-5、设置(settings)"><a href="#4-5、设置(settings)" class="headerlink" title="4.5、设置(settings)"></a>4.5、设置(settings)</h2><p>这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。<br>这里我们先来看一个,其他的暂时用不到,等用到了再去查。<br><img src="https://s1.ax1x.com/2022/08/22/v6QLmn.png" alt="日志"></p><h2 id="4-6映射器(mappers)"><a href="#4-6映射器(mappers)" class="headerlink" title="4.6映射器(mappers)"></a>4.6映射器(mappers)</h2><p>方法一:</p><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!-- 使用相对于类路径的资源引用 --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>mappers</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>mapper</span> <span class="token attr-name">resource</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com/lut/dao/UserMapper.xml<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>mappers</span><span class="token punctuation">></span></span></code></pre><p>方法二:</p><pre class=" language-xml"><code class="language-xml"><span class="token comment" spellcheck="true"><!-- 使用映射器接口实现类的完全限定类名 --></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>mappers</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>mapper</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.lut.dao.UserMapper<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>mappers</span><span class="token punctuation">></span></span></code></pre><p>方法三:</p><pre class=" language-xml"><code class="language-xml"><span class="token comment" spellcheck="true"><!-- 将包内的映射器接口实现全部注册为映射器 --></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>mappers</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>package</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.lut.dao<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>mappers</span><span class="token punctuation">></span></span></code></pre><h1 id="5、作用域(Scope)和生命周期"><a href="#5、作用域(Scope)和生命周期" class="headerlink" title="5、作用域(Scope)和生命周期"></a>5、作用域(Scope)和生命周期</h1><p><strong>以下只是部分资料,但是还不是很懂。。。</strong></p><p>不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的<strong>并发问题</strong>。</p><p><strong>SqlSessionFactoryBuilder:</strong></p><ul><li>一旦创建了 SqlSessionFactory,就不再需要它了</li><li>局部变量</li></ul><p><strong>SqlSessionFactory:</strong></p><ul><li>类似与数据库连接池</li><li>一旦被创建就应该在应用的运行期间一直存在,<strong>没有任何理由丢弃它或重新创建另一个实例</strong></li><li>SqlSessionFactory 的最佳作用域是应用作用域</li><li>最简单的就是使用单例模式或者静态单例模式</li></ul><p><strong>SqlSession:</strong></p><ul><li>连接到连接池的请求</li><li>SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域</li><li>用完之后需要关闭,否则会占用资源</li></ul><h1 id="6、解决属性名和字段名不一致的问题"><a href="#6、解决属性名和字段名不一致的问题" class="headerlink" title="6、解决属性名和字段名不一致的问题"></a>6、解决属性名和字段名不一致的问题</h1><h2 id="6-1、问题"><a href="#6-1、问题" class="headerlink" title="6.1、问题"></a>6.1、问题</h2><p>数据库中的字段<br><img src="https://s1.ax1x.com/2022/08/23/vctCf1.png" alt="字段名"></p><p>新建一个项目,拷贝之前的项目,修改属性名,测试实体类字段不一致的情况。</p><pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">int</span> id<span class="token punctuation">;</span> <span class="token keyword">private</span> String name<span class="token punctuation">;</span> <span class="token keyword">private</span> String password<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><p>测试出现问题,查到的用户pwd为null<br><img src="https://s1.ax1x.com/2022/08/23/vctJ0g.md.png" alt="测试结果"></p><pre class=" language-sql"><code class="language-sql"> <span class="token comment" spellcheck="true">// select * from mybatis.user where id = #{id}</span> <span class="token comment" spellcheck="true">// 类型处理器</span> <span class="token comment" spellcheck="true">// </span></code></pre><p>解决方法:</p><ul><li>起别名:</li></ul><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--sql语句--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>select</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>getUserById<span class="token punctuation">"</span></span> <span class="token attr-name">parameterType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>int<span class="token punctuation">"</span></span> <span class="token attr-name">resultType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>com.lut.pojo.User<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> select id, name, pwd as password from mybatis.user where id = #{id} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>select</span><span class="token punctuation">></span></span></code></pre><h2 id="6-2resultMap"><a href="#6-2resultMap" class="headerlink" title="6.2resultMap"></a>6.2resultMap</h2><p>结果集映射</p><pre><code>id name pwdid name password</code></pre><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--结果集映射--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resultMap</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>UserMap<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>User<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--colum为数据库中的字段,property为实体类中的属性--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>id<span class="token punctuation">"</span></span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>id<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>pwd<span class="token punctuation">"</span></span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>password<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resultMap</span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--sql语句--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>select</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>getUserById<span class="token punctuation">"</span></span> <span class="token attr-name">resultMap</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>UserMap<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> select id, name, pwd from mybatis.user where id = #{id} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>select</span><span class="token punctuation">></span></span></code></pre><ul><li>resultMap 元素是 MyBatis 中最重要最强大的元素</li><li>ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了</li><li>ResultMap 的优秀之处——你完全可以不用显式地配置它们</li></ul><h1 id="7、日志"><a href="#7、日志" class="headerlink" title="7、日志"></a>7、日志</h1><h2 id="7-1、日志工厂"><a href="#7-1、日志工厂" class="headerlink" title="7.1、日志工厂"></a>7.1、日志工厂</h2><p>日志是帮助我们排除错误的最好帮手,由此可以见得日志的重要性。</p><p>曾经采用:sout、debug(有兴趣的可以看一下)</p><p>现在采用:日志工厂</p><p>在mybatis的设置中,就有这样的应用。<br><img src="https://s1.ax1x.com/2022/08/23/vcNNDO.png" alt="日志"></p><ul><li>SLF4J</li><li>LOG4J(掌握)(3.5.9 起废弃,突然就不想学了。。。)</li><li>LOG4J2</li><li>JDK_LOGGING</li><li>COMMONS_LOGGING</li><li>STDOUT_LOGGING(掌握)</li><li>NO_LOGGING</li></ul><p>在mybatis中具体使用哪一种日志,在设置中设定即可!</p><pre class=" language-xml"><code class="language-xml"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>settings</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>setting</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>logImpl<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>STDOUT_LOGGING<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>settings</span><span class="token punctuation">></span></span></code></pre><p><strong>STDOUT_LOGGING标准日志输出</strong><br><img src="https://s1.ax1x.com/2022/08/23/vc0AXt.png" alt="STDOUT_LOGGING"></p><h2 id="7-2、log4j"><a href="#7-2、log4j" class="headerlink" title="7.2、log4j"></a>7.2、log4j</h2><p>什么是log4j?</p><ul><li>Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件</li><li>我们也可以控制每一条日志的输出格式</li><li>通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程</li><li>可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码</li></ul><ol><li>导入log4j依赖</li></ol><pre class=" language-xml"><code class="language-xml"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>log4j<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>log4j<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>1.2.17<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span></code></pre><ol start="2"><li>log4j.properties</li></ol><pre class=" language-properties"><code class="language-properties"><span class="token comment" spellcheck="true">#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码</span><span class="token attr-name">log4j.rootLogger</span><span class="token punctuation">=</span><span class="token attr-value">DEBUG,console,file</span><span class="token comment" spellcheck="true">#控制台输出的相关设置</span><span class="token attr-name">log4j.appender.console</span> <span class="token punctuation">=</span> <span class="token attr-value">org.apache.log4j.ConsoleAppender</span><span class="token attr-name">log4j.appender.console.Target</span> <span class="token punctuation">=</span> <span class="token attr-value">System.out</span><span class="token attr-name">log4j.appender.console.Threshold</span><span class="token punctuation">=</span><span class="token attr-value">DEBUG</span><span class="token attr-name">log4j.appender.console.layout</span> <span class="token punctuation">=</span> <span class="token attr-value">org.apache.log4j.PatternLayout</span><span class="token attr-name">log4j.appender.console.layout.ConversionPattern</span><span class="token punctuation">=</span><span class="token attr-value">[%c]-%m%n</span><span class="token comment" spellcheck="true">#文件输出的相关设置</span><span class="token attr-name">log4j.appender.file</span> <span class="token punctuation">=</span> <span class="token attr-value">org.apache.log4j.RollingFileAppender</span><span class="token attr-name">log4j.appender.file.File</span><span class="token punctuation">=</span><span class="token attr-value">./log/lut.log</span><span class="token attr-name">log4j.appender.file.MaxFileSize</span><span class="token punctuation">=</span><span class="token attr-value">10mb</span><span class="token attr-name">log4j.appender.file.Threshold</span><span class="token punctuation">=</span><span class="token attr-value">DEBUG</span><span class="token attr-name">log4j.appender.file.layout</span><span class="token punctuation">=</span><span class="token attr-value">org.apache.log4j.PatternLayout</span><span class="token attr-name">log4j.appender.file.layout.ConversionPattern</span><span class="token punctuation">=</span><span class="token attr-value">[%p][%d{yy-MM-dd}][%c]%m%n</span><span class="token comment" spellcheck="true">#日志输出级别</span><span class="token attr-name">log4j.logger.org.mybatis</span><span class="token punctuation">=</span><span class="token attr-value">DEBUG</span><span class="token attr-name">log4j.logger.java.sql</span><span class="token punctuation">=</span><span class="token attr-value">DEBUG</span><span class="token attr-name">log4j.logger.java.sql.Statement</span><span class="token punctuation">=</span><span class="token attr-value">DEBUG</span><span class="token attr-name">log4j.logger.java.sql.ResultSet</span><span class="token punctuation">=</span><span class="token attr-value">DEBUG</span><span class="token attr-name">log4j.logger.java.sql.PreparedStatement</span><span class="token punctuation">=</span><span class="token attr-value">DEBUG</span></code></pre><ol start="3"><li>配置log4j为日志的实现</li></ol><pre class=" language-xml"><code class="language-xml"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>settings</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>setting</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>logImpl<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>LOG4J<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>settings</span><span class="token punctuation">></span></span></code></pre><ol start="4"><li>log4j的简单使用</li></ol><ul><li>导入import org.apache.log4j.Logger;</li><li>生成日志对象</li></ul><pre class=" language-xml"><code class="language-xml">static Logger logger = Logger.getLogger(UserDaoTest.class);</code></pre><ul><li>日志级别:info、debug、error等</li></ul><h1 id="8、分页"><a href="#8、分页" class="headerlink" title="8、分页"></a>8、分页</h1><p><strong>为什么要使用分页?</strong></p><ul><li>为了减少数据的处理量</li></ul><p><strong>使用limit分页</strong></p><pre class=" language-xml"><code class="language-xml"># 语法 select * from user limit startIndex, pageSizeselect * from user limit 0,2</code></pre><p>使用mybatis进行分页步骤与进行增删改查区别不大,都是先写好接口,然后再xml中使用sql语句实现,最后可以在test中测试。</p><h1 id="9、使用注解开发"><a href="#9、使用注解开发" class="headerlink" title="9、使用注解开发"></a>9、使用注解开发</h1><h2 id="9-1、面向接口编程"><a href="#9-1、面向接口编程" class="headerlink" title="9.1、面向接口编程"></a>9.1、面向接口编程</h2><p>面向接口编程最直观的好处就是<strong>高内聚,低耦合</strong>,这也是java一直所强调的。JAVA运行父类指向子类的引用,因此面向接口编程就很好的解耦。这也为我们的程序提供很大的方便,比如我们系统底层需要变化的时候我们不需去考虑上层接口,只要我们面向接口这一套标准去进行编程那么我们就可以实现。当然这也提高了程序的可扩展性,这一点在很多框架,JDBC上都得以体现,比如现在很多商用的数据,JAVA只需要给出一套标准及接口,让公司自己去实现这些接口就可以。</p><h2 id="9-2、使用注解开发"><a href="#9-2、使用注解开发" class="headerlink" title="9.2、使用注解开发"></a>9.2、使用注解开发</h2><p>本来是需要自己往下去写的,但是学到后面发现哪怕是官方都推荐使用xml作为实现类,所以有关利用注解开发的就不再继续往下写了,有兴趣的话可以去看看官方文档。<a href="https://mybatis.org/mybatis-3/zh/index.html">传送门</a></p><h1 id="10、Lombok"><a href="#10、Lombok" class="headerlink" title="10、Lombok"></a>10、Lombok</h1><pre class=" language-java"><code class="language-java">Project Lombok is a java library that automatically plugs into your editor and build tools<span class="token punctuation">,</span> spicing up your java<span class="token punctuation">.</span>Never write another getter or equals method again<span class="token punctuation">,</span> with one annotation your <span class="token keyword">class</span> <span class="token class-name">has</span> a fully featured builder<span class="token punctuation">,</span> Automate your logging variables<span class="token punctuation">,</span> and much more<span class="token punctuation">.</span></code></pre><p>使用步骤:</p><ol><li>在idea中安装Lombok插件</li><li>在项目中导入Lombok的jar包</li></ol><pre class=" language-xml"><code class="language-xml"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>dependency</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>groupId</span><span class="token punctuation">></span></span>org.projectlombok<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>groupId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>artifactId</span><span class="token punctuation">></span></span>lombok<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>artifactId</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>version</span><span class="token punctuation">></span></span>1.18.10<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>version</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>dependency</span><span class="token punctuation">></span></span></code></pre><ol start="3"><li>在实体类上加注解即可</li></ol><pre class=" language-xml"><code class="language-xml">@Data@AllArgsConstructor@NoArgsConstructorpublic class User { private int id; private String name; private String password;}</code></pre><p>经常用的注解有以上三个,还有很多这里就不再一一列举。</p><p><strong>@Data:无参构造、get、set、tostring、hashcode、equals等</strong></p><h1 id="11、多对一处理(多个学生对应一个老师)"><a href="#11、多对一处理(多个学生对应一个老师)" class="headerlink" title="11、多对一处理(多个学生对应一个老师)"></a>11、多对一处理(多个学生对应一个老师)</h1><h2 id="11-1、测试环境搭建"><a href="#11-1、测试环境搭建" class="headerlink" title="11.1、测试环境搭建"></a>11.1、测试环境搭建</h2><p>老师-学生数据库创建</p><pre class=" language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> <span class="token punctuation">`</span>teacher<span class="token punctuation">`</span> <span class="token punctuation">(</span> <span class="token punctuation">`</span>id<span class="token punctuation">`</span> <span class="token keyword">INT</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>name<span class="token punctuation">`</span> <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span> <span class="token keyword">DEFAULT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token keyword">PRIMARY</span> <span class="token keyword">KEY</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>id<span class="token punctuation">`</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">ENGINE</span><span class="token operator">=</span><span class="token keyword">INNODB</span> <span class="token keyword">DEFAULT</span> <span class="token keyword">CHARSET</span><span class="token operator">=</span>utf8<span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> teacher<span class="token punctuation">(</span><span class="token punctuation">`</span>id<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>name<span class="token punctuation">`</span><span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">'秦老师'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> <span class="token punctuation">`</span>student<span class="token punctuation">`</span> <span class="token punctuation">(</span> <span class="token punctuation">`</span>id<span class="token punctuation">`</span> <span class="token keyword">INT</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>name<span class="token punctuation">`</span> <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span> <span class="token keyword">DEFAULT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>tid<span class="token punctuation">`</span> <span class="token keyword">INT</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token keyword">DEFAULT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span> <span class="token keyword">PRIMARY</span> <span class="token keyword">KEY</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>id<span class="token punctuation">`</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">KEY</span> <span class="token punctuation">`</span>fktid<span class="token punctuation">`</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>tid<span class="token punctuation">`</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">CONSTRAINT</span> <span class="token punctuation">`</span>fktid<span class="token punctuation">`</span> <span class="token keyword">FOREIGN</span> <span class="token keyword">KEY</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>tid<span class="token punctuation">`</span><span class="token punctuation">)</span> <span class="token keyword">REFERENCES</span> <span class="token punctuation">`</span>teacher<span class="token punctuation">`</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>id<span class="token punctuation">`</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">ENGINE</span><span class="token operator">=</span><span class="token keyword">INNODB</span> <span class="token keyword">DEFAULT</span> <span class="token keyword">CHARSET</span><span class="token operator">=</span>utf8INSERT <span class="token keyword">INTO</span> <span class="token punctuation">`</span>student<span class="token punctuation">`</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>id<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>name<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>tid<span class="token punctuation">`</span><span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'1'</span><span class="token punctuation">,</span> <span class="token string">'小明'</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token punctuation">`</span>student<span class="token punctuation">`</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>id<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>name<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>tid<span class="token punctuation">`</span><span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'2'</span><span class="token punctuation">,</span> <span class="token string">'小红'</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token punctuation">`</span>student<span class="token punctuation">`</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>id<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>name<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>tid<span class="token punctuation">`</span><span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'3'</span><span class="token punctuation">,</span> <span class="token string">'小张'</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token punctuation">`</span>student<span class="token punctuation">`</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>id<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>name<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>tid<span class="token punctuation">`</span><span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'4'</span><span class="token punctuation">,</span> <span class="token string">'小李'</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">INSERT</span> <span class="token keyword">INTO</span> <span class="token punctuation">`</span>student<span class="token punctuation">`</span> <span class="token punctuation">(</span><span class="token punctuation">`</span>id<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>name<span class="token punctuation">`</span><span class="token punctuation">,</span> <span class="token punctuation">`</span>tid<span class="token punctuation">`</span><span class="token punctuation">)</span> <span class="token keyword">VALUES</span> <span class="token punctuation">(</span><span class="token string">'5'</span><span class="token punctuation">,</span> <span class="token string">'小王'</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><ol><li>导入Lombok</li><li>新建学生和老师的实体类</li><li>建立mapper接口</li><li>建立mapper.xml文件</li><li>在核心配置文件中绑定mapper.xml(多种方式,随便写!)</li><li>进行测试</li></ol><h2 id="11-2、按照查询嵌套处理"><a href="#11-2、按照查询嵌套处理" class="headerlink" title="11.2、按照查询嵌套处理"></a>11.2、按照查询嵌套处理</h2><pre class=" language-xml"><code class="language-xml"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resultMap</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>StudentTeacher<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Student<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>id<span class="token punctuation">"</span></span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>id<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token comment" spellcheck="true"><!-- 复杂属性需要单独处理 对象:association 集合:collection --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>association</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>teacher<span class="token punctuation">"</span></span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tid<span class="token punctuation">"</span></span> <span class="token attr-name">javaType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Teacher<span class="token punctuation">"</span></span> <span class="token attr-name">select</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>getTeacher<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resultMap</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>select</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>getTeacher<span class="token punctuation">"</span></span> <span class="token attr-name">resultType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Teacher<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> select name from teacher <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>select</span><span class="token punctuation">></span></span></code></pre><p><strong>注意!!!</strong></p><p><strong>跟着视频能理解意思了,但是我还是不清楚为什么这里id为getTeacher的查询明明在mapper接口中没有声明,但它却不报错。。。</strong></p><p><strong>目前的理解是接口中没有getTeacher,所以也不会调用这个接口。从这边来说它相当于不存在。而在xml文件当中嵌套查询时调用了这个查询,也没有涉及到接口类,所以没有报错。也不知道对不对。。。</strong></p><h2 id="11-3、按照结果嵌套处理"><a href="#11-3、按照结果嵌套处理" class="headerlink" title="11.3、按照结果嵌套处理"></a>11.3、按照结果嵌套处理</h2><pre class=" language-xml"><code class="language-xml"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>select</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>getStudent<span class="token punctuation">"</span></span> <span class="token attr-name">resultMap</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>StudentTeacher2<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> select s.id sid, s.name sname, t.name tname from student s, teacher t where s.tid = t.id <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>select</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resultMap</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>StudentTeacher2<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Student<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>id<span class="token punctuation">"</span></span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sid<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sname<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>association</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>teacher<span class="token punctuation">"</span></span> <span class="token attr-name">javaType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Teacher<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tname<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>association</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resultMap</span><span class="token punctuation">></span></span></code></pre><h1 id="12、一对多处理(一个老师对应多个学生)"><a href="#12、一对多处理(一个老师对应多个学生)" class="headerlink" title="12、一对多处理(一个老师对应多个学生)"></a>12、一对多处理(一个老师对应多个学生)</h1><h2 id="12-1、搭建环境"><a href="#12-1、搭建环境" class="headerlink" title="12.1、搭建环境"></a>12.1、搭建环境</h2><p>和前面步骤相同,只不过需要修改一下<strong>实体类</strong></p><pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Data</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Student</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">int</span> id<span class="token punctuation">;</span> <span class="token keyword">private</span> String name<span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">int</span> tid<span class="token punctuation">;</span> <span class="token punctuation">}</span></code></pre><pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Data</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Teacher</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">int</span> id<span class="token punctuation">;</span> <span class="token keyword">private</span> String name<span class="token punctuation">;</span> <span class="token comment" spellcheck="true">// 一个老师对应多个学生</span> <span class="token keyword">private</span> List<span class="token operator"><</span>Student<span class="token operator">></span> students<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><h2 id="12-3、按照结果嵌套处理"><a href="#12-3、按照结果嵌套处理" class="headerlink" title="12.3、按照结果嵌套处理"></a>12.3、按照结果嵌套处理</h2><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--按结果嵌套查询--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>select</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>getTeacher<span class="token punctuation">"</span></span> <span class="token attr-name">resultMap</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>TeacherStudent<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> select s.id sid, s.name sname, t.name tname, t.id tid from student s, teacher t where s.tid = t.id and t.id = #{tid} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>select</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resultMap</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>TeacherStudent<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Teacher<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>id<span class="token punctuation">"</span></span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tid<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tname<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token comment" spellcheck="true"><!--集合中的泛型信息,需要使用ofType来获取--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>collection</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>students<span class="token punctuation">"</span></span> <span class="token attr-name">ofType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Student<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>id<span class="token punctuation">"</span></span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sid<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>name<span class="token punctuation">"</span></span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>sname<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>result</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tid<span class="token punctuation">"</span></span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>tid<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>collection</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resultMap</span><span class="token punctuation">></span></span></code></pre><h2 id="12-4、按照查询嵌套处理"><a href="#12-4、按照查询嵌套处理" class="headerlink" title="12.4、按照查询嵌套处理"></a>12.4、按照查询嵌套处理</h2><pre class=" language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>select</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>getTeacher2<span class="token punctuation">"</span></span> <span class="token attr-name">resultMap</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>TeacherStudent2<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>select * from teacher where id = #{id}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>select</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>resultMap</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>TeacherStudent2<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Teacher<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token comment" spellcheck="true"><!--column是一对多的外键 , 写的是一的主键的列名--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>collection</span> <span class="token attr-name">property</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>students<span class="token punctuation">"</span></span> <span class="token attr-name">javaType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>ArrayList<span class="token punctuation">"</span></span> <span class="token attr-name">ofType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Student<span class="token punctuation">"</span></span> <span class="token attr-name">column</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>id<span class="token punctuation">"</span></span> <span class="token attr-name">select</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>getStudentByTeacherId<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>resultMap</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>select</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>getStudentByTeacherId<span class="token punctuation">"</span></span> <span class="token attr-name">resultType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Student<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> select * from student where tid = #{id}<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>select</span><span class="token punctuation">></span></span></code></pre><p><strong>小结:</strong></p><ul><li><p>关联-association</p></li><li><p>集合-collection</p></li><li><p>JavaType和ofType都是用来指定对象类型的</p><ul><li>JavaType是用来指定pojo中属性的类型</li><li>ofType指定的是映射到list集合属性中pojo的类型。</li></ul></li></ul><p>ps:丫的这里真的有点头晕唉~</p><h1 id="13、动态SQL"><a href="#13、动态SQL" class="headerlink" title="13、动态SQL"></a>13、动态SQL</h1><p><strong>什么是动态SQL:根据不同的条件生成不同的SQL</strong></p><p>利用动态 SQL,可以彻底摆脱这种痛苦。</p><pre class=" language-xml"><code class="language-xml">如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。ifchoose (when, otherwise)trim (where, set)foreach</code></pre><h2 id="13-1、搭建环境"><a href="#13-1、搭建环境" class="headerlink" title="13.1、搭建环境"></a>13.1、搭建环境</h2><pre class=" language-sql"><code class="language-sql"><span class="token keyword">CREATE</span> <span class="token keyword">TABLE</span> <span class="token punctuation">`</span>blog<span class="token punctuation">`</span><span class="token punctuation">(</span><span class="token punctuation">`</span>id<span class="token punctuation">`</span> <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">COMMENT</span> <span class="token string">'博客id'</span><span class="token punctuation">,</span><span class="token punctuation">`</span>title<span class="token punctuation">`</span> <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">COMMENT</span> <span class="token string">'博客标题'</span><span class="token punctuation">,</span><span class="token punctuation">`</span>author<span class="token punctuation">`</span> <span class="token keyword">VARCHAR</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">COMMENT</span> <span class="token string">'博客作者'</span><span class="token punctuation">,</span><span class="token punctuation">`</span>create_time<span class="token punctuation">`</span> <span class="token keyword">DATETIME</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">COMMENT</span> <span class="token string">'创建时间'</span><span class="token punctuation">,</span><span class="token punctuation">`</span>views<span class="token punctuation">`</span> <span class="token keyword">INT</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword">COMMENT</span> <span class="token string">'浏览量'</span><span class="token punctuation">)</span><span class="token keyword">ENGINE</span><span class="token operator">=</span><span class="token keyword">INNODB</span> <span class="token keyword">DEFAULT</span> <span class="token keyword">CHARSET</span><span class="token operator">=</span>utf8</code></pre><p>这里我们再来回顾一下整个流程,加深加深印象:</p><p>创建一个基础工程</p><ol><li>导包</li><li>编写配置文件</li><li>编写实体类</li></ol><pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Data</span><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Blog</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> <span class="token keyword">int</span> id<span class="token punctuation">;</span> <span class="token keyword">private</span> String title<span class="token punctuation">;</span> <span class="token keyword">private</span> String author<span class="token punctuation">;</span> <span class="token keyword">private</span> Date createTime<span class="token punctuation">;</span> <span class="token comment" spellcheck="true">// 属性名和字段名不一致(设置中有参数可以帮助解决该问题)</span> <span class="token keyword">private</span> <span class="token keyword">int</span> views<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><ol start="4"><li>编写实体类对应的mapper接口和mapper.xml文件</li></ol><p><strong>IF</strong></p><pre class=" language-xml"><code class="language-xml"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>select</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>queryBlogIF<span class="token punctuation">"</span></span> <span class="token attr-name">parameterType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>map<span class="token punctuation">"</span></span> <span class="token attr-name">resultType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Blog<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> select * from mybatis.blog where 1=1 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>if</span> <span class="token attr-name">test</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>title !<span class="token punctuation">=</span> null<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> and title = #{title} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>if</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>if</span> <span class="token attr-name">test</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>author !<span class="token punctuation">=</span> null<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> and author = #{author} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>if</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>select</span><span class="token punctuation">></span></span></code></pre><p><strong>choose (when, otherwise)</strong></p><pre class=" language-xml"><code class="language-xml">select * from mybatis.blog <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>where</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>choose</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>when</span> <span class="token attr-name">test</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>title !<span class="token punctuation">=</span> null<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> title = #{title} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>when</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>when</span> <span class="token attr-name">test</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>author !<span class="token punctuation">=</span> null<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> and author = #{author} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>when</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>otherwise</span><span class="token punctuation">></span></span> and views = #{views} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>otherwise</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>choose</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>where</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>select</span><span class="token punctuation">></span></span></code></pre><p><strong>trim (where, set)</strong></p><pre class=" language-xml"><code class="language-xml"> select * from mybatis.blog <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>where</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>if</span> <span class="token attr-name">test</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>title !<span class="token punctuation">=</span> null<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> and title = #{title} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>if</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>if</span> <span class="token attr-name">test</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>author !<span class="token punctuation">=</span> null<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> and author = #{author} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>if</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>where</span><span class="token punctuation">></span></span></code></pre><pre class=" language-xml"><code class="language-xml"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>update</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>updateBlog<span class="token punctuation">"</span></span> <span class="token attr-name">parameterType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>map<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> update mybatis.blog <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>set</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>if</span> <span class="token attr-name">test</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>title !<span class="token punctuation">=</span> null<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> title = #{title} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>if</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>if</span> <span class="token attr-name">test</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>author !<span class="token punctuation">=</span> null<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> author = #{author} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>if</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>set</span><span class="token punctuation">></span></span> where id = #{id} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>update</span><span class="token punctuation">></span></span></code></pre><p><strong>所谓动态SQL,本质上还是一些SQL语句。主要还是通过一些逻辑代码将SQL语句进行拼接从而达到动态!</strong></p><p><strong>SQL片段</strong></p><p>有的时候我们会将一些公共的sql代码抽出来复用。</p><ol><li>利用sql标签抽取公共代码</li></ol><pre class=" language-xml"><code class="language-xml"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>sql</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>if-title-author<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> select * from mybatis.blog where 1=1 <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>if</span> <span class="token attr-name">test</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>title !<span class="token punctuation">=</span> null<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> and title = #{title} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>if</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>if</span> <span class="token attr-name">test</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>author !<span class="token punctuation">=</span> null<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> and author = #{author} <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>if</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>sql</span><span class="token punctuation">></span></span></code></pre><ol start="2"><li>利用include标签引用公共代码</li></ol><pre class=" language-xml"><code class="language-xml"> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>select</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>queryBlogIF<span class="token punctuation">"</span></span> <span class="token attr-name">parameterType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>map<span class="token punctuation">"</span></span> <span class="token attr-name">resultType</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>blog<span class="token punctuation">"</span></span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>include</span> <span class="token attr-name">refid</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>if-title-author<span class="token punctuation">"</span></span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>include</span><span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span>select</span><span class="token punctuation">></span></span></code></pre><p>注意:</p><ul><li>最好基于单表来定义sql片段</li><li>不要存在where标签</li></ul><p><strong>foreach</strong><br><img src="https://s1.ax1x.com/2022/08/30/vhEIbR.md.png" alt="foreach"></p><h1 id="14、缓存"><a href="#14、缓存" class="headerlink" title="14、缓存"></a>14、缓存</h1><p>在开始之前我们先思考一个问题,连接数据库时需要消耗一定的资源,那么我们有没有什么办法可以将这种消耗降低?我们将查询的结果先暂时存储在一个地方,如果下次查询还是需要这个数据,那我们无需连接数据库,直接从这个地方拿数据就可以,这样就大大减少了资源的占用。</p><h2 id="14-1、简介"><a href="#14-1、简介" class="headerlink" title="14.1、简介"></a>14.1、简介</h2><ol><li>什么是缓存?<ul><li>存在内存中的临时数据</li><li>将用户经常使用的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上查询,从缓存中查询,可以提高查询效率,解决高并发系统的性能问题。</li></ul></li><li>为什么使用缓存?<ul><li>减少和数据库的交互次数,减少系统开销,提高效率。</li></ul></li><li>什么样的数据可以使用缓存?<ul><li>经常查询并且不经常改变的数据。</li></ul></li></ol><h2 id="14-2、Mybatis缓存"><a href="#14-2、Mybatis缓存" class="headerlink" title="14.2、Mybatis缓存"></a>14.2、Mybatis缓存</h2><p>mybatis为减轻数据库压力,提高数据库性能。提供了两级缓存机制:</p><ol><li><strong>一级缓存</strong>:</li></ol><ul><li><strong>SqlSession级别的缓存,缓存的数据只在SqlSession内有效。</strong></li><li>一级缓存mybatis已近为我们自动开启,不用我们手动操作,而且我们是关闭不了的!!但是我们可以手动清除缓存。</li><li>在操作数据库时需要构造sqlSession对象,在对象中有一个基于 PerpetualCache的HashMap 本地缓存数据结构,用于缓存数据。</li><li>不同的sqlSession之间的缓存数据区域(HashMap)是互不影响的。</li></ul><ol start="2"><li><strong>二级缓存</strong>:</li></ol><ul><li><strong>mapper级别的缓存,同一个namespace公用这一个缓存,所以对SqlSession是共享的。</strong></li><li>二级缓存需要我们手动开启。</li><li>二级缓存是mapper级别的缓存,多个sqlSession去操作同一个Mapper的sql语句,多个sqlSession可以共用二级缓存,二级缓存是跨sqlSession的。</li></ul><h2 id="14-1、一级缓存"><a href="#14-1、一级缓存" class="headerlink" title="14.1、一级缓存"></a>14.1、一级缓存</h2><ul><li>一级缓存也叫本地缓存:SqlSession<ul><li>与数据库同一次会话期间查询到的数据会存放在本地缓存中</li><li>以后如果需要相同的数据,直接从换从中获取即可</li></ul></li></ul><p>测试步骤:</p><ol><li>开启日志</li><li>测试在一个sqlsession中查询两次相同记录</li><li>查看日志输出</li></ol><p><img src="https://s1.ax1x.com/2022/08/30/vhn8t1.md.png" alt="一级缓存"></p><p><strong>缓存失效的情况:</strong></p><ol><li>增删改操作可能会改变原来的数据,所以增删改操纵必定会刷新缓存</li><li>查询不同的东西</li><li>查询不同的Mapper.xml</li><li>手动清理缓存</li></ol><p>小结:一级缓存默认是开启的,但是它只在一次SqlSession中有效,即只在拿到连接和关闭连接的过程中有效。</p><h2 id="14-2、二级缓存"><a href="#14-2、二级缓存" class="headerlink" title="14.2、二级缓存"></a>14.2、二级缓存</h2><ul><li>二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存</li><li>基于namespace级别的缓存,一个名称空间,对应一个二级缓存</li><li>工作机制<ul><li>一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中</li><li>如果当前会话关闭了,这个会话对应的一级缓存就没了。但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中</li><li>新的会话查询信息,就可以从二级缓存中获取内容</li><li>不同的mapper查出的数据会放在自己对应的缓存(map)中</li></ul></li></ul><p>步骤:</p><ol><li>开启全局缓存</li></ol><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--开启全局缓存--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>setting</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>cacheEnabled<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span></code></pre><ol start="2"><li>在要使用的Mapper中开启</li></ol><pre class=" language-xml"><code class="language-xml"> <span class="token comment" spellcheck="true"><!--在当前xml文件中使用二级缓存--></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>cache</span><span class="token punctuation">/></span></span></code></pre><p>当然,也可以自定义参数</p><pre class=" language-xml"><code class="language-xml"><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>cache</span> <span class="token attr-name">eviction</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>FIFO<span class="token punctuation">"</span></span> <span class="token attr-name">flushInterval</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>60000<span class="token punctuation">"</span></span> <span class="token attr-name">size</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>512<span class="token punctuation">"</span></span> <span class="token attr-name">readOnly</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>true<span class="token punctuation">"</span></span><span class="token punctuation">/></span></span></code></pre><ol start="3"><li>测试</li></ol><h2 id="14-3、mybatis缓存原理"><a href="#14-3、mybatis缓存原理" class="headerlink" title="14.3、mybatis缓存原理"></a>14.3、mybatis缓存原理</h2><p>看到一份写的比较详细的博客,在这里贴出来,<a href="https://blog.csdn.net/m0_37583655/article/details/122188217?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166191021516781647569404%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=166191021516781647569404&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v33_ecpm-1-122188217-null-null.142%5Ev42%5Epc_ran_alice,185%5Ev2%5Econtrol&utm_term=mybatis%E7%BC%93%E5%AD%98%E4%B8%8E%E5%93%AA%E9%87%8C&spm=1018.2226.3001.4187">传送门</a></p><p>大家有兴趣的可以去看看。</p><p><strong>完结撒花~~~,继续下一项技术!</strong></p>]]></content>
<categories>
<category> 编程 </category>
</categories>
<tags>
<tag> Java </tag>
<tag> mybatis </tag>
</tags>
</entry>
<entry>
<title>记录一次手写数字识别实战</title>
<link href="/2022/07/17/ji-lu-yi-ci-shou-xie-shu-zi-shi-bie-shi-zhan/"/>
<url>/2022/07/17/ji-lu-yi-ci-shou-xie-shu-zi-shi-bie-shi-zhan/</url>
<content type="html"><![CDATA[<p>废话不多说,我们直接开整。首先需要导入需要的类库,相关内容我会在后续代码中进行详细介绍。</p><pre class=" language-python"><code class="language-python"><span class="token keyword">from</span> keras<span class="token punctuation">.</span>datasets <span class="token keyword">import</span> mnist<span class="token keyword">from</span> keras<span class="token punctuation">.</span>utils <span class="token keyword">import</span> to_categorical<span class="token keyword">from</span> keras <span class="token keyword">import</span> models<span class="token punctuation">,</span>layers<span class="token punctuation">,</span>regularizers<span class="token keyword">from</span> keras<span class="token punctuation">.</span>optimizers <span class="token keyword">import</span> RMSprop</code></pre><p>数据集为<strong>MNIST 手写字符数据集</strong>,训练集为 60,000 张 28x28 像素灰度图像,测试集为 10,000 同规格图像,总共 10 类数字标签。</p><h2 id="1、用法"><a href="#1、用法" class="headerlink" title="1、用法"></a>1、用法</h2><p><strong>from keras.datasets import mnist</strong></p><p><strong>(x_train, y_train), (x_test, y_test) = mnist.load_data()</strong><br>返回2 个元组:</p><ul><li>x_train, x_test: 分别表示训练集与测试集的图片。</li><li>y_train, y_test: 分别表示训练集与测试集的数字标签(范围在 0-9 之间的整数)。</li></ul><h2 id="2、下载数据集"><a href="#2、下载数据集" class="headerlink" title="2、下载数据集"></a>2、下载数据集</h2><p>根据上述用法我们可以直接将这个数据集下载下来。</p><pre class=" language-python"><code class="language-python"><span class="token comment" spellcheck="true">#加载数据集</span><span class="token punctuation">(</span>train_images<span class="token punctuation">,</span> train_labels<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>test_images<span class="token punctuation">,</span> test_labels<span class="token punctuation">)</span> <span class="token operator">=</span> mnist<span class="token punctuation">.</span>load_data<span class="token punctuation">(</span><span class="token punctuation">)</span></code></pre><h2 id="3、展平矩阵"><a href="#3、展平矩阵" class="headerlink" title="3、展平矩阵"></a>3、展平矩阵</h2><p>通过上述介绍我们知道,每张图片其实是一个28<em>28的数字矩阵,矩阵中的每个数字(0-255)代表着该像素点的灰度级。为了可以更方便的对其进行操作,我们将其变为一个一维的向量(784</em>1),即将这个数字矩阵<strong>展平</strong>,将这个正方形变为一个宽为1的长方形。astype方法用来转换数据类型。</p><pre class=" language-python"><code class="language-python"><span class="token comment" spellcheck="true">#展平</span>train_images <span class="token operator">=</span> train_images<span class="token punctuation">.</span>reshape<span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token number">60000</span><span class="token punctuation">,</span> <span class="token number">28</span><span class="token operator">*</span><span class="token number">28</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>astype<span class="token punctuation">(</span><span class="token string">'float'</span><span class="token punctuation">)</span>test_images <span class="token operator">=</span> test_images<span class="token punctuation">.</span>reshape<span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token number">10000</span><span class="token punctuation">,</span> <span class="token number">28</span><span class="token operator">*</span><span class="token number">28</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>astype<span class="token punctuation">(</span><span class="token string">'float'</span><span class="token punctuation">)</span></code></pre><h2 id="4、采用one-hot编码"><a href="#4、采用one-hot编码" class="headerlink" title="4、采用one-hot编码"></a>4、采用one-hot编码</h2><p>one-hot编码是在深度学习中非常常见的一种编码方式,使用它的目的就是为了能够让各种变量转换为可以被各种算法利用的形式。将离散型特征使用one-hot编码还会让各个特征之间的距离更加的合理。举个例子,若用1来表示狗,2来表示猫,3来表示老鼠。则猫狗之间的距离为1,鼠狗之间的距离为2,但是猫狗之间的差别真的就小于鼠狗之间的差别吗?这种差别又以什么来作为标准呢?所以采用one-hot编码,以[1,0,0]表示狗,[0,1,0]表示猫,[0,0,1]来表示老鼠就不会出现这种情况。<br>这里用to_categorical方法来对十种数字进行编码。例如,数字3的编码方式为:[0,0,0,1,0,0,0,0,0,0,0]</p><pre class=" language-python"><code class="language-python"><span class="token comment" spellcheck="true">#将标签以onehot编码</span>train_labels <span class="token operator">=</span> to_categorical<span class="token punctuation">(</span>train_labels<span class="token punctuation">)</span>test_labels <span class="token operator">=</span> to_categorical<span class="token punctuation">(</span>test_labels<span class="token punctuation">)</span></code></pre><h2 id="5、建立模型"><a href="#5、建立模型" class="headerlink" title="5、建立模型"></a>5、建立模型</h2><p>这里需要用到Sequential 顺序模型,该模型是多个网络层的线性堆叠。我们可以简单地使用 .add() 方法将各层添加到模型中。在这里需要注意的是顺序模型中的第一层(且只有第一层,因为下面的层可以自动地推断尺寸)需要接收关于其输入尺寸的信息。</p><pre class=" language-python"><code class="language-python"><span class="token comment" spellcheck="true">#建立模型</span>network <span class="token operator">=</span> models<span class="token punctuation">.</span>Sequential<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">#kernel_regularizer正则化降低过拟合</span>network<span class="token punctuation">.</span>add<span class="token punctuation">(</span>layers<span class="token punctuation">.</span>Dense<span class="token punctuation">(</span>units<span class="token operator">=</span><span class="token number">128</span><span class="token punctuation">,</span> activation<span class="token operator">=</span><span class="token string">'relu'</span><span class="token punctuation">,</span> input_shape<span class="token operator">=</span><span class="token punctuation">(</span><span class="token number">28</span><span class="token operator">*</span><span class="token number">28</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> kernel_regularizer<span class="token operator">=</span>regularizers<span class="token punctuation">.</span>l1<span class="token punctuation">(</span><span class="token number">0.0001</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">#drout层降低过拟合</span>network<span class="token punctuation">.</span>add<span class="token punctuation">(</span>layers<span class="token punctuation">.</span>Dropout<span class="token punctuation">(</span><span class="token number">0.01</span><span class="token punctuation">)</span><span class="token punctuation">)</span>network<span class="token punctuation">.</span>add<span class="token punctuation">(</span>layers<span class="token punctuation">.</span>Dense<span class="token punctuation">(</span>units<span class="token operator">=</span><span class="token number">32</span><span class="token punctuation">,</span> activation<span class="token operator">=</span><span class="token string">'relu'</span><span class="token punctuation">,</span> kernel_regularizer<span class="token operator">=</span>regularizers<span class="token punctuation">.</span>l1<span class="token punctuation">(</span><span class="token number">0.0001</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>network<span class="token punctuation">.</span>add<span class="token punctuation">(</span>layers<span class="token punctuation">.</span>Dropout<span class="token punctuation">(</span><span class="token number">0.01</span><span class="token punctuation">)</span><span class="token punctuation">)</span>network<span class="token punctuation">.</span>add<span class="token punctuation">(</span>layers<span class="token punctuation">.</span>Dense<span class="token punctuation">(</span>units<span class="token operator">=</span><span class="token number">10</span><span class="token punctuation">,</span> activation<span class="token operator">=</span><span class="token string">'softmax'</span><span class="token punctuation">)</span><span class="token punctuation">)</span></code></pre><h2 id="6、编译与训练"><a href="#6、编译与训练" class="headerlink" title="6、编译与训练"></a>6、编译与训练</h2><p>通过对模型设置一些超参数来尽可能的使模型达到最优。</p><pre class=" language-python"><code class="language-python"><span class="token comment" spellcheck="true">#编译</span>network<span class="token punctuation">.</span>compile<span class="token punctuation">(</span>optimizer<span class="token operator">=</span>RMSprop<span class="token punctuation">(</span>learning_rate<span class="token operator">=</span><span class="token number">0.001</span><span class="token punctuation">)</span><span class="token punctuation">,</span> loss<span class="token operator">=</span><span class="token string">'categorical_crossentropy'</span><span class="token punctuation">,</span> metrics<span class="token operator">=</span><span class="token punctuation">[</span><span class="token string">'accuracy'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">#训练</span>network<span class="token punctuation">.</span>fit<span class="token punctuation">(</span>train_images<span class="token punctuation">,</span> train_labels<span class="token punctuation">,</span> epochs<span class="token operator">=</span><span class="token number">20</span><span class="token punctuation">,</span> batch_size<span class="token operator">=</span><span class="token number">128</span><span class="token punctuation">,</span> verbose<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">)</span></code></pre><h2 id="7、在测试集上测试性能"><a href="#7、在测试集上测试性能" class="headerlink" title="7、在测试集上测试性能"></a>7、在测试集上测试性能</h2><p>训练模型最终的目的是为了预测,通过训练模型已经能够在训练集上达到不错的效果,现在为了检验在测试集上它的表现如何,采用evaluate方法返回模型的误差值和评估标准值。</p><pre class=" language-python"><code class="language-python"><span class="token comment" spellcheck="true">#在测试集上测试模型性能</span>test_loss<span class="token punctuation">,</span> test_accuracy <span class="token operator">=</span> network<span class="token punctuation">.</span>evaluate<span class="token punctuation">(</span>test_images<span class="token punctuation">,</span> test_labels<span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"test_loss:"</span><span class="token punctuation">,</span> test_loss<span class="token punctuation">,</span> <span class="token string">" test_accuracy:"</span><span class="token punctuation">,</span> test_accuracy<span class="token punctuation">)</span></code></pre><p>最后附上完整代码:</p><pre class=" language-python"><code class="language-python"><span class="token keyword">from</span> keras<span class="token punctuation">.</span>datasets <span class="token keyword">import</span> mnist<span class="token keyword">import</span> matplotlib<span class="token punctuation">.</span>pyplot <span class="token keyword">as</span> plt<span class="token keyword">from</span> keras<span class="token punctuation">.</span>utils <span class="token keyword">import</span> to_categorical<span class="token keyword">from</span> keras <span class="token keyword">import</span> models<span class="token punctuation">,</span>layers<span class="token punctuation">,</span>regularizers<span class="token keyword">from</span> keras<span class="token punctuation">.</span>optimizers <span class="token keyword">import</span> RMSprop<span class="token comment" spellcheck="true">#加载数据集</span><span class="token punctuation">(</span>train_images<span class="token punctuation">,</span> train_labels<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>test_images<span class="token punctuation">,</span> test_labels<span class="token punctuation">)</span> <span class="token operator">=</span> mnist<span class="token punctuation">.</span>load_data<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true"># print(train_images.shape, test_images.shape)</span><span class="token comment" spellcheck="true"># print(train_images[0])</span><span class="token comment" spellcheck="true"># print(train_labels[0])</span><span class="token comment" spellcheck="true"># plt.imshow(train_images[0])</span><span class="token comment" spellcheck="true"># plt.show()</span><span class="token comment" spellcheck="true">#展平</span>train_images <span class="token operator">=</span> train_images<span class="token punctuation">.</span>reshape<span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token number">60000</span><span class="token punctuation">,</span> <span class="token number">28</span><span class="token operator">*</span><span class="token number">28</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>astype<span class="token punctuation">(</span><span class="token string">'float'</span><span class="token punctuation">)</span>test_images <span class="token operator">=</span> test_images<span class="token punctuation">.</span>reshape<span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token number">10000</span><span class="token punctuation">,</span> <span class="token number">28</span><span class="token operator">*</span><span class="token number">28</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>astype<span class="token punctuation">(</span><span class="token string">'float'</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">#将标签以onehot编码</span>train_labels <span class="token operator">=</span> to_categorical<span class="token punctuation">(</span>train_labels<span class="token punctuation">)</span>test_labels <span class="token operator">=</span> to_categorical<span class="token punctuation">(</span>test_labels<span class="token punctuation">)</span><span class="token comment" spellcheck="true"># print(train_labels[0])</span><span class="token comment" spellcheck="true">#建立模型</span>network <span class="token operator">=</span> models<span class="token punctuation">.</span>Sequential<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">#kernel_regularizer正则化降低过拟合</span>network<span class="token punctuation">.</span>add<span class="token punctuation">(</span>layers<span class="token punctuation">.</span>Dense<span class="token punctuation">(</span>units<span class="token operator">=</span><span class="token number">128</span><span class="token punctuation">,</span> activation<span class="token operator">=</span><span class="token string">'relu'</span><span class="token punctuation">,</span> input_shape<span class="token operator">=</span><span class="token punctuation">(</span><span class="token number">28</span><span class="token operator">*</span><span class="token number">28</span><span class="token punctuation">,</span> <span class="token punctuation">)</span><span class="token punctuation">,</span> kernel_regularizer<span class="token operator">=</span>regularizers<span class="token punctuation">.</span>l1<span class="token punctuation">(</span><span class="token number">0.0001</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">#drout层降低过拟合</span>network<span class="token punctuation">.</span>add<span class="token punctuation">(</span>layers<span class="token punctuation">.</span>Dropout<span class="token punctuation">(</span><span class="token number">0.01</span><span class="token punctuation">)</span><span class="token punctuation">)</span>network<span class="token punctuation">.</span>add<span class="token punctuation">(</span>layers<span class="token punctuation">.</span>Dense<span class="token punctuation">(</span>units<span class="token operator">=</span><span class="token number">32</span><span class="token punctuation">,</span> activation<span class="token operator">=</span><span class="token string">'relu'</span><span class="token punctuation">,</span> kernel_regularizer<span class="token operator">=</span>regularizers<span class="token punctuation">.</span>l1<span class="token punctuation">(</span><span class="token number">0.0001</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>network<span class="token punctuation">.</span>add<span class="token punctuation">(</span>layers<span class="token punctuation">.</span>Dropout<span class="token punctuation">(</span><span class="token number">0.01</span><span class="token punctuation">)</span><span class="token punctuation">)</span>network<span class="token punctuation">.</span>add<span class="token punctuation">(</span>layers<span class="token punctuation">.</span>Dense<span class="token punctuation">(</span>units<span class="token operator">=</span><span class="token number">10</span><span class="token punctuation">,</span> activation<span class="token operator">=</span><span class="token string">'softmax'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">#编译</span>network<span class="token punctuation">.</span>compile<span class="token punctuation">(</span>optimizer<span class="token operator">=</span>RMSprop<span class="token punctuation">(</span>learning_rate<span class="token operator">=</span><span class="token number">0.001</span><span class="token punctuation">)</span><span class="token punctuation">,</span> loss<span class="token operator">=</span><span class="token string">'categorical_crossentropy'</span><span class="token punctuation">,</span> metrics<span class="token operator">=</span><span class="token punctuation">[</span><span class="token string">'accuracy'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">#训练</span>network<span class="token punctuation">.</span>fit<span class="token punctuation">(</span>train_images<span class="token punctuation">,</span> train_labels<span class="token punctuation">,</span> epochs<span class="token operator">=</span><span class="token number">20</span><span class="token punctuation">,</span> batch_size<span class="token operator">=</span><span class="token number">128</span><span class="token punctuation">,</span> verbose<span class="token operator">=</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token comment" spellcheck="true">#在测试集上测试模型性能</span><span class="token comment" spellcheck="true"># y_pre = network.predict(test_images[:5])</span><span class="token comment" spellcheck="true"># print(y_pre, test_labels[:5])</span>test_loss<span class="token punctuation">,</span> test_accuracy <span class="token operator">=</span> network<span class="token punctuation">.</span>evaluate<span class="token punctuation">(</span>test_images<span class="token punctuation">,</span> test_labels<span class="token punctuation">)</span><span class="token keyword">print</span><span class="token punctuation">(</span><span class="token string">"test_loss:"</span><span class="token punctuation">,</span> test_loss<span class="token punctuation">,</span> <span class="token string">" test_accuracy:"</span><span class="token punctuation">,</span> test_accuracy<span class="token punctuation">)</span></code></pre><p>本次实战是参照b站大佬敲出来的,大佬讲的很详细,需要的小伙伴可以来看一下,地址我贴在在这里了 <a href="https://www.bilibili.com/video/BV16g4y1z7Qu">传送门</a><br>因为搭建的网络较为简单,所以准确率没有那么高。<br><img src="https://img-blog.csdnimg.cn/7135ad697a434a0db8c849a0c2745f9c.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNDE0Mjky,size_16,color_FFFFFF,t_70" alt="训练过程可视化"></p>]]></content>
<categories>
<category> 人工智能 </category>
</categories>
<tags>
<tag> 深度学习 </tag>
<tag> python </tag>
</tags>
</entry>
</search>