
前言
课程视频地址:https://www.bilibili.com/video/BV15b4y1a7yG/
Java环境:JavaSE 1.8.0_351
开发IDE:IntelliJ IDEA Community Edition 2022.2.3
0.1 IDEA Community Edition设置
0.1.1 统一设置编码为utf-8编码
1、文件和项目编码File -> Settings -> Editor -> File Encodings,其中的Project Encoding和Default encoding for properties files两项,后面Transparent native to ascii convension打勾。
2、新项目文件编码:File -> New Project Setup -> Settings for New Projects -> Editor -> File Encodings,与上面相同。
3、File -> Settings -> Build, Execution, Deployment -> Compiler -> Java Compiler,设置Additional command line parameters选项为-encoding utf-8
4、将项目中的**.idea文件夹中的encodings.xml**文件中的编码格式改为utf-8,一般来说进行了上述第1步,这个文件中的编码格式自动改为utf-8,不需要手动修改。
0.1.2 Maven设置
本例中IDEA自带的Maven是3.8.1,一般网上教程要求是Maven 3即可。
强烈建议在IDEA里安装Maven Helper插件。
首先准备好自己的maven仓库目录,本例中是 D:\Java\mvn-repository
准备好自己的一个 settings.xml,如下:
<settings xmlns=“http://maven.apache.org/SETTINGS/1.0.0”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=“http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd”>
这个settings.xml里
菜单File -> Settings -> Build, … -> Build Tools -> Maven,将两个Override都勾上,在User settings file里打开自己的settings.xml,点下面的“Apply”,就行了。
0.1.3 代码提示
格式化代码快捷键:Ctrl + Alt + L
不希望格式化代码时格式化注释:File -> Settings -> Editor -> Code Style -> Java,右边选择Javadoc将下面的Enable Javadoc formatting勾勾去掉。
不要提示Dangling Javadoc comment:File -> Settings -> Editor -> Inspections ->Java -> Javadoc把对应项后面的勾勾去掉。在自动生成Javadoc时不写入悬空的注释。
不要Duplicated code提示:File -> Settings -> Editor -> Inspections -> General -> Duplicated Code fragement把勾勾去掉。社区版好像没有这一项。
不要拼写检查:File -> Settings -> Editor -> Inspections -> Proofreading勾勾去掉,就没有拼写和语法检查了。
鼠标在类、方法、参数上悬停时出现相应说明信息:File -> Settings -> Editor -> Code Editing右边把Show quick documentation on mouse hover打上勾。默认是有的。
经常会警告(黄色标签)声明,或者方法没有被使用。File -> Settings -> Editor -> Inspections -> Java -> Declaration redundancy -> Unused declaration去掉勾。或者搜索unused就可以找到。
0.1.4 设置Java代码文件头
菜单File -> Settings -> Editor -> File and Code Templates右边Includes -> File Header,如下图所示输入作者信息,则新建Java Class文件时会自动加到头上。
一、基础篇
前置知识:
- Java基础语法
- Spring与SpringMVC,知道Spring是用来管理bean,能够基于Restful实现页面请求交互功能
- Mybatis与MyBatis-Plus,基于MyBatis和Mybatis-Plus能够开发出包含基础CRUD功能的Dao模块
- 数据库MySQL,能够读懂基础CRUD功能的SQL语句
- 服务器,知道服务器与Web工程的关系,熟悉Web服务器的配置
- Maven,知道Maven的依赖关系,知道什么是依赖范围,依赖传递,排除依赖,可选依赖,继承
- Web技术(含Vue,ElementUI),知道Vue如何发送ajax请求,如何获取响应数据,如何进行数据模型双向绑定
学习目标:
- 能够创建SpringBoot工程
- 基于SpringBoot实现ssm整合
1.1 快速上手SpringBoot
在IDEA里新建一个Project,类型为Empty Project,名字为Springboot。IDEA里的Project相当于Eclipse里面的Work Space,只是一个容器或框架。后续的各个案例都将作为Module模块放在这个空的Project里面。
1.1.1 IDEA联网版入门案例
需要用到Spring Intilalizr,社区版里没有。之前有Spring Assistant插件可以用,现在该插件已被Spring Boot Helper取代,激活收费$15。
略。
1.1.2 官网创建版案例
到Spring官网https://spring.io/,顶部的Projects里找到Spring Boot
或者直接https://spring.io/projects/spring-boot进入,到最下面看到如下图标和链接
点击Spring Initializr进入定制页面,或者直接https://start.spring.io/进入如下:
1、选择Maven Project
2、语言选择Java
3、Spring Boot的版本为当前最新版2.7.5
4、项目的元数据自定义,最后一项包名自动包含了项目名称,可以修改为短的
5、右侧Dependencies选择增加Spring Web
点击下方GENERATE按钮,会自动生成一个springboot_01_02_quickstart.zip压缩包并自动下载。解压缩后生成同名文件夹,把文件夹springboot_01_02_quickstart整个拷贝到项目文件夹(D:\id-space\Springboot)下。
在IDEA菜单File -> Project Structure 看看JDK设置好没有
然后在下面Modules里面点击“+”Import Module添加一个模块,选中刚才拷贝过来的文件夹
中间注意要选中Maven类型
然后IDEA开始导入模块,如果是第一次,则开始下载Maven相关依赖包,插件等,需要几分钟。如“0.1.2 Maven设置”中的settings.xml中设置的是阿里云下载点,下载速度会很快。
Maven更新完成后,pom.xml文件可能会报错“spring-boot-maven-plugin not found”,如下增加一行版本号,与Initializr里使用的Spring Boot版本号一致。如果IDEA里安装了Maven Helper,则在这个文件上右键Maven -> reimport更新即可。
在src/main/java/cn/zlz8x8下新建一个包controller,下面新建一个类BookControllerr如下。如果前面步骤都正常的话,在写上面代码时应正常出现代码补全的提示,并会自动根据代码在import载入相应的包。
package cn.zlz8x8.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//Rest模式
@RestController
@RequestMapping(“/books”)
public class BookController {
@GetMapping
public String getById() {
System.out.println(“springboot is running …”);
return “springboot is running …”;
}
}
运行Springboot0102QuickstartApplication.java,文件上右键run,或者打开这个文件,工具栏上自动会有run的图标。
控制台会显示如上输出,最后一行springboot is running并没有。
打开浏览器,输入http://localhost:8080/books,则会看到浏览器的输出,同时上面控制台也会输出最后一行springboot is running
工具栏上红色方块停止按钮可以停止运行。
1.1.3 阿里云版案例
仍然要用到Spring Initializr,IDAE社区版没有。只是把Initailizr里的创建地址https://start.spring.io换成了https://start.aliyun.com而已。
进入https://start.aliyun.com/bootstrap.html可以看到与Spring官网类似的在线生成器,但是Spring Boot的版本过低。但依赖包比官网多一些,比如有MyBatis-Plus
这部分略过。
1.1.4 手工制作版案例
在项目Springboot下新建一个Module,Build system选择Maven,需要修改的是Name和GroupId,其他的会自动生成。点击按钮Create就可以创建一个Maven模块。
修改pom.xml,参照“1.1.2 官网创建版案例”拷贝有用的部分,主要是
如果安装了Maven Helper插件,文件上会出现一个悬浮刷新按钮,修改完点击刷新,没有报错即可。
<project xmlns=“http://maven.apache.org/POM/4.0.0”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
前面创建Module时,Add sample code打了勾,因此已经有一个cn.zlz8x8.Main文件,同样参照“1.1.2 官网创建版案例”修改如下:
package cn.zlz8x8;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
同样参照“1.1.2 官网创建版案例”,新建一个包cn.zlz8x8.controller,把之前的BookController.java拷贝到这个包里,可以稍微修改一下输出,如下:
package cn.zlz8x8.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
//Rest模式
@RestController
@RequestMapping(“/books”)
public class BookController {
@GetMapping
public String getById() {
System.out.println(“控制台: springboot is running … 4”);
return “页面: springboot is running … 4”;
}
}
然后运行Main,看控制台和浏览器输出(中文显示正常) … 停止。
1.1.5 IDEA隐藏文件
对比上面1.1.2和1.1.4会发现,手工创建的Module清爽很多。
可以把多余的文件删除,又担心会出什么问题,那么就可以把这些文件或目录隐藏。
菜单File -> Settings -> Editor -> File Types,右边标签页,点“+”将需要隐藏的文件名添加进去即可。例如.mvn,.gitignore,HELP.md等,可以用通配符 * ,使用通配符时注意别把需要的文件隐藏了。
1.1.6 入门案例解析:parent、starter
Spring Boot的目的是用来简化Spring应用的初始搭建及开发过程。
关键的pom.xml中可以看出,parent里定义的版本号2.7.5实际上就已经包含了几乎所有依赖包的版本号,经过测试,相互之间没有冲突。更改parent里的版本号,实际上相当于更换了了所有依赖包的版本号集合。
后面
后面
Maven会根据pom.xml定义的依赖,将相应依赖包的正确版本下载到本地Maven Repository里,因此第一次创建的时候会需要几分钟。如果后续再创建Spring Boot项目,只要主版本号没变,则不联网也可以创建成功。
其中最重要的是
总结:parent定义了所有Spring Boot项目要继承的依赖包版本号,主要是进行依赖管理,达到减少依赖冲突的目的。而starter定义了当前项目使用的所有依赖包,以达到减少依赖配置工作量的目的。
1.1.7 入门案例解析:引导类
以“1.1.4 手工制作版案例”生成的项目为例。将cn.zlz8x8.Main改写为如下:
package cn.zlz8x8;
import cn.zlz8x8.controller.BookController;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args);
//SpringApplicaiton.run 实际上是生成了一个Spring容器,也就是上下文Context
//项目里的其他 类(对象) 都是 bean 被放到了Spring容器里,如下
BookController beanBookController = ctx.getBean(BookController.class);
System.out.println(“这是一个Bean:” + beanBookController);
DemoUser beanDemoUser = ctx.getBean(DemoUser.class);
System.out.println(“这又是一个 bean:” + beanDemoUser);
}
}
为了上面代码最后两行正确执行,新建一个cn.zlz8x8.DemoUser类如下,空的,不需要执行任何功能,注意@Component不能少。
package cn.zlz8x8;
import org.springframework.stereotype.Component;
@Component
public class DemoUser {
}
然后执行Main看输出。可知引导类SpringApplication.run生成了一个Spring容器。
1.1.8 内嵌Tomcat
从自己的pom.xml里
如果不想用内嵌的Tomcat,或者想换成Jetty,则在我们自己的pom.xml里如下处理:
改为如上内容后,右侧Maven工具栏展开,点刷新,可以看到很快就下载了jetty包。
1.1.9 RESTful快速开发
第一步:REST简介
REST = Representational State Transfer
特点:隐藏接口的访问行为,无法通过地址得知对接口的操作;书写简化
根据REST风格对接口(资源)进行访问称为RESTful
传统风格访问接口描述形式:
http://localhost/user/getById?=1
http://localhost/user/saveUser
REST风格接口描述形式:
http://localhost/users | 查询全部用户信息 | GET(查询) |
---|---|---|
http://localhost/users/1 | 查询全部指定信息 | GET(查询) |
http://localhost/users | 添加用户信息 | POST(新增/保存) |
http://localhost/users | 修改用户信息 | PUT(修改/更新) |
http://localhost/users/1 | 删除用户信息 | DELETE(删除) |
用postman可以看到对接口有多种动作,Spring Boot支持的包括上述等8种。
到https://www.postman.com/注册一个免费用户,激活注册用的邮箱。就可以开始使用postman了。使用方式主要有三种:(1)在postman官网在线使用;(2)利用Chrome的插件在线使用;(3)下载postman的桌面程序在线使用。这三种方式都要求在线使用。本例下载了postman的Windows桌面程序,安装之后登录、在线使用。
第二步:RESTful入门案例
首先,采用复制的方式新建一个Module,如“1.2.1 模块Module复制”,名称为Springboot_01_06_rest,在其中新建一个类cn.zlz8x8.controller.UserController如下。
可以看出一个API主要有两部分:
@RequestMapping 首先指定API调用的路径,跟着是参数的调用形式。然后是调用的动作,POST、PUT、DELETE等。调用路径 /users/{userName} 对应的真实调用路径为http://localhost:8080/users/Tom,因为使用的内置Tomcat,默认端口是8080,对应的参数就是Tom。
@ResponseBogy 里面的方法就是获得API传参后如何处理,下面都只做了简单输出,实际项目则可以进行希望的操作。里面的@PathVariable指明参数取自路径后面的哪部分。
package cn.zlz8x8.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
@RequestMapping(value = “/users/{userName}”, method = RequestMethod.POST)
@ResponseBody
public String save(@PathVariable String userName){
System.out.println(“user save …” + userName);
return “{‘module’: ‘user save’}”;
}
@RequestMapping(value = “/users/{id}”, method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
System.out.println(“user delete …” + id);
return “{‘module’: ‘user delete’}”;
}
@RequestMapping(value = “/users/{userName}”, method = RequestMethod.PUT)
@ResponseBody
public String update(@PathVariable String userName){
System.out.println(“user update …” + userName);
return “{‘module’: ‘user update’}”;
}
@RequestMapping(value = “/users/{id}”, method = RequestMethod.GET)
@ResponseBody
public String getById(@PathVariable Integer id){
System.out.println(“user getById …” + id);
return “{‘module’: ‘user getById’}”;
}
@RequestMapping(value = “/users”, method = RequestMethod.GET)
@ResponseBody
public String getAll(){
System.out.println(“user getAll …”);
return “{‘module’: ‘user getAll’}”;
}
}
将这个模块运行起来。打开postman,可以发送不同的请求看结果以及IDEA控制台的输出。可以将若干个请求保存到一个collection里面,今后不需要重复输入,直接可以测试。本例中将对应上面5个API的请求保存到了一个名为Springboot_01_06_rest的集合里。
注意:
- 后期开发中,参数超过1个,以json格式为主,@RequestBody应用较广,用于接收json数据。
- 如果发送非json格式参数,选用@RequestParam接收参数,用于url地址传参或表单传参。
- 采用RESTful进行开发,如果参数较少,可以采用@PathVariable接收路径参数。
第三步:简化开发
复制生成的Springboot_01_06_rest里有一个cn.8x8.controller.BookController几乎是空的,将其改写如下,与上面的UserController进行对比。API的功能和调用方式完全一样,但是代码简洁了许多。
1、原来类名上有个@Controller,方法名上有个@ResponseBody,将所有方法名上的@ResponseBody合并提升到类名上。然后再将@Controller和@ResponseBody合并成了@RestController
2、原来方法名上相同的@RequestMapping(value = “/books” 合并提升到了类名上。剩下的方法动作 method = … 简化成了对应的@PostMapping、@DeleteMapping、@PutMapping和@GetMapping,里面的参数简化了相同路径部分(合并到了类名上面)。
package cn.zlz8x8.controller;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(“/books”)
public class BookController {
@PostMapping(“/{userName}”)
public String save(@PathVariable String userName){
System.out.println(“book save …” + userName);
return “{‘module’: ‘book save’}”;
}
@DeleteMapping(“/{id}”)
public String delete(@PathVariable Integer id){
System.out.println(“book delete …” + id);
return “{‘module’: ‘book delete’}”;
}
@PutMapping(“/{userName}”)
public String update(@PathVariable String userName){
System.out.println(“book update …” + userName);
return “{‘module’: ‘book update’}”;
}
@GetMapping(“/{id}”)
public String getById(@PathVariable Integer id){
System.out.println(“book getById …” + id);
return “{‘module’: ‘book getById’}”;
}
@GetMapping
public String getAll(){
System.out.println(“book getAll …”);
return “{‘module’: ‘book getAll’}”;
}
}
在postman里测试,在原来的测试集下建两个目录,对应Users和Books,然后将不同的请求保存到对应的目录里,方便今后测试,不用重复输入。
1.2 SpringBoot基础配置
1.2.1 模块Module复制
第一步:选定要复制的Module并简化
“1.1.2 官网创建版”里创建的springboot_01_02_quickstart是用官网Initializr创建的,把它作为要复制的目标。首先进行简化。
将pom.xml修改简化如下。主要修改的内容:
1、删除了
2、保留了
3、插件
<project xmlns=“http://maven.apache.org/POM/4.0.0” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”>
<java.version>1.8</java.version>
springboot_01_02_quickstart里面的代码文件cn.zlz8x8.Springboot0102QuickstartApplication.java和cn.zlz8x8.controller.BookController只有几行基础代码,不需要修改。非常长的名字可以在复制之后修改。
至此,要复制的Module就准备好了,这个Module以后就不动了,专门用来复制成新的模块。当然,每次从官网创建也可以。
第二步:复制
到IDEA工作空间的Springboot项目下,本例是D:\id-space\Springboot
复制文件夹springboot_01_02_quickstart到同一个目录,形成副本,然后将文件夹名称改为新的模块名称,springboot_01_06_rest,进入这个文件夹。
删除目录下的子目录.mvn,删除子目录target,删除除pom.xml之外的其他文件,最后只剩文件夹src和文件pom.xml,如下:
用其他文本编辑器,如VSCode等打开pom.xml,修改
第三步,IDEA导入
IDEA菜单File -> Project Structure,在下面Modules里面点击“+”Import Module添加一个模块,选中刚才复制生成的springboot_01_06_rest文件夹,弹出对话框注意要选中Maven类型。然后就完事了,导入顺利,没有报错。
此时主文件还是cn.zlz8x8.Springboot0102QuickstartApplication.java,在此文件上右键Refactor -> rename …,将名称改为Springboot0106RestApplication,就自动将文件里的类名等都相应更改了,如果项目里其他地方有引用,也一并改了。今后改类名、方法名、变量名都用Refactor,不要手工改。运行此文件,看效果。
模块复制完成。今后只用从第二步开始。
1.2.2 属性配置方式
默认内置的Tomcat端口是8080,比较麻烦。修改resources目录下的application.properties文件,打开看到是空的,添加server.port=80如下设置,启动项目,日志看到端口已变更为80,然后到postman修改调用url把8080端口号去掉,测试。
IDEA社区版修改application.properties没有高亮颜色、代码提示和补全,几个插件用了也没效果,关系不大。以后用yml配置,就有提示和代码补全了。需要安装插件Spring Boot Assistant,这跟之前的插件Spring Assistant不一样(这个插件现在已经没有了,改成了收费插件)。不同IDEA版本现象不一样,网上搜解决方法。
1.2.3 基础配置
上面的application.properties文件再加一行 spring.main.banner-mode=off
启动程序,发现控制台的Spring的字符画就没有了。也可以进行一些其他设置。
设置项非常多。到官网 https://spring.io/projects/spring-boot#learn 下面的Documentation,找到与正在用的版本最接近的版本,点右侧的Reference Doc
下一个页面找到下面附件中 Application Properties点进去就可以看到所有配置参数、解释、默认值等。
1.2.4 配置文件类型
application.properties
server.port=80
application.yml
server:
port: 80
application.yaml
server:
port: 80
Spring Boot配置文件的加载有先后顺序:yaml,yml,properties,后加载的会把先加载的覆盖。因此使用yml时,要先把properties移走。
上一小节中的resources目录下新建一个目录bak,把application.properties文件移进去,然后再新建一个application.yml文件。按前面格式设定端口,编辑时有代码提示和补全,运行,发现有效。
同样把yml移到bak目录,新建一个application.yaml,内容如上。测试。
今后的开发中,主要用yml格式进行配置。
1.2.5 yaml数据格式
Yaml优点:容易阅读,容易与脚本语言交互,以数据为中心,重数据轻格式。
扩展名:yml 或 yaml
Yaml语法规则:
- 大小写敏感
- 属性层级关系用多行,属性名(key)和属性值(value)之间用“冒号+空格”
- 使用缩进表示层级关系,同层级左侧对齐,缩进只能用空格不能用Tab
- 注释用#
对象与数组的格式与json类似,不赘述。下一小节有示例。
1.2.6 读取yml数据
下面的综合实例展示了:
- 读取单一属性数据
- 读取二级属性数据
- 读取数组元素数据
- 读取数组元素二级数据
- 读取引用数据
- 用env读取全部属性数据
- 使用类封装yml数据
步骤一:准备application.yml文件
server:
port: 80
spring:
main:
banner-mode: off
# 以下是自定义属性
country: China
province: 湖北
city: Wuhan
user1:
name: cat
age: 29
married: true
user2:
name: dog
age: 20
# 数组,其中有数据引用,与顺序无关
hobbies:
- video ${habbits[0]}
- basketball
- swiming
# 数组简单形式,双引号内可解析转义字符
habbits: [game, “mu\t\nsic”, sleep]
# 对象数组
users1:
- name: Alton John
age: 65
birthday: 1949-10-01
- name: Poppy Alex
age: 19
# 对象数组简单形式
users2: [{name: Tylor Swift, age: 24, birthday: 2000-11-11}, {name: 李小龙, age: 46}]
步骤二:准备User1.java封装yml结构化数据
首先定义类的变量,然后可以用IDEA自动生成get,set,toString方法的代码。
package cn.zlz8x8.controller;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/* 定义User1类封装yml文件中对应的结构化数据
* 定义User1类为Spring管理的bean,头上加@Component
* 指定加载的数据,@ConfigureationProperties
*/
@Component
@ConfigurationProperties(prefix = “user1”)
public class User1 {
private String name;
private int age;
private Boolean married;
@Override
public String toString() {
return “User1{” +
“name='” + name + ‘'’ +
“, age=” + age +
“, married=” + married +
‘}’;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Boolean getMarried() {
return married;
}
public void setMarried(Boolean married) {
this.married = married;
}
}
步骤三:改写BookController.java
package cn.zlz8x8.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(“/books”)
public class BookController {
//读取yml数据
@Value(“${province}”)
private String country; // 上面定义的属性名不需要与变量名一致,数据为中文“湖北”
@Value(“${user1.age}”)
private int age;
@Value(“${habbits[1]}”)
private String hab1;
@Value(“${users1[0].birthday}”)
private String user1birth;
@Value(“${hobbies[0]}”)
private String hob1;
//使用自动装配,将所有yml里的数据读取到env中
//注意有多个Environment类,选择 org.springframework.core.env
@Autowired
private Environment env;
// 使用类封装yml数据,使用自动装配@Autowired
@Autowired
private User1 myUser1;
@GetMapping
public String getAll(){
System.out.println(“book getAll …”);
System.out.println("从yml文件中读取的单一属性数据:country ====> " + this.country);
System.out.println("从yml文件中读取的二级属性数据:user1.age ====> " + this.age);
System.out.println("从yml文件中读取的数组元素数据:habbits[1] ====> " + this.hab1);
System.out.println("从yml文件中读取的数组元素二级数据:users1[0].birthday ====> " + this.user1birth);
System.out.println("从yml文件中读取的引用数据:hobbies[0] ====> " + this.hob1);
System.out.println("用env读取全部数据并取出users2[1].name ====> " + env.getProperty(“users2[1].name”));
System.out.println("使用类封装的yml数据:User1 ====> " + myUser1.toString());
return “{‘module’: ‘book getAll’}”;
}
@PostMapping(“/{userName}”)
public String save(@PathVariable String userName){
System.out.println(“book save …” + userName);
return “{‘module’: ‘book save’}”;
}
@DeleteMapping(“/{id}”)
public String delete(@PathVariable Integer id){
System.out.println(“book delete …” + id);
return “{‘module’: ‘book delete’}”;
}
@PutMapping(“/{userName}”)
public String update(@PathVariable String userName){
System.out.println(“book update …” + userName);
return “{‘module’: ‘book update’}”;
}
@GetMapping(“/{id}”)
public String getById(@PathVariable Integer id){
System.out.println(“book getById …” + id);
return “{‘module’: ‘book getById’}”;
}
}
然后运行,看控制台输出。
1.3 基于SpringBoot实现SSM整合
1.3.1 官网创建新模块
本小节内容可选。
从官网创建新模块的目的是为后面的内容生成一个干净的基准模块。
如下图所示,Spring Boot版本已经升到了2.7.6,另外除了基本Spring Web的依赖包,还选择了Spring Boot Dev Tools包和Spring Configuration Processor包。
选择后两个包的目的是想试一下Dev Tools好不好用,另外application.properties会不会出现代码提示和补全。结果不理想。又从pom里把这两个包删除了。
不过从这里可以看出,生成模块时选择依赖包是没关系的,今后可以很方便地在pom增加或删除依赖包。
生成的springboot_base_quickstart模块导入IDEA,然后小修改一下:
- 在pom里删除项目的name和description,这样IDEA就只认artifactId了
- 在pom里删除不需要的包,只留下最基本的starter-web和starter-test
- 把application.properties改名(用refactor -> rename)为application.yml,这样配置文件里的代码提示和补全就有了。
模块里除了main和test里各有一个类,其他类都没有,很干净。
新模块导入IDEA后,Maven开始下载依赖包,大概几分钟。然后把之前的模块在pom里把parent的版本号改为2.7.6,很快就行了,因为2.7.6的依赖包已经下载。并且之前的2.7.5的包就都没有了。如果项目里各模块的Spring Boot主版本不一样,那么各个版本对应的依赖包都会下载到Maven本地库里。
1.3.2 整合Junit
首先复制一个模块备用。
在IDEA工作目录把上一节中的springboot_base_quickstart目录复制到同一个目录,改名为springboot_04_junit,然后进入该目录,除了src文件夹和pom.xml,其他都删除。然后修改pom.xml的artifactId为springboot_04_junit,在IDEA导入该模块。
用Refactor -> rename改名SpringbootBaseQuickstartApplication.java为Springboot04JunitApplication.java,弹出对话框询问是否更改对应的test主类,把test主类勾上,然后点确定按钮,这样两个主类的名称都改了。
通过改名发现Junit其实已经集成到Spring Boot里了,用就行了。
第一步:新建要测试的对象和方法
新建cn.zlz8x8.dao.BookDao.java,对话框里选interface而不是class,然后手写一个方法save,并不执行任何操作。生成的文件如下:
package cn.zlz8x8.dao;
public interface BookDao {
public void save();
}
新建cn.zlz8x8.dao.impl.BookDaoImpl.java,这次是选class,然后实现上面接口的方法,在控制台打印一句话。注意类头上加@Repository,表明这是一个受Spring管理的bean,生成的文件如下:
package cn.zlz8x8.dao.impl;
import cn.zlz8x8.dao.BookDao;
import org.springframework.stereotype.Repository;
@Repository
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println(“Message from BookDaoImpl …”);
}
}
第二步,改写test主类
改写test主类Springboot04JunitApplicationTests.java,如下。注意导入要测试对象时,头上加@Autowired表示自动装配。注意主类头上的@SpringBootTest,表明这是一个Spring Boot的测试类。注意import的包,就包括了org.junit
package cn.zlz8x8;
import cn.zlz8x8.dao.BookDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class Springboot04JunitApplicationTests {
// 1.注入要测试的对象
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
// 2.执行要测试的对象的方法
bookDao.save();
}
}
类名、方法contextLoads()旁边都有运行按钮,随便哪一个。运行后控制台显示相应的消息,并且会显示Tests passed 测试通过。与之前运行Spring Boot主类不同,不需要停止或重启,测试运行后自动就停止了。
第三步,关于classes属性
将测试主类Springboot04JunitApplicationTests.java拷贝到cn包下,在原主类(位于cn.zlz8x8下)上右键Refactor -> copy class … 弹出对话框中将包修改为cn
运行新拷贝的测试类,发现报错。修改代码如下,就OK了。
报错的原因是测试类在test下的同级包中找哪个类头上有@SpringBootApplication,显然原来的测试类在cn.zlz8x8下,与main下的主类Springboot04JunitApplication在同级包下,可以找到。拷贝后的测试类提升了一级就找不到了,则需要如下指定。指定的方法有两种,如下注释,第二种方法两行@与第一种方法效果一样。
package cn;
import cn.zlz8x8.Springboot04JunitApplication;
import cn.zlz8x8.dao.BookDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(classes = Springboot04JunitApplication.class)
// @SpringBootTest
// @ContextConfiguration(classes = Springboot04JunitApplication.class)
class Springboot04JunitApplicationTests {
// 1.注入要测试的对象
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
// 2.执行要测试的对象的方法
bookDao.save();
}
}
1.3.3 整合MyBatis
本节内容涉及MySQL数据库,先按顺序看完并实现“附录一、Vmware安装CentOS7”和“附录二、CentOS7安装MySQL”就有了一个MySQL数据库服务器。
数据库类型:MySQL 8.0
数据库连接:mysql://192.168.138.21:3306/ssm_db
用户名:ssmaster
密码:1gE=M!ka
数据表:tbl_book,字段id(主键,自增,不需要值),type(字符串),name(字符串),description(字符串)。已经有2条数据。
第一步:复制导入新模块
从“1.3.1官网创建新模块”springboot_base_quickstart复制出一个新模块springboot_05_mybatis,只保留src文件夹和pom.xml,并将pom.xml中artifactId修改为springboot_05_mybatis,在IDEA中导入。Refactor修改主类方法名为Springboot05MybatisApplication,并勾选自动修改测试主类方法名。
第二步:引入相关依赖包
修改pom.xml如下,增加了mybatis和mysql driver依赖。刷新一下Maven,就会自动分析并下载相应的依赖包。注意mybatis版本号与视频课里不一样。
<project xmlns=“http://maven.apache.org/POM/4.0.0” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd”>
<java.version>1.8</java.version>
自己手工怎么知道如何写mybatis和mysql的依赖?
(1)IDEA正式版中用Spring Initializr生成模块的时候,勾选上mybatis和mysql driver依赖,生成的pom.xml里就有了。
(2)使用官网Initializr生成模块,也勾选上mybatis和mysql driver
手工写的时候,可以参考上面两种方式生成的pom.xml
第三步:配置相关信息
修改application.yml如下,可以看到,多了spring.datasource一段。其中driver-class-name的值与视频课里讲的不一样,mysql-connector 8开始就用如下这样的驱动了。
server:
port: 80
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.138.21:3306/ssm_db
username: ssmaster
password: 1gE=M!ka
第四步:编写测试代码
(1)新建一个实体类cn.zlz8x8.domain.Book,只需要定义出与数据库tbl_book表中字段对应的四个属性就可以,后面的toString和setter,getter代码都可以自动生成。
package cn.zlz8x8.domain;
public class Book {
private Integer id;
private String type;
private String name;
private String description;
@Override
public String toString() {
return “Book{” +
“id=” + id +
“, type='” + type + ‘'’ +
“, name='” + name + ‘'’ +
“, description='” + description + ‘'’ +
‘}’;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
(2)新建一个接口类cn.zlz8x8.dao.BookDao,注意接口类头上的@Mapper和方法名上的@Select,方法并没有方法体,通过@Select里面的SQL查询语句实现了。
package cn.zlz8x8.dao;
import cn.zlz8x8.domain.Book;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper
public interface BookDao {
@Select(“select * from tbl_book where id = #{id}”)
Book getById(Integer id);
}
(3)改写测试类,运行测试
package cn.zlz8x8;
import cn.zlz8x8.dao.BookDao;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class Springboot05MybatisApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
System.out.println(bookDao.getById(2));
}
}
代码编辑器左边点击运行按钮,运行这个测试类。看结果
到此整合MyBatis的实例完成。回过头看,没有用到spring-boot-starter-web依赖,也没有用到application.yml里的server.port=80的配置,这两项都可以删掉,留着也行。
1.3.4 整合MyBatis常见问题
主要讲的是在设置数据源时
com.mysql.jdbc.Driver 是MySQL connector 5 的写法
com.mysql.cj.jdbc.Driver 是MySQL connector 8的写法,本例中就是这样写的
第二个问题,是使用了8的驱动,会出现没有设置时区的报错,解决方法是在url里加上时区设置:
url: jdbc:mysql://192.168.138.21:3306/ssm_db?serverTimezone=UTC
url: jdbc:mysql://192.168.138.21:3306/ssm_db?serverTimezone=Asia/Shanghai
本例中没有设置时区,并没有报错。
1.3.5 整合MyBatisPlus
MyBatis-Plus与MyBatis的区别:导入依赖不同,数据层实现简化
Spring官方并没有把MyBatis-Plus纳入其主要可选依赖,在定义pom依赖的时候,可以从阿里云Initializr里导入MyBatis-Plus依赖,然后看其pom里是怎么写的。
另外:**https://mvnrepository.com/ 是Maven库的大本营,可以去查!!!
二、实用篇
前置知识:
- Linux(CentOS 7),熟悉常用Linux基础命令,熟悉Linux系统目录结构
- 使用开发技术:缓存:redis、MongoDB;消息中间件:RocketMQ、RabbitMQ
2.1 运维实用篇
学习目标:
- 能够掌握SpringBoot程序多环境开发
- 能够基于Linux系统发布SpringBoot工程
- 能够解决线上灵活配置SpringBoot工程的需求
2.2 开发实用篇
学习目标:
- 能够基于SpringBoot整合任意第三方技术
三、原理篇
前置知识:
- 了解Spring加载bean的各种方式
- 知道Spring容器底层工作原理,能够阅读简单的Spring底层源码
学习目标:
- 掌握SpringBoot内部工作流程
- 理解SpringBoot整合第三方技术的原理
- 实现自定义开发整合第三方技术的组件
附录一、Vmware安装CentOS 7
本例中采用虚拟化软件VMware Workstation安装CentOS 7-2009(最小安装minimal)。实际应用中,单个服务器一般都设定为单一功能,比如Web服务器,数据库服务器,LDAP服务器等,或者多台服务器分布式部署云计算组件如Hadoop等,单个服务器只需要操作系统的基本功能,因此CentOS最小化安装符合需求,如果需要额外的功能,可以在使用过程中增加。云服务提供商(例如阿里云)提供的云服务器操作系统一般是CentOS minimal。
本例CentOS安装环境如下:
主机(Host Machine):CPU 20核,内存32G,操作系统Windows 11家庭版64位
虚拟化软件:VMware Workstation 16 pro
到 https://www.centos.org/ 下载安装包,本例是CentOS-7-x86_64-DVD-2009.iso
1.1 安装前Vmware设置
1、在VMware菜单“编辑-首选项”可以设置虚拟机默认放置的目录,应选择有足够空间的硬盘分区。本例中是 D:\MyVM
2、创建虚拟机采用“自定义(高级)”配置,选择安装来源时,载入CentOS的ISO后,VMware会自动识别出操作系统类型和版本。选择“稍后安装操作系统”不采用简易安装,而采用手动安装。后面“客户机操作系统”选择Linux,下拉框选择CentOS 7 64位。
3、虚拟机名称 CentOS7-min,选择 D:\MyVM\CentOS7-min作为存储位置
4、为虚机分配处理器1个,内核数量1个,2G内存。本例中这个虚拟机实例是作为干净基准系统,具体的应用虚拟机可以克隆这个虚拟机,不用重新安装。分配的CPU核数,内存数在克隆后可以在Vmware里修改。实验用虚机一般1核2G内存即可,可租用的轻量级云服务器一般是1核1G内存。实际应用虚机则根据需要分配资源,计算单元则对CPU要求较高,内容服务器则对内存要求较高。
5、使用NAT网络(默认选项),虚机没有与主机同级的IP地址。
桥接,NAT,仅主机模式,三者的简要区别如下:
(1)桥接:虚机与主机在网络中地位一样,虚机拥有与主机同级的独立IP地址。
(2)NAT:虚机共享主机的IP地址访问Internet,同一个主机中的各个虚机在同一网段中,可互相访问。外部无法直接访问虚机,但可通过主机的转接访问虚机。
(3)仅主机模式:同一主机中的各个虚机可互相访问,虚机无法访问Internet,外部也无法访问虚机。
6、I/O类型:默认LSI Logic,磁盘类型:默认SCSI,选择磁盘:创建新虚拟磁盘。
7、分配20G虚拟磁盘空间,存为多个文件(默认选项)。没有勾选“立即分配所有磁盘空间”,会稍微影响虚机的速度。
8、指定虚机磁盘文件,保持默认(拆分成多个文件)。方便虚拟机的拷贝。
9、开始安装时,可能会提示要更改BIOS设置以支持64位操作系统之类的,按照提示修改主机BIOS设置,再回来安装。
注意:一般新的电脑无需设置自动支持64位虚拟化,有些电脑需要在BIOS里设置以支持64位虚拟化,有些更旧的电脑完全不支持64位虚拟化,则无法在VMware里安装64位的操作系统。
如上完成新建虚拟机设置。会出现该虚拟机配置画面,点击“编辑虚拟机设置”,打开对话框,核对硬件配置。如果CD/DVD是自动检测,则选择“使用ISO印象文件”,并选中CentOS的安装镜像文件。
然后点击上图中的“开启此虚拟机”,开始安装。
开始安装后,窗口下面会出现“我已完成安装”,不要点,等安装完了再点。
1.2 安装过程
注意:安装过程中,鼠标点击虚机界面即可进入虚机操作,组合键ctrl + alt 可使鼠标返回主机。在VMware Workstation窗口的左下角会有提示。
1、安装过程与在真实裸机上安装一样,初始界面按键“i”选择“Install CentOS”,然后回车进入安装过程。
2、选择安装过程中的语言:保持默认 English - Englisth (United States)
3、如下图所示,设置安装选项:
Date & Time 选到 Asia / Shanghai
Language Support 可以把中文,简体中文(中国)选上
Software Selection 保持Minimal Install不变
Installation Destination 需要点开,默认是自动配置磁盘,不需要修改,直接点“Done”按钮返回即可,黄色的感叹号才会消失,此界面右下角“Begin Installation”按钮才会亮起。
Network & Hostname 点进去,如果有显示有线网络ens33之类的,打开ON
KDUMP可以设置为Disabled,保持默认也可以。
设置完成后,点击右下角“Begin Installation”按钮开始安装。
4、安装的过程中给root用户设置密码(4geT%not),如果密码太弱,需点击两次确定才能完成操作。
新建一个用户admin(密码d00r%Key),勾选“Make this user administrator”,今后的系统管理员用户。如果密码太弱,需点击两次确定才能完成操作。
安装完成,点击“Reboot”重新启动。
5、系统是最小化安装,没有GUI,以root登录,安装完成。
关闭虚拟机后,可以编辑虚拟机设置。把CD/DVD 改回为自动检测。
关闭虚机后,可以编辑虚机设置,修改CPU核数,硬盘大小,内存等。
小技巧:虚机屏幕有时候不匹配VMware的窗口,需要拉动窗口的滚动条才能看见全部的虚机屏幕内容。或者,虚机屏幕太小,Vmware经常自动改变窗口大小去适应虚机。从VMware菜单“编辑 - 首选项 - 显示”,把“自动适应窗口”前的勾去掉(自动适应下面的两个选项都不勾)。然后再开启此虚机,可解决这个问题。
1.3 忘记root密码
下面是CentOS 7的root密码修改,一般情况可略过。
开机按ESC
选择CentOS Linux (3.10.0-693…) 按 e键
光标移动到 linux 16开头的行,找到 ro改为 rw init=sysroot/bin/sh
按 Ctrl+x执行
进入后输 chroot /sysroot
输入 passwd
根据提示输入2次新密码
完成后输入 touch /.autorelabel 更新系统信息
exit
reboot重启
重启过程慢,耐心等等
重启后用新密码登录
1.4 安装后设置
1.4.1 关于用户
目前系统里有2个用户,root是超级管理员;admin是系统管理员。
系统提示符为 # 表明用户为root,提示符为$ 表明用户为其他用户。
每个用户都有自己的主目录,以 ~表示,root用户是 /root,其他用户是 /home/用户名。例如admin输入命令 cd ~ 则会进入其主目录 /home/admin
admin需要执行root权限的命令时,可以用 sudo 临时获得权限,也可以用 su 切换身份为root。
使用sudo时,需要输入admin用户自己的密码,使用 su时,需要输入root用户的密码,使用“sudo su”则可以使用admin自己的密码切换到root用户身份,在root用户没有设置密码时,这个方法很好用。
1、使用sudo不需要输入密码
$ sudo visudo -f /etc/sudoers
文件编辑的方式与vi一样,进入界面后,按i进入编辑(insert)模式,左下角会有INSERT提示。移动光标修改内容。修改完毕后按ESC进入命令模式,输入 :w 回车,就保存,再输入 :q 回车就退出。或者输入 :wq 一次性保存退出。
如下修改内容,在 %wheel ALL=(ALL) ALL 前加注释符#,去掉 %wheel ALL=(ALL) NOPASSWD:ALL 前的注释符。保存退出就行了。用户admin 命令exit退出,然后再登录,就发现已经生效,使用sudo不需要输入密码了。
这是针对wheel这个组的设置,这个组的成员都不需要输入密码就可以使用sudo,admin是wheel组的成员。
传统修改方法是在 root ALL=(ALL) ALL 下面增加一行 admin ALL=(ALL) NOPASSWD:ALL 但在这里会被后面的 %wheel ALL=(ALL) ALL 覆盖掉。原因是在安装过程中,创建 admin用户时使其成为管理员,便成为了 wheel组的成员。系统只允许wheel组的用户来执行“su”命令登录为root用户,而让其他组的用户即使执行“su”、输入了正确的root密码,也无法登录为root用户。
用visudo编辑sudoers文件是正确的做法。有些做法是增加文件sudoers的写权限,用vi修改,再去掉其写权限。可能会出现文件权限错乱,如下恢复sudoers文件的正确属性:
$ sudo chmod 0440 /etc/sudoers
1.4.2 配置静态IP地址
第一步:在Vmware里确认网络配置
菜单“编辑”-“虚拟网络编辑器”,这个界面,有很多网络文章说要修改,其实不用。选中列表里的Vmnet8(NAT模式),只需要看一下子网IP 192.168.138.0 及 子网掩码 255.255.255.0 记住就行了。“使用本地DHCP服务将IP地址分配给虚拟机”前面的勾不用去掉。
然后确认一下虚拟机的网络适配器是否是NAT,安装的时候默认就是这项。如果不是,就在虚拟机关机状态下,编辑虚拟机设置,改为NAT。
在Vmware里只需要确认上述配置就行了,不用做任何修改!
第二步:在虚拟机设置静态IP
以root用户登录虚拟机,下面的命令都不带sudo了。
vi /etc/sysconfig/network-scripts/ifcfg-ens33
因为是虚拟机,所以配置脚本文件是ens33这样的,如果是在物理机上的CentOS,则会是eth0这样的,可以先到目录里看一下是否有这个文件,再编辑。
如下修改文件,保存退出。首先将BOOTPROTO改为static,然后增加下面的内容,设置静态IP,网关,DNS,注意要和上面的Vmware里的一致。
这里设置的网关是 192.168.138.2 而不是习惯上的 192.168.138.1 这是Vmware的内外网隔离措施。而 192.168.138.1 是从虚拟机角度看到的主机的IP地址。
重启网络服务 service network restart
测试网络是否通了 ping www.baidu.com 信息滚动过程中可以用Ctrl + C中断
然后从主机开一个命令行窗口 ping 192.168.138.11 能通,就说明双向OK了。
1.4.3 安装常用工具
前提是网络连接没有问题。
更新系统(可选):yum update
没想到新下载的CentOS7-2009,更新居然有255M,现在比较智能,会找最快的镜像站点,大概更新用了5分钟。
因为是最小化安装,很多工具没有,安装常用工具:
yum -y install perl gcc kernel-devel wget
yum -y install yum-utils
yum -y install net-tools
yum -y install unzip zip
安装了上面的net-tools以后,就有ifconfig命令了,试一下
ifconfig
可以看到自己的静态IP地址
更新完毕后,可以重新启动一下系统 systemctl reboot
1.5 用Putty连接虚拟机上传下载文件
到Putty官网https://putty.org/,选第一个Download PuTTY,下面是第三方项目。
下载64-bit x86版本,形如putty-64bit-0.77-installer.msi的安装文件。
安装完成后,有多个程序,首先运行Putty,输入IP地址,点open就可以连接。
连接后以root身份登录,可以看到显示的主机IP是192.168.138.1,命令exit可以退出登录,断开连接。
然后运行PSFTP,窗口中输入open 192.168.138.11 进行连接,以root登录,可以看到提示当前工作路径是 /root,命令exit可以退出登录,断开连接。
以后可以在虚拟机开机状态下,关闭Vmware,选择让虚拟机后台运行,然后用Putty连接进行操作,上传下载文件。
需要在虚拟机里安装JDK,安装文件为主机 D:\software\jdk-8u351-linux-x64.rpm,这个文件是事先从Oracle网站下载来的。打开PSFTP连接,root登录。使用put命令将文件上传到虚拟机 /root 目录下。注意路径分隔符使用 / 而不是Windows风格的 \,然后ls命令查看虚拟机上是否有这个文件了。exit退出,断开连接。
1.6 密钥方式连接虚机
密钥形式登录的原理是:利用密钥生成器制作一对密钥——一只公钥和一只私钥。将公钥添加到服务器的某个账户上,然后在客户端利用私钥即可完成认证并登录。这样一来,没有私钥,任何人都无法通过 SSH 暴力破解你的密码来远程登录到系统。此外,如果将公钥复制到其他账户甚至主机,利用私钥也可以登录。
第一步:制作密钥对
在虚机上制作密钥对。首先用root登录,然后执行以下命令:
ssh-keygen <== 建立密钥对
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): <== 回车
Created directory ‘/root/.ssh’.
Enter passphrase (empty for no passphrase): <== 输入密钥锁码,或回车
Enter same passphrase again: <== 再输入一遍密钥锁码,回车
Your identification has been saved in /root/.ssh/id_rsa. <== 私钥
Your public key has been saved in /root/.ssh/id_rsa.pub. <== 公钥
The key fingerprint is:
…
The key’s randomart image is:
…
现在,在 /root 生成了一个 .ssh 的隐藏目录,内含两个密钥文件,id_rsa 为私钥,id_rsa.pub 为公钥。
密钥锁码在使用私钥时必须输入,这样就可以保护私钥不被盗用。本例中没有密钥锁码,方便使用。
第二步:在虚机上安装公钥
键入以下命令,在服务器上安装公钥:
cd .ssh
cat id_rsa.pub >> authorized_keys
如此便完成了公钥的安装。为了确保连接成功,请保证以下文件权限正确:
chmod 600 authorized_keys
chmod 700 ~/.ssh
第三步:虚机开启密钥登录
执行命令vi /etc/ssh/sshd_config,如下找到PubkeyAuthentication yes这一项,把前面的注释符号去掉。如果要禁用密码登录方式,则把下面的PasswordAuthentication改为no,本例中没有改,保留了密码登录方式。
保存,退出编辑。重启ssh服务systemctl restart sshd
第三步:用PSFTP下载私钥到主机
用PSFTP密码登录方式连接虚机,下载id.rsa到本地重命名192.168.138.11.rsa
第四步:将密钥导入到Putty
首先打开PuttyGen,点Load按钮,选择文件对话框里的文件类型默认是*.ppk,改为*.*,找到刚才的192.168.138.11.rsa,就导入成功了,提示是旧的pem格式。
然后点击Save private key,保存为192.168.138.11.ppk,与刚才的文件最好在同一文件夹下,询问是否要个锁码,不理他。
关闭PuttyGen,打开Putty,左侧选择Session,右边填写Host Name为root@192.168.138.11,这里指定了登录用户为root,如果为其他用户则改为其他用户名。然后下面Saved Sessions空格里填上一个名字vm-192.168.138.11,点右侧Save就保存了。
然后左侧Connection - SSH - Auth,直接点Auth不用展开,右边Browse找到刚才保存的192.168.138.11.ppk
回到上一张图的Session,选中vm-192.168.138.11的情况下,点Save,一定要保存,否则下次又要找密钥。然后点下面的Open就连接成功了,不需要输入密码,直接root登录成功。
今后要连接的时候,打开Putty,选中保存的vm-192.168.138.11,点Load,然后点下面的Open就可以连接上了。
主机运行Putty组件Pageant,会在Windows右下角出现一个常驻的代理,从中可以快速连接已经保存的session或者进行一些密钥操作。
1.7 安装JDK8
前面“1.5 用Putty连接虚拟机上传下载文件”已经把JDK安装文件上传到 /root目录下了,执行 rpm -ivh jdk-8u351-linux-x64.rpm就可以安装JDK了。
完成后执行java -version看到版本号就说明OK了
命令alternatives --config java可以看到系统里有几个JDK,并设置默认JDK,本例只有一个,回车保持默认。
vi /etc/profile
在文件最后添加
export JAVA_HOME=/usr/java/default
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
注意CLASSPATH=后面是个英文句号,这样设置可以解决很多命令行下运行java程序找不到类的问题。
Oracle JDK安装后,在安装目录 /usr/java/ 下会生成3个目录。其中一个是真实的目录jdk1.8.0_351-amd64、目录链接latest表示最新版本、目录链接default表示默认版本。当前latest 指向真实的目录,default 指向 latest。上面的 JAVA_HOME 使用了 default目录,今后如果有多个版本,默认版本有变化,只需要修改default的指向就可以了,不需要修改系统变量。
注销当前用户,重新登录,执行下面命令验证各变量正确:
echo $JAVA_HOME
echo $CLASSPATH
java -version
附录二、CentOS7安装MySQL
2.1 克隆虚机
上一章已经创建了一个虚机CentOS7-min,更新了系统,安装了常用工具,设置了密钥连接,安装了JDK8,为此虚机创建一个快照。菜单“虚拟机 - 快照 - 拍摄快照”,输入名字和描述就行了。
菜单“虚拟机 - 管理 - 克隆”,克隆源选择“现有快照”,找到刚才拍摄的快照。
克隆类型选择“创建完整克隆”
输入虚机名称CentOS7-mysql,确认保存位置,完成。
2.2 设置虚机
开启新的虚机CentOS7-mysql,以root登录,首先要修改的是静态IP地址。
vi /etc/sysconfig/network-scripts/ifcfg-ens33
将静态IP地址改为192.168.138.21就行了,其他的不用动。
重启网络服务service network restart
虚机ping www.baidu.com,主机ping 192.168.138.21都OK
参照“1.6密钥方式连接虚机”,打开Putty,在Session里新建保存一个名称为db-192.168.138.21,连接地址为root@192.168.138.21,左侧Connection - SSH - Auth,直接点Auth不用展开,右边Browse找到刚才保存的192.168.138.11.ppk(就是这个旧的密钥,不需要到虚机上创建新的密钥对了,因为是克隆的,所有信息都一样)
Save,Open 连接成功。
一般安全起见,新的虚机要创建新的密钥对。本例直接使用了旧的密钥,简便。
2.3 安装MySQL
2.3.1 安装MySQL8
到MySQL官网,下载MySQL Yum Repository,操作系统是CentOS7,要安装的MySQL8.0,因此下载到的对应版本是mysql80-community-release-el7-7.noarch.rpm
下载需要登录。注册一个免费的MySQL或Oracle账号即可,以后用得着。
用PSFTP将文件上传到虚机 /root 目录下。
安装yum库:rpm -Uvh mysql80-community-release-el7-7.noarch.rpm
安装MySQL:yum install mysql-community-server
中间可能有几个需要确认的地方,输入y回车即可。这个版本只有80M左右,非常快,不到1分钟就安装完毕。
查询mysqld的状态systemctl status mysqld.service
如果是inactive(active是绿色的)则启动之systemctl start mysqld.service
启动完毕再查询状态systemctl status mysqld.service,正常
查看安装过程中生成的随机密码,并以此密码登录mysql
grep ‘temporary password’ /var/log/mysqld.log
可以看到下面的z6iv!b7Q8Zjt就是临时密码
以临时密码登录MySQL,如下命令,提示输入密码时输入临时密码
mysql -u root -p
进入MySQL后,修改root(这个root用户是MySQL的用户)密码,大小写,数字,符号,8位,否则提示密码不合要求
alter user ‘root’@’localhost’ identified by ‘sql=R00T’;
命令quit或exit退出MySQL,然后用新密码登录MySQL成功。
开启3306端口:firewall-cmd --zone=public --add-port=3306/tcp --permanent
配置立即生效:firewall-cmd --reload
以后会用到的其他防火墙命令:
关闭端口firewall-cmd --zone=public --remove-port=5672/tcp --permanent
查看所有开放端口firewall-cmd --zone=public --list-ports
查看防火墙状态firewall-cmd --state
关闭防火墙systemctl stop firewalld.service
查看所有监听端口netstat -lnpt
重启虚机reboot,查询mysqld的状态systemctl status mysqld.service
发现是active的,说明MySQL服务是随系统启动而启动的,一切正常。
到此,MySQL安装完毕,初始化配置root密码完毕。关闭虚机,拍摄快照,启动虚机,以后没事就不再安装MySQL了。
(1)此虚机将作为数据库服务器长期保持运行,关闭Vmware界面时让其后台运行。今后操作MySQL以远程为主,比如用IDEA里的database navigator
(2)MySQL有其备份方式,定期备份保障数据安全。另外,此虚机也可定期拍摄快照,如遇系统级故障,可以用快照恢复。
2.3.2 特殊故障
MySQL一段时间不操作则服务停掉。有时几天,有时十几天。
参考解决方法:https://124654439.iteye.com/blog/2174953
注意该文章的后半部分,否则就白看了。关键点是修改参数要带 global
以root身份连接登录进mysql
mysql> show global variables like ‘wait_timeout’;
mysql> set global interactive_timeout= 31536000;
mysql> set global wait_timeout=31536000;
在MySQL8.1的版本有这个问题,此方法可以解决。
如果没这个问题,则略过。
2.3.3 建立数据库、用户、表、数据
数据库服务器建好后,一般远程操作。这里仅展示在服务器上的基本操作。
本例中建立的库、用户、表、数据是为了配合前面的Spring Boot案例。
用root登录MySQL,建立一个数据库ssm_db,建立一个用户ssmaster,然后把数据库ssm_db的所有权限赋予ssmaster
mysql -u root -p
输入root的密码登录,下面的命令都是MySQL里了
mysql> create database ssm_db DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
mysql> create user ssmaster@‘%’ identified by ‘1gE=M!ka’;
mysql> create user ssmaster@localhost identified by ‘1gE=M!ka’;
mysql> grant all on ssm_db.* to ssmaster@‘%’;
mysql> grant all on ssm_db.* to ssmaster@localhost;
mysql> quit;
库和用户都建好了,然后用ssmaster登录MySQL
mysql -u ssmaster -p
输入用户ssmaster的密码,下面的命令都是MySQL里了
mysql> use ssm_db;
mysql> CREATE TABLE IF NOT EXISTS tbl_book(id INT UNSIGNED AUTO_INCREMENT,type VARCHAR(100) NOT NULL,name VARCHAR(100) NOT NULL,description VARCHAR(200),PRIMARY KEY (id))DEFAULT CHARSET=utf8;
mysql> INSERT INTO tbl_book(type,name,description) VALUES (‘novel’,’Learning Spring Boot’,’How to coding with Spring Boot.’);
mysql> select * from tbl_book;
可以看到表建好了,并且插入了一条数据。id是自增的,不需要输入。
mysql> quit;
2.3.4 远程操作数据库
IDEA社区版安装Database Navigator插件就可以远程操作数据库了。
一般工具栏在左侧,点开后,点绿色 + 号新建一个MySQL连接如下。输入Name不一定要与数据库名一致,Description可以留空,Host填写IP地址,确认端口号是3306,Database填上面创建的库ssm_db,下面的用户名密码填上面创建的用户名密码,Driver用内置库。可以先点Test Connection按钮测试一下连接,显示成功。然后点最下面的OK,这个数据库连接就完成了。
连接建好后,就可以看到ssm_db的整个结构,并可以进行建表,修改数据等操作。
一般对数据库进行操作,是通过SQL方式。点击Open SQL console按钮打开SQL的控制台,在控制台输入如下,插入一条数据
insert into tbl_book(type,name,description) VALUES (‘技术’,’大学物理’,’全国通用大学物理教程’);
点Execute Statement就可以执行这条SQL语句。执行完毕,就生效了,另外两个按钮Commit和Rollback还亮着,说明这条SQL语句还没有正式提交数据库,可以回滚。点击Commit按钮正式提交,然后Commit和Rollback两个按钮就灰了。
再输入select * from tbl_book; 执行,就可以看到查询出的数据。
完结撒花!