Spring学习笔记
Spring学习笔记
一定要区分mapper,service,和controller
- mapper是用来控制数据库
- service主要实现业务逻辑
- controller与前端交互
MVC模式
- controller,view,model分别对应一个文件夹
前端后端,分离不分离的区别
- 每一个用户操作的就是客户端
- 后端是用spring搭建
- 前端有两个可以搭建的方式:web和app
- 用户打开网页,本质是向服务器发送了一个链接(请求),服务器接收到了请求之后,会返回一个页面,这个页面是以字符串表单的形式返回的,浏览器接收之后会自动转化
- 前后端不分离:客户端发送一个请求,服务端直接返回了一个表单
- 前后端分离:客户端发送一个请求,不会直接调用服务端的数据,而是会从web端返回一个html,css的表单,等到调用的时候才会去调用服务端的数据,图解如下
MVC模式
- 每一个链接对应一个函数
- C:controller,负责向用户返回一个数据的控制器
- V:视图,html
- M:model,数据库调用
创建后端项目
- 在spring initializer中选择
- 选择spring web和thymleaf
- 记住不要初始化git
Controller
```java
package com.kob.backend.controller.pk;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
@RequestMapping(value=”/pk/“)//注解的内容详见Java面向对象
public class IndexController {@RequestMapping("index/") public String index(){ return "pk/index.html"; //这个地方返回的是一个路径,所以是String类型 }
}
2. 前端页面添加在templates下创建各自模块的文件夹(注意这个地方是文件夹,而不是package) 3. 在类上定义@RequestMapping,提供初步的请求映射信息,相对于Web应用的根目录 4. 在方法上定义@RequestMapping,提供进一步的细分信息,相对于类定义处的URL 5. 如果对方法不写@RequestMapping的话,则不能访问后面方法中写的return的路径 ## template 1. template中存放的是html页面 ## static 1. static中一般创建三个目录,分别是CSS,JS,image ## 以上是前后端不分离的写法 _______________________ # 前后端分离的写法 1. 前后端分离,后端只会返回数据 2. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220830194938.png) 3. List<String> 数据类型 ## 改端口 1. 可以在 **templates** 的 **application.properties** 中修改端口 2. 如果使用默认的官方的网址,则properties文件是空的 3. 因为vue的默认端口也是8080 ## JDBC ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220830223222.png) ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220830223651.png) ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220830225133.png) 1. idea中可以查看到数据库的可视化界面 ## 添加数据库依赖 1. maven仓库官方地址[Just a moment... (mvnrepository.com)](https://mvnrepository.com/) 2. 第一个spring boot of JDBC(好像是这个名吧) 3. ``` <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> <version>2.7.1</version> </dependency>
直接复制进pom.xml中
在pom.xml中查询dependencies,添加到dependencies的下一级中,和其它dependeny同级
第二个,Project Lombok
```
org.projectlombok lombok 1.18.14 provided 10. MySQL Connector/J 11. ``` <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.29</version> </dependency>
mybatis-plus-boot-starter
-
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.1</version> </dependency>
mybatis-plus-generator
```
com.baomidou mybatis-plus-generator 3.5.2 16. 如果maven报红的话,点击重新加载 17. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220830230836.png) 18. spring如果想要访问数据库,则需要和登录mysql一样,输入用户名密码登录 19. 在application.properties中添加数据库配置,下面的还需要自行更改 20. 我不知道为什么还要每次**重启idea的时候都要重新写上**,否则会报 21. ```java Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
```java
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/kob?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver23. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220831142804.png) ## SpringBoot中常用模块 1. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220831152828.png) 2. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220831152901.png) 3. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220831153435.png) ### pojo层 1. 第一步:将数据库中的表翻译成Java中的class 2. 创建一个package,名为pojo,一个表对应一个pojo 3. 创建一个class,名为User 4. 类中写数据库中对应的数据类型 5. 加入注解,自动化生成 6. @Data,这个注解会导入常用的函数 7. @NoArgsConstructor,无参构造函数 8. @AllArgsConstructor,全参构造函数 ### mapper层 1. 第二步是创建mapper层 2. 加入@Mapper注解 3. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220831162135.png) 4. UserMapper是一个接口,继承自BaseMapper<User>写法固定 ### service ### controller #### controller的定义 1. 初步写的时候,controller和service不用分开,等到真正的写业务逻辑的时候再分开 2. 在backend.user中创建UserController类 3. 加入注解@RestController 4. 在这个类中可以实现各种请求查询 5. 如果想要只映射get类型的,则为@GetMapping Mapping 6. 只映射post类型的映射,则为@PostMapping Mapping 7. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220831163835.png) 8. 具体详见[春季@GetMapping和@PostMapping与示例 (howtodoinjava.com)](https://howtodoinjava.com/spring5/webmvc/controller-getmapping-postmapping/) 9. 要用到mapper的话,一定要加上@Autowired的注解 10. ```java @Autowired UserMapper userMapper;
当声明出一个上一级的变量时,必须使用此注解
这样可以使用不同的方法来实现不同的查询,具体查看mybatis CRUD接口
controller中用mybatis-plus的自动化方法实现CRUD
查:
```java
@GetMapping(value=”/user/{userId}”) //这个注解,当get传参为userId时,可以调用后面的方法
public User getuser(int userId){ //这个地方,返回值是数据库中的数据,所以返回值类型写表的名字return userMapper.selectById(userId);
}
3. 上面的是从mybatis的官方文档中看的 4. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220831173429.png) ### mybatis CRUD接口 1. [CRUD 接口 | MyBatis-Plus (baomidou.com)](https://baomidou.com/pages/49cc81/#service-crud-接口) 2. 官方文档中的所有语句一般都是要写到return 语句中的,在userMapper中使用,例如 3. ```java return userMapper.selectById(userId); 上面的return userMapper.是一定要写的,因为声明的mapper为userMapper
Spring Boot中传参数
大括号,中间写参数名称
例如,要get传参,传给XXX
```java
@GetMapping(“/user/{userId}”)4. 另外,如果需要引用传入的参数的话,则需要使用如下注解 5. ```java @PathVariable
@PathVariable注解用来修饰参数,放在参数的前面
{id},大括号中的参数不需要使用 ? 传递,只需要在后面拼接即可
@PathVariable的详解春季@PathVariable注释|贝尔东 (baeldung.com)
当出现红色报错时
- 当遇到can not resolve symbol XXX的时候,首先检查XXX有没有导入进去
- 例如can not resolve symbol User,就是没有引入第一步写的pojo中的User类
- 当出现红色报错,例如can not resolve symbol XXX的时候,重启
- 如果还是报错红色,刷新依赖
- 如果依然报错的话,可以检查Maven的配置,查看Maven的home路径,user setting file路径,local repository的路径。
springboot在客户端和mysql之间传递的逻辑
- client给spring boot传一个url,spring boot将查询数据返回给mysql
- mysql将数据返回给spring boot,spring boot再将来自spring boot的数据返回给client
映射数据库中的表
package com.kob.backend.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Kob {
private Integer id;
private String username;
private String password;
private Integer rating;
private String photo;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getRating() {
return rating;
}
public void setRating(Integer rating) {
this.rating = rating;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
}
Mapper
package com.kob.backend.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kob.backend.pojo.Kob;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<Kob> {
}
UserController
package com.kob.backend.controller.user;
import com.kob.backend.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.kob.backend.pojo.Kob;
import java.util.List;
@RestController
public class UserController {
@Autowired
UserMapper userMapper;
@GetMapping(value="/user/all/")
public List<Kob> getAll(){
return userMapper.selectList(null);
}
@GetMapping(value="/user/{userId}")
public Kob getUser(@PathVariable int userId){
return userMapper.selectById(userId);
}
}
用户授权操作
spring security模块
需要将spring security继承进来
从maven官网找依赖,spring-boot-starter-security
```java
org.springframework.boot spring-boot-starter-security 2.7.3 5. 添加进pom.xml中 6. session和jwt,选择了jwt 7. spring用户名默认为user 8. spring密码会自动生成,需要在终端中寻找 ## session验证 1. 当spring boot传数据给client的时候,同时传了一个字符串,session id 2. client在拿到session id的时候,还会在浏览器中留一个cookie,关闭之后仍然会存在 3. 每一次访问的时候,浏览器都会默认从客户端取出session id,并放到cookie中传给spring boot 4. 如果cookie中的session id没有过期,则可以登录 5. 如果cookie中的session id过期了,或者session id不存在,则会返回一个登录页面,让其重新登录 ## post请求需要在参数前面加一个注解 1. post请求需要在参数前面加一个注解 2. ```java @RequestParam
QueryWrapper
用来生成sql的where条件,entity属性也用于生成sql的where条件
声明一个QueryWrapper:
-
QueryWrapper<User> queryWrapper = new QueryWrapper(); queryWrapper.eq("column_name",value_in_database); User user = userMapper.selectOne(queryWrapper);//这个userMapper是@Autowired private UserMapper userMapper声明出来的,记住是由userMapper来控制数据库 //此处可以对如果查找错误进行判断 if(user == null){ throw new RuntimeException("用户不存在"); //报错用throw new RuntimeException();扔出一个错误 }
搭建项目的框架
MVC
M:model,用JavaBean写的实体类
```
public 的类
private的属性
必须包含一个无参构造器,构造器可以不唯一,即可以存在其它构造器和无参构造器构成重载
必须对每一个成员属性都有一个getter和一个setter4. V:view,即存放前端可视化代码 5. C:controller,用来控制实体类 ## 再细分 1. User来映射数据库 2. Mapper来操控制数据库,其实就是复制一个接口 3. Service来实现具体的业务逻辑 4. Controller来实现和前端的交互 # 黑马springboot ## springboot起步依赖原理分析 1. 版本锁定:在父工程中定义了一些坐标和版本信息,在后面继承这个父类时,就不需要再写版本信息了,可以有效地避免冲突 2. spring boot-web中集成了spring的一些依赖,也就是说springboot是基于spring的,spring较为底层 3. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220917211502.png) 4. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220917211615.png) ## 配置文件 1. springboot是基于约定的,很多配置都有默认值,但是如果想用自己的配置替换默认配置的话,就可以使用application.properties或者application.yml(或者application.yaml,yml和yaml是相同的,就和html和htm一样)进行配置 2. 配置文件都在resources目录下 3. 加载顺序:properties > yml > yaml,如果高低优先级中同时存在,则会采用高优先级的 ### properties ```java\ server.port=8080
properties采用键值对的形式
yml
```java
server:port: 8080
2. 使用缩进代表父子层级关系 3. 冒号和数值之间有空格,如果没有空格,数值将不会被识别 ## yaml 1. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220918092359.png) 2. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220918092647.png) 3. 注意:**缩进表示层级关系** 4. 缩进时不允许使用tab,只允许使用空格,各个系统tab对应的空格数目可能不同,导致层次混乱(idea不用担心) 5. 缩进的空格数目不重要,只要相同层级的元素左对齐即可 ### yaml数据格式 1. 对象(map):键值对的集合,支持行内写法 2. 行内写法,不同属性之间**用逗号去分隔** 3. 采用一种键值对的形式 4. ``` person: {name: zhangsan,age: 20} //了解即可,最好采用缩进的写法
数组:
address: - beijing - shanghai address: [beijing,shanghai] //也可以采用一种默认数组下标的方式
纯量,单引号忽略转义字符,双引号识别转义字符
参数引用
name: lisi person: name: ${name} //这样在获取person.name时,就会输出lisi
读取配置文件的内容
注意,以下内容都是獲取application.properties/yml/yaml中的配置文件的内容
@Value("${name}") //這樣可以獲取到一個application配置文件中的name屬性 private String name; //然後需要一個變量來承接,而且一定要承接,爲其分配内存空間,否則會報錯,承接的變量變量名可以自定
可以理解為@Value中的内容是用來取數據,而承接是用來起別名
```java
@Value(“{address[0]}”)
private String msg; //此時,msg的值就為address[0]### 注入一個對象,環境對象 1. 使用這種方法的目的就是不用@Value()去一個一個地注入,一次性整體注入進去 ```java @Autowired; //使用@Autowired注解自動注入 private Environment env; //在springboot程序啓動的時候,就會在spring boot容器中初始化好一個Environment對象
通過getProperty方法,指定鍵的名稱,就可以獲取到鍵對應的屬性值了
String env.getProperty("name");//引號中寫鍵的名稱/屬性的名稱
@ConfigurationProperties
- prefix参数:捕获配置文件中固定前缀的属性,然后依次赋值到这个类中
@Component
- @Component是基础注解,表示一个JavaBean可以被注入到spring容器中
- 上面这张图片,@Component表示这个person类被spring识别,是一个bean
profile
用途
- 在程序迁移时,数据库地址,端口等配置进行动态切换
注意配置文件的命名
都为
application-xxx.properties
模板:
application-dev.properties 开发环境developer
application-pro.properties 生产环境
application-test.properties 测试环境
profile配置方式
- 多profile文件方式
- yml多文档方式
profile激活方式,多profile文件方式
```
spring.profiles.active=dev2. 上面这个spring.profiles.active属性用来激活profile,后面的dev根据具体情况而定 3. 例如dev是根据后缀application-dev.properties 4. pro是根据application-pro.properties ### yml多文档方式 1. 使用三个杠来分隔 2. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220918181518.png) 3. spring.profiles.active属性来设定来调用哪一个properties ### profile激活方式 1. 配置文件 2. 虚拟机参数 3. 命令行参数 ### 利用虚拟机参数进行激活 1. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220918182650.png) 2. 在run/debug configruation中更改配置 3. 修改VM options参数为 4. ```java -Dspring profiles active=test
虚拟机参数会覆盖配置文件中的配置
使用命令行参数进行配置的修改
在program arguments中添加命令行参数
将此参数修改为
--spring.profiles.active=pro
java -jar 文件名### 注意 1. 命令行参数和虚拟机参数激活的前提是在yml文件中写为多文档模式 2. 后两种优点是不用一次次地修改配置文件 ## 实际生产中打成jar包的操作 1. ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220918183902.png) 2. 运行jar包
java -jar 文件名 --spring.profiles.active=pro3. 添加命令行参数来激活profile