Spring学习笔记

一定要区分mapper,service,和controller

  1. mapper是用来控制数据库
  2. service主要实现业务逻辑
  3. controller与前端交互

MVC模式

  1. controller,view,model分别对应一个文件夹

前端后端,分离不分离的区别

  1. 每一个用户操作的就是客户端
  2. 后端是用spring搭建
  3. 前端有两个可以搭建的方式:web和app
  4. 用户打开网页,本质是向服务器发送了一个链接(请求),服务器接收到了请求之后,会返回一个页面,这个页面是以字符串表单的形式返回的,浏览器接收之后会自动转化
  5. 前后端不分离:客户端发送一个请求,服务端直接返回了一个表单
  6. 前后端分离:客户端发送一个请求,不会直接调用服务端的数据,而是会从web端返回一个html,css的表单,等到调用的时候才会去调用服务端的数据,图解如下

MVC模式

  1. 每一个链接对应一个函数
  2. C:controller,负责向用户返回一个数据的控制器
  3. V:视图,html
  4. M:model,数据库调用

创建后端项目

  1. 在spring initializer中选择
  2. 选择spring web和thymleaf
  3. 记住不要初始化git

Controller

  1. ```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>
         
  2. 直接复制进pom.xml中

  3. 在pom.xml中查询dependencies,添加到dependencies的下一级中,和其它dependeny同级

  4. 第二个,Project Lombok

  5. ```

    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>
          
  6. mybatis-plus-boot-starter

  7. <!-- 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>
    
  8. mybatis-plus-generator

  9. ```

    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.
  10. ```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.Driver

    
    23.   ![](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;
  11. 当声明出一个上一级的变量时,必须使用此注解

  12. 这样可以使用不同的方法来实现不同的查询,具体查看mybatis CRUD接口

controller中用mybatis-plus的自动化方法实现CRUD

  1. 查:

  2. ```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中传参数

  1. 大括号,中间写参数名称

  2. 例如,要get传参,传给XXX

  3. ```java
    @GetMapping(“/user/{userId}”)

    
    4.   另外,如果需要引用传入的参数的话,则需要使用如下注解
    
    5.   ```java
         @PathVariable
  4. @PathVariable注解用来修饰参数,放在参数的前面

  5. {id},大括号中的参数不需要使用 ? 传递,只需要在后面拼接即可

  6. @PathVariable的详解春季@PathVariable注释|贝尔东 (baeldung.com)

当出现红色报错时

  1. 当遇到can not resolve symbol XXX的时候,首先检查XXX有没有导入进去
  2. 例如can not resolve symbol User,就是没有引入第一步写的pojo中的User类
  3. 当出现红色报错,例如can not resolve symbol XXX的时候,重启
  4. 如果还是报错红色,刷新依赖
  5. 如果依然报错的话,可以检查Maven的配置,查看Maven的home路径,user setting file路径,local repository的路径。

springboot在客户端和mysql之间传递的逻辑

  1. client给spring boot传一个url,spring boot将查询数据返回给mysql
  2. 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);
    }
}

用户授权操作

  1. spring security模块

  2. 需要将spring security继承进来

  3. 从maven官网找依赖,spring-boot-starter-security

  4. ```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

  1. 用来生成sql的where条件,entity属性也用于生成sql的where条件

  2. 声明一个QueryWrapper:

  3. 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();扔出一个错误
    }

搭建项目的框架

  1. MVC

  2. M:model,用JavaBean写的实体类

  3. ```
    public 的类
    private的属性
    必须包含一个无参构造器,构造器可以不唯一,即可以存在其它构造器和无参构造器构成重载
    必须对每一个成员属性都有一个getter和一个setter

    
    4.   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
  4. properties采用键值对的形式

yml

  1. ```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} //了解即可,最好采用缩进的写法
  2. 数组:

    address:
    	- beijing
    	- shanghai
    address: [beijing,shanghai] //也可以采用一种默认数组下标的方式
  3. 纯量,单引号忽略转义字符,双引号识别转义字符

  4. 参数引用

    name: lisi
    person:
    	name: ${name}
    //这样在获取person.name时,就会输出lisi

读取配置文件的内容

  1. 注意,以下内容都是獲取application.properties/yml/yaml中的配置文件的内容

    @Value("${name}") //這樣可以獲取到一個application配置文件中的name屬性
    private String name; //然後需要一個變量來承接,而且一定要承接,爲其分配内存空間,否則會報錯,承接的變量變量名可以自定
  2. 可以理解為@Value中的内容是用來取數據,而承接是用來起別名

  3. ```java
    @Value(“{address[0]}”)
    private String msg; //此時,msg的值就為address[0]

    
    ### 注入一個對象,環境對象
    
    1.   使用這種方法的目的就是不用@Value()去一個一個地注入,一次性整體注入進去
    
    ```java
    @Autowired; //使用@Autowired注解自動注入
    private Environment env; //在springboot程序啓動的時候,就會在spring boot容器中初始化好一個Environment對象
  4. 通過getProperty方法,指定鍵的名稱,就可以獲取到鍵對應的屬性值了

    String env.getProperty("name");//引號中寫鍵的名稱/屬性的名稱

@ConfigurationProperties

  1. prefix参数:捕获配置文件中固定前缀的属性,然后依次赋值到这个类中

@Component

  1. @Component是基础注解,表示一个JavaBean可以被注入到spring容器中
  2. 上面这张图片,@Component表示这个person类被spring识别,是一个bean

profile

用途

  1. 在程序迁移时,数据库地址,端口等配置进行动态切换

注意配置文件的命名

  1. 都为

    application-xxx.properties
  2. 模板:

  3. application-dev.properties 开发环境developer

  4. application-pro.properties 生产环境

  5. application-test.properties 测试环境

profile配置方式

  1. 多profile文件方式
  2. yml多文档方式

profile激活方式,多profile文件方式

  1. ```
    spring.profiles.active=dev

    
    2.   上面这个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
  2. 虚拟机参数会覆盖配置文件中的配置

使用命令行参数进行配置的修改

  1. 在program arguments中添加命令行参数

  2. 将此参数修改为

  3.   --spring.profiles.active=pro
      
    
    ### 注意
    
    1.   命令行参数和虚拟机参数激活的前提是在yml文件中写为多文档模式
    2.   后两种优点是不用一次次地修改配置文件
    
    ## 实际生产中打成jar包的操作
    
    1.   ![](https://strongwillpro.oss-cn-beijing.aliyuncs.com/img/20220918183902.png)
    
    2.   运行jar包
    
    java -jar 文件名
    
    3.   添加命令行参数来激活profile
    
    java -jar 文件名 --spring.profiles.active=pro

springboot内部配置加载顺序