SpringBoot 2.X 快速掌握

来源:https://www.cnblogs.com/xiegongzi/archive/2022/05/26/16312315.html
-Advertisement-
Play Games

0、重寫博文的原因 當初我的SpringBoot系列的知識是採用分節來寫的,即:每一個知識點為一篇博文,但是:最近我霉到家了,我發現有些博文神奇般地打不開了,害我去找當初的markdown筆記,但是方便的話還是線上版舒服,只要有網就可以訪問,因此昨天晚上東拼西湊搞出了這篇SpringBoot基礎系列 ...


0、重寫博文的原因

  • 當初我的SpringBoot系列的知識是採用分節來寫的,即:每一個知識點為一篇博文,但是:最近我霉到家了,我發現有些博文神奇般地打不開了,害我去找當初的markdown筆記,但是方便的話還是線上版舒服,只要有網就可以訪問,因此昨天晚上東拼西湊搞出了這篇SpringBoot基礎系列知識


1、什麼是SpringBoot?

1.1、百度百科一下

截圖



2、對SpringBoot快速上手

2.1、通過官網來創建 - 瞭解

這裡面的創建方式不做過多說明,只需要在官網裡面創建好了,然後下載解壓,就可以了,我這裡直接使用編輯器創建
springboot搭建項目官網
截圖



2.2、使用IDEA編輯器創建

截圖

截圖

截圖

選完之後,idea就會去拉取相應的jar包,創建結果如下:
截圖



啟動項目

截圖

截圖

截圖



編寫controller

截圖

重新啟動主方法,輸入請求
截圖

這樣就創建成功了一個springboot項目



3、小彩蛋 - banner

截圖



上面這玩意兒,我不想看到它

截圖

截圖

  • 在項目的resources資源目錄下,新建一個banner文件
    截圖

  • 再運行項目主方法
    截圖

    • 至於這個banner為什麼可以啟動,在下一篇小博客中說SpringBoot的原理圖時,裡面有


4、瞭解yml語法

  • 這玩意兒的語法就像如下圖的類與屬性的關係一樣,層層遞進的( 註意:使用yml語法時,每句的結尾別有空格,容易出問題,另外:IDEA中採用tab縮進沒問題,但是:在其他地方,如:linux中,使用yml語法時,別用tab縮進,也容易導致程式啟動不起來 )

截圖

4.1、使用yml給實體類賦值

  • 準備工作:導入依賴

        <!--這個jar包就是為了實體類中使用@ConfigurationProperties(prefix = "person")這個註解而不報紅-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>


  • 使用@ConfigurationProperties註解實現給實體類屬性賦值
    截圖

截圖

  • 測試
    截圖


5、jsr303檢驗

  • jsr303這是數據檢驗的規範,基於這個的實現方式有好幾個,自行百度一下,然後註解含義都是和下麵列出來的差不多

依賴


        <!--JSR303校驗的依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>


使用jsr303檢驗

截圖



  • 可以搭配的註解如下:

空檢查
	@Null 驗證對象是否為null
	@NotNull 驗證對象是否不為null, 無法查檢長度為0的字元串
	@NotBlank 檢查約束字元串是不是Null還有被Trim的長度是否大於0,只對字元串,且會去掉前後空格.
	@NotEmpty 檢查約束元素是否為NULL或者是EMPTY.


Booelan檢查
	@AssertTrue 驗證 Boolean 對象是否為 true
	@AssertFalse 驗證 Boolean 對象是否為 false


長度檢查
	@Size(min=, max=) 驗證對象(Array,Collection,Map,String)長度是否在給定的範圍之內
	@Length(min=, max=) Validates that the annotated string is between min and max included.


日期檢查
	@Past 驗證 Date 和 Calendar 對象是否在當前時間之前,驗證成立的話被註釋的元素一定是一個過去的日期
	@Future 驗證 Date 和 Calendar 對象是否在當前時間之後 ,驗證成立的話被註釋的元素一定是一個將來的日期
	@Pattern 驗證 String 對象是否符合正則表達式的規則,被註釋的元素符合制定的正則表達式,regexp:正則表達式 flags: 指定 Pattern.Flag 的數組,表示正則表達式的相關選項。


數值檢查
	建議使用在Stirng,Integer類型,不建議使用在int類型上,因為表單值為“”時無法轉換為int,但可以轉換為Stirng為”“,Integer為null
	@Min 驗證 Number 和 String 對象是否大等於指定的值
	@Max 驗證 Number 和 String 對象是否小等於指定的值
	@DecimalMax 被標註的值必須不大於約束中指定的最大值. 這個約束的參數是一個通過BigDecimal定義的最大值的字元串表示.小數存在精度
	@DecimalMin 被標註的值必須不小於約束中指定的最小值. 這個約束的參數是一個通過BigDecimal定義的最小值的字元串表示.小數存在精度
	@Digits 驗證 Number 和 String 的構成是否合法
	@Digits(integer=,fraction=) 驗證字元串是否是符合指定格式的數字,interger指定整數精度,fraction指定小數精度。
	@Range(min=, max=) 被指定的元素必須在合適的範圍內
	@Range(min=10000,max=50000,message=”range.bean.wage”)
	@Valid 遞歸的對關聯對象進行校驗, 如果關聯對象是個集合或者數組,那麼對其中的元素進行遞歸校驗,如果是一個map,則對其中的值部分進行校驗.(是否進行遞歸驗證)
	@CreditCardNumber信用卡驗證
	@Email 驗證是否是郵件地址,如果為null,不進行驗證,算通過驗證。
	@ScriptAssert(lang= ,script=, alias=)
	@URL(protocol=,host=, port=,regexp=, flags=)



6、yml多環境配置

截圖

截圖

還有一種標準的配置,即:採用多個yml文件,如:application-test.yml 就是測試環境的配置appilication-dev.yml 就是開發環境的配置appilication-pro.yml 就是生產環境配置



7、設置預設首頁

  • 這是SpringBoot + thmeleaf響應式編程的技術,現在前後端分離,這種東西其實沒什麼鳥用

7.1、頁面在static目錄中時

  • 直接在controller中編寫跳轉地址即可
    截圖

7.2、頁面在templates模板引擎中時

截圖

這種需要導入相應的啟動器


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>


編寫controller

截圖

測試

截圖



8、簡單認識thymeleaf

  • 這是SpringBoot + thmeleaf響應式編程的技術,現在前後端分離,這種東西其實沒什麼鳥用

官網學習地址


8.1、什麼是thymeleaf?

一張圖看明白:

  • 截圖

解讀:

  • 前端交給我們的頁面,是html頁面。如果是我們以前開發,我們需要把他們轉成jsp頁面,jsp好處就是當我們查出一些數據轉發到JSP頁面以後,我們可以用jsp輕鬆實現數據的顯示,及交互等

  • jsp支持非常強大的功能,包括能寫Java代碼,但是,SpringBoot是以jar的方式,不是war,第二,我們用的還是嵌入式的Tomcat,所以,springboot現在預設是不支持jsp的

  • 那不支持jsp,如果我們直接用純靜態頁面的方式,那給我們開發會帶來非常大的麻煩,那怎麼辦?


SpringBoot推薦使用模板引擎:

  • 模板引擎,jsp就是一個模板引擎,還有用的比較多的FreeMaker、Velocity,再多的模板引擎,他們的思想都是一樣的,SpringBoot推薦使用thymeleaf

    • 模板引擎的作用就是我們來寫一個頁面模板,比如有些值,是動態的,我們寫一些表達式。而這些值從哪來?就是我們在後臺封裝一些數據。然後把這個模板和這個數據交給模板引擎,模板引擎按照我們封裝的數據把這表達式解析出來、填充到我們指定的位置,然後把這個數據最終生成一個我們想要的內容從而最後顯示出來,這就是模板引擎。

    • 不管是jsp還是其他模板引擎,都是這個思想。只不過,不同模板引擎之間,他們可能語法有點不一樣。其他的就不介紹了,這裡主要介紹一下SpringBoot給我們推薦的Thymeleaf模板引擎,這模板引擎,是一個高級語言的模板引擎,他的這個語法更簡單。而且功能更強大


8.2、thymeleaf的取數據方式

  • 官網中有說明
    截圖

提取出來看一下,從而在springboot中演示一下

  • 簡單的表達:
    • 變數表達式: ${...}
    • 選擇變數表達式: *{...}
    • 消息表達: #{...}
    • 鏈接 URL 表達式: @{...}
    • 片段表達式: ~{...}


8.3、在springboot中使用thymeleaf

依賴


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>


怎麼使用thymeleaf?

  • 這個問題換言之就是:html文件應該放到什麼目錄下
    • 前面我們已經導入了依賴,那麼按照springboot的原理( 本篇博客結尾附有原理鏈接 ),底層會幫我們導入相應的東西,並做了相應的配置,那麼就去看一下源碼,從而知道我們應該把文件放在什麼地方( 註:springboot中和配置相關的都在xxxxxProperties文件中,因此:去看一下thymeleaf對應的thymeleafProperties文件

截圖

  • 那就來建一個

截圖


  • 編寫controller,讓其跳到templates目錄的頁面中去
    截圖

  • 測試
    截圖

  • 成功跳過去了



8.4、延伸:傳輸數據

8.4.1、開胃菜

  • 參照官網來( 這裡只演示 變數表達式: ${...},其他的都是一樣的原理 )

截圖


編寫後臺,存入數據

截圖


在前臺獲取數據

截圖


表空間約束鏈接如下,這個在thymeleaf官網中有


	xmlns:th="http://www.thymeleaf.org"


測試:

截圖



8.4.2、開整

截圖


後臺

截圖


前臺

截圖


測試

截圖


其他的玩法都差不多



9、靜態資源處理方式

  • 在前面玩了thymeleaf,在resources中還有一個目錄是static

截圖

  • 那麼就來研究一下靜態資源:靜態資源,springboot底層是怎麼去裝配的?
    • 都在WebMvcAutoConfiguration有答案,去看一下

截圖

  • 通過上述的源碼發現兩個東西:webjarsgetStaticLocations()


9.1、webjars的方式處理靜態資源


使用jQuery做演示

  • 導入jQuery的依賴

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.4.1</version>
</dependency>

截圖


  • 導入之後:發現多了這麼一個jar包,現在我們去直接訪問一下

截圖


  • 是可以直接訪問的,為什麼?

截圖


getStaticLocations(),點進去看一下

發現是如下這麼一個方法


        public String[] getStaticLocations() {
            return this.staticLocations;
        }


  • 查看staticLocations

截圖

截圖


"classpath:/META-INF/resources/",   <!--這個就不多說明,指的就是再建一個META-INF文件夾,裡面再建一個resources目錄,參照Java基礎中的web項目目錄-->

"classpath:/resources/",

"classpath:/static/",

"classpath:/public/"

  • 發現有四種方式可以放靜態資源,那就來測試一下


9.1.1、resources/ static/ public的優先順序

截圖


測試
截圖

  • 發現resources下的優先順序最高

刪掉resources中的資源文件,繼續測試

截圖

截圖

  • 發現static目錄其次


9.1.1.1、總結:resources、static、public優先順序

  • resources目錄下的優先順序最高
  • 其次是static
  • 最後是public

資源放置建議:

  • public放置公有的資源,如:img、js、css....
  • static放置靜態訪問的頁面,如:登錄、註冊....
  • resources,應該說是templates,放置動態資源,如:用戶管理.....


10、整合jdbc、druid、druid實現日誌監控

10.1、整合jdbc、druid

依賴


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


編寫application.yml


spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_spring?useUnicode=true&characterEncoding=utf-8
    username: root
    password: "072413"

測試
截圖



10.2、整合druid

依賴


<!--要玩druid的話,需要導入下麵這個依賴 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>


修改yml文件

截圖


測試
截圖



10.3、druid實現日誌監控

  • 註意點:需要web啟動器支持

<!--
	玩druid實現監控日誌,需要web啟動器支持,因為:druid的statViewServlet本質是繼承了servlet
	因此:需要web的依賴支持 / servlet支持
-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


編寫配置


package cn.xiegongzi.config;

// 這個類是為了延伸druid的強大功能 ————— 監控後臺
// 註意:這個需要spring的web啟動器支持,即:這個監控後臺的本質StatViewServlet就是servlet,所以需要servlet支持

import com.alibaba.druid.support.http.StatViewServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;

@Configuration
public class DruidConfig {

    @Bean
    public ServletRegistrationBean StatViewServlet() {

        ServletRegistrationBean bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");

        HashMap<String, String> initParameters = new HashMap<>();

    // 下麵這些參數可以在 com.alibaba.druid.support.http.StatViewServlet
    // 的父類 com.alibaba.druid.support.http.ResourceServlet 中找到
        initParameters.put("loginUsername", "zixieqing");  // 登錄日誌監控的用戶名
        initParameters.put("loginPassword", "072413");    // 登錄密碼

        initParameters.put("allow", "`localhost`");    // 運行誰可以訪問日誌監控

        bean.setInitParameters(initParameters);
        return bean;
    }
}


測試

截圖

截圖



11、整合mybatis

  • 註:複雜sql使用xml,簡單sql使用註解

11.1、xml版

導入依賴


<!--
        mybatis-spring-boot-starter是第三方( mybatis )jar包,不是spring官網的
        spring自己的生態是:spring-boot-stater-xxxx
-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>


編寫實體


package cn.xiegongzi.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {

    private Integer id;
    private String username;
    private String password;
}


編寫dao / mapper層


package cn.xiegongzi.mapper;

import cn.xiegongzi.entity.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/*
*   @Mapper 這個註解是mybati-spring提供的,即:和自動裝配是一樣的效果
*   還可以用:
*       @Repository   是spring本身提供的
* 
*   以及:在啟動類( main )中使用@mapperScan掃包
* */

@Mapper

public interface IUserMapper {

    List<User> findALLUser();
}


編寫xml的sql語句

截圖

  • 註意點:dao層 / mapper和xml的同包同名問題

編寫yml


# 編寫連接池
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_spring?useUnicode=true&characterEncoding=utf-8
    username: root
    password: "072413"
    type: com.alibaba.druid.pool.DruidDataSource
# 把實現類xml文件添加進來
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: cn.xiegongzi.entity   # 給實體類配置別名
  configuration:
    map-underscore-to-camel-case: true    # 開啟駝峰命名映射

截圖


測試

截圖



11.2、註解版

  • 和ssm整合中的玩法一樣,只改動一個地方即可,就是不需要xml了
  • 直接在dao層 / mapper的介面方法頭上用@insert()@delete()@update() @select()註解,然後小括弧中編寫sql字元串即可

截圖


  • 當然:也可以給日誌設置級別

截圖



12、整合pageHelper分頁插件

依賴


<dependency>
	<groupId>com.github.pagehelper</groupId>
	<artifactId>pagehelper-spring-boot-starter</artifactId>
	<version>1.2.5</version>
</dependency>



測試

截圖



13、集成swagger


13.1、快速上手

導入依賴


        <!--swagger所需要的依賴-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.8.0</version>
        </dependency>
        <!--這個依賴是為了渲染swagger文檔頁面的( 為了好看一點罷了 ) ,swagger真正的依賴是上面兩個-->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>1.8.5</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>


編寫swagger配置文件

截圖


	package cn.xiegongzi.config;


	import org.springframework.context.annotation.Bean;
	import org.springframework.context.annotation.Configuration;
	import springfox.documentation.builders.ApiInfoBuilder;
	import springfox.documentation.builders.PathSelectors;
	import springfox.documentation.builders.RequestHandlerSelectors;
	import springfox.documentation.service.ApiInfo;
	import springfox.documentation.service.Contact;
	import springfox.documentation.spi.DocumentationType;
	import springfox.documentation.spring.web.plugins.Docket;
	import springfox.documentation.swagger2.annotations.EnableSwagger2;

	@Configuration      // 表明當前類是一個配置類,並把當前類丟到spring容器中去
	@EnableSwagger2     // 開啟swagger功能
	public class SwaggerConfig {

		@Bean
		public Docket createRestApi() {
			// http://ip地址:埠/項目名/swagger-ui.html#/
			ApiInfo apiInfo = new ApiInfoBuilder()
					// 網站標題    即:生成的文檔網址標題
					.title( "悠忽有限公司" )
					 // 網站描述     即:對生成文檔的描述
					.description( "這是一個很nice的介面文檔" )
					 // 版本
					.version( "9.0" )
					 // 聯繫人
					.contact( new Contact("紫邪情","https://www.cnblogs.com/xiegongzi/","110" ) )
					 // 協議  http / https都可以
					.license( "tcp" )
					// 協議url 即:進入到swagger文檔頁面的地址
					.licenseUrl( "http://localhost:8080/" )
					.build();

			// swagger版本
			return new Docket( DocumentationType.SWAGGER_2 )
					// 請求映射路徑  就是:controller中有一個介面,然後前臺訪問的那個介面路徑
					// 這個可以在生成的文檔中進行調試時看到
					.pathMapping( "/" )
					 // 根據pathMapping去進行查詢( 做相應的操作 )
					.select()
					// 掃描包   即:哪些地方可以根據我們的註解配置幫我們生成文檔
					.apis( RequestHandlerSelectors.basePackage( "cn.xiegongzi" ) )
					.paths( PathSelectors.any() )
					.build()
					.apiInfo( apiInfo );
		}

	}


編寫yml文件


	spring:
	  datasource:
	  	# 註意這裡加了cj啊,即:MySQL驅動用的是8.x的
		driver-class-name: com.mysql.cj.jdbc.Driver
		url: jdbc:mysql://localhost:3306/mybatis_spring?useUnicode=true&characterEncoding=utf-8
		username: root
		# 註意:在yml中,這種自己寫的內容最好用字元串寫法,以後玩Redis也是一樣,不然有時出現坑,即:密碼無效 / 這裡面填入的值沒有解析出來,不匹配
		password: "072413"


編寫實體類


	package cn.xiegongzi.entity;

	import io.swagger.annotations.ApiModel;
	import io.swagger.annotations.ApiModelProperty;
	import lombok.AllArgsConstructor;
	import lombok.Data;
	import lombok.NoArgsConstructor;

	import java.io.Serializable;

	@Data
	@AllArgsConstructor
	@NoArgsConstructor

/**
 * @ApiModel(description = "描述")
 * 表明這個實體類就是需要的數據名和類型
 * 後臺接收前端的參數是一個對象時使用( controller寫的是@RequestBody OrderPaidDTO orderPaid ),即:後端接收參數封裝成了一個xxxxDTO( PO、BO、Entity、DTO、DAO含義和關係是什麼,自行百度 )
 * 這個東西可以先不加,在做增加、修改時可以用這個測試一下,從而去swagger中看效果
*/
	@ApiModel(description = "用戶信息")
	public class User implements Serializable {

		 // 數據屬性配置,這裡面可以跟幾個屬性,常見的是value、required、dataType、hidden,在待會後面附加的鏈接中有解釋
		@ApiModelProperty
		private Integer id;

		@ApiModelProperty
		private String username;

		@ApiModelProperty
		private String phone;
	}


編寫mapper


	package cn.xiegongzi.mapper;

	import cn.xiegongzi.entity.User;
	import org.apache.ibatis.annotations.Mapper;
	import org.apache.ibatis.annotations.Select;

	import java.util.List;

	@Mapper
	public interface IUserMapper {

		@Select("select * from user")
		List<User> findAllUser();
	}


編寫service介面和實現類

截圖


編寫controller

截圖


	package cn.xiegongzi.controller;

	import cn.xiegongzi.service.IUserService;
	import com.alibaba.fastjson.JSON;
	import io.swagger.annotations.Api;
	import io.swagger.annotations.ApiOperation;
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.web.bind.annotation.GetMapping;
	import org.springframework.web.bind.annotation.RestController;

	@RestController
	/*
		@Api
			表示當前類可以被生成一個swagger文檔
			可以跟參數tags,參數表示:這整個介面的名字( 前端是介面,後端是controller控制層 )
	*/
	@Api(tags = "用戶管理介面集")
	public class UserController {

		@Autowired
		private IUserService userService;


		/*
			@ApiImplicitParam 這個註解是對請求參數做限制用的,如:請求時要求前臺傳遞一個id,那麼:在這個註解裡面:就可以聲明這個參數的類型( 對象類型中要求屬性限制,可以使用@ApiModelProperty 也可以使用 符合jsr303規範的數據檢驗方式 )
		*/
		// 遵循restful風格  要是使用@RequestMapping的話,會生成多個介面swagger文檔( 即:對應post、get.... )
		@GetMapping("/swaggger/doc")
		// value這個介面的名字;notes 對這個介面的描述
		@ApiOperation(value = "獲取全部用戶介面" , notes = "獲取全部的用戶")
		public String findAllUser() {

			return JSON.toJSONString( userService.findAllUser() );
		}
	}


測試

截圖

截圖



13.2、結語

  • 以上的內容是入門,其他的註解開發時自行摸索吧!
  • 還有一種,比swagger更好,就是:Apifox / ApiPost / eolink,自行下載安裝包,安裝之後玩一下


14、集成JPA

資料庫表欄位信息

截圖


導入依賴


        <!--導入jpa需要的依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>


        <!--項目需要的依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.75</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>


編寫yml文件


spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_spring?useUnicode=true&characterEncoding=utf-8
    username: root
    password: "072413"

  jpa:
# 這裡可以不用hibernate,還可以用hikari( 這個在前面整合jdbc時見過,就是當時輸出的那句話 )
    hibernate:
# 指定為update,每次啟動項目檢測表結構有變化的時候會新增欄位,表不存在時會新建表
      ddl-auto: update
# 如果指定create,則每次啟動項目都會清空數據並刪除表,再新建
# 這裡面還可以跟:create-drop/create/none
      naming:
        # 指定jpa的自動表生成策略,駝峰自動映射為下劃線格式
        implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl  # 預設就是這個
#        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
# 註掉的這種是:不用駝峰名字,直接把實體類的大寫字母變小寫就完了

    show-sql: true		# 在控制台顯示sql語句( 不是真的sql語句,而是相當於:說明 ),預設是false
# 使用INNODB引擎
    properties.hibernate.dialect: org.hibernate.dialect.MySQL55Dialect
    database-platform: org.hibernate.dialect.MySQL55Dialect
# 使用JPA創建表時,預設使用的存儲引擎是MyISAM,通過指定資料庫版本,可以使用InnoDB

編寫實體類


package cn.xiegongzi.entity;

import lombok.Data;
import org.springframework.data.annotation.Id;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import java.io.Serializable;


@Data
// @AllArgsConstructor
// @NoArgsConstructor

@Entity
/** @Entity
 * 表明:當前類和資料庫中的這個同類名的資料庫表形成ORM映射關係
 * 要是資料庫中沒有這個表,那麼:根據yml配置的ddl-auto: update 就會自動幫我們生成
*/
public class ZiXieQing implements Serializable {

    @javax.persistence.Id
    @Id     // 表明這個屬性是資料庫表中的主鍵
    @GeneratedValue(strategy = GenerationType.IDENTITY)     // 表示:自增  預設是auto,即:和資料庫中的auto_increment是一樣的
    private int id;

    @Column( length = 15 )          // 生成資料庫中的列欄位,裡面的參數不止這些,還可以用其他的,對應資料庫列欄位的那些操作
                                    // 可以點進源碼看一下
    private String name;

    // public ZiXieQing() {
    // }


    public ZiXieQing(int id, String name) {
        this.id = id;
        this.name = name;
    }
}


附:@Column註解中可以支持的屬性


@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    String name() default "";

    boolean unique() default false;

    boolean nullable() default true;

    boolean insertable() default true;

    boolean updatable() default true;

    String columnDefinition() default "";

    String table() default "";

    int length() default 255;

    int precision() default 0;

    int scale() default 0;
}


編寫mapper


package cn.xiegongzi.mapper;

import cn.xiegongzi.entity.ZiXieQing;
import org.springframework.data.jpa.repository.JpaRepository;

@Repository
/**
 * 註:這裡別用@Mapper這個註解,因為:@mapper是mybatis提供的註解
 * JpaRepository相對mybatis來說就是是外部的東西。因此:並不能支持@mapper註解
 */
public interface ZiXieQingMapper extends JpaRepository<ZiXieQing , Integer> {

    /*
		JpaRepository這裡面有預設的一些方法,即:增刪查改...
    	JpaRepository<ZiXieQing , Integer> 本來樣子是:JpaRepository<T , ID>
    	T  表示:自己編寫的實體類 類型
    	ID  表示: 實體類中id欄位的類型      註:本示例中,實體類中id是int 因為要弄自增就必須為int,不然和資料庫映射時對不上
    */

}


附:JpaRepository中提供的方法

截圖


編寫service介面和實現類

截圖


編寫controller

截圖


測試

截圖


現在去看一下資料庫

截圖

生成出來了,完成



15、集成mybatis-plus


導入依賴


        <!--mybatis-plus需要的依賴-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>


編寫yml


spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_spring?useUnicode=true&characterEncoding=utf-8
    username: root
    password: "072413"
    type: com.alibaba.druid.pool.DruidDataSource

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl   # mybatis-plus配置日誌
    map-underscore-to-camel-case: true    # 開啟駝峰映射 即:實體類屬性名和資料庫欄位採用駝峰映射
    auto-mapping-behavior: full     # 自動映射欄位
  mapper-locations: classpath:mapper/*.xml    # 如果使用了mybatis和mybatis-plus 那麼這裡就可以把mybatis的實現類xml集成進來
    # 但是:最好別這種做,用了mybatis就別用mybatis-plus,二者最好只用其一

註:別把mybatis和mybatis-plus一起集成到spring中,否則:很容易出問題,雖然:mybatis-plus是mybatis的增強版,既然是增強版,那麼就不會拋棄它原有的東西,只會保留原有的東西,然後新增功能,但是:mybatis和mybatis-plus集成到一起之後很容易造成版本衝突,因此:對於單個系統模塊 / 單個系統來說,建議二者只選其一集成 ( PS:當然事情不是絕對的 我說的是萬一,只是操作不當很容易觸發錯誤而已,但是:二者一起集成也是可以的,當出現報錯時可以解決掉,不延伸了 ,這不是這裡該做的事情 )


編寫實體類


package cn.xiegongzi.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "user")      // 表名註解
public class User implements Serializable {

    @TableId(type = IdType.AUTO)        // 表示主鍵,這個主鍵是一個Long類型的值( 即:snowflake雪花演算法 )
    private Integer id;
    @TableField("username")         // 資料庫欄位名   就是:當實體類中的欄位和資料庫欄位不一樣時可以使用
    private String name;
    private String phone;
}


編寫mapper


package cn.xiegongzi.mapper;

import cn.xiegongzi.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

@Mapper         // 不想在每個mapper層都寫這個註解,那把@MapperScan("cn.xiegongzi.mapper") 在啟動類中加入這個註解也可以實現
public interface IUserMapper extends BaseMapper<User> {

    /*
		BaseMapper 和 JPA一樣,內部有很多方法 , 即:CRUD.....,還有分頁( 分頁就是page()這個方法 )
		BaseMapper原來的樣子是:BaseMapper<T>  T表示實體類 類型
	*/

}

附:BaseMapper<T>提供的方法如下:
截圖


測試

截圖


其他的知識,在mybatis-plus官網中都有



15、分散式本地緩存技術ehcache

  • 還有一種比較流行的是Caffeine這個東西要更簡單一點,而且不需要藉助xml文件,而ehcache需要藉助xml文件

15.1、Ehcache介紹

  • Ehacahe是一個比較成熟的Java緩存框架,最早從hibernate發展而來,是進程中的緩存系統,它提供了用記憶體、磁碟文件存儲,以及分散式存儲方式等多種靈活的cache管理方案

15.2、ehcache常用註解

15.2.1、@CacheConfig註解

  • 用於標準在類上,可以存放該類中所有緩存的公有屬性( 如:設置緩存名字 )

@CacheConfig(cacheNames = "users")
public class UserService{

}

  • 當然:這個註解其實可以使用@Cacheable來代替


15.2.2、@Cacheable註解( 讀數據時 ) - 用得最多

  • 應用到讀取數據的方法上,如:查找數據的方法,使用了之後可以做到先從本地緩存中讀取數據,若是沒有在調用此註解下的方法去資料庫中讀取數據,當然:還可以將資料庫中讀取的數據放到用此註解配置的指定緩存中

@Cacheable(value = "user", key = "#userId")
User selectUserById( Integer userId );


@Cacheable註解的屬性

  • value、cacheNames
    • 這兩個參數其實是等同的( cacheNames為Spring 4新增的,作為value的別名 )
    • 這兩個屬性的作用:用於指定緩存存儲的集合名

  • key
    • 作用:緩存對象存儲在Map集合中的key值

  • condition
    • 作用:緩存對象的條件,即:只有滿足這裡面配置的表達式條件的內容才會被緩存,如:@Cache( key = "#userId",condition="#userId.length() < 3" 這個表達式表示只有當userId長度小於3的時候才會被緩存

  • unless
    • 作用:另外一個緩存條件,它不同於condition參數的地方在於此屬性的判斷時機( 此註解中編寫的條件時在函數被調用之後才做判斷,所以:這個屬性可以通過封裝的result進行判斷 )

  • keyGenerator
    • 作用:用於指定key生成器,若需要綁定一個自定義的key生成器,我們需要去實現org.springframewart.cahce.intercceptor.KeyGenerator介面,並使用改參數來綁定
    • 註意點:改參數與上面的key屬性是互斥的

  • cacheManager
    • 作用:指定使用哪個緩存管理器,也就是當有多個緩存器時才需要使用

  • cacheResolver
    • 作用:指定使用哪個緩存解析器
    • 需要通過org.springframewaork.cache.interceptor.CacheResolver介面來實現自己的緩存解析器


15.2.3、@CachePut註解 ( 寫數據時 )

  • 用在寫數據的方法上,如:新增 / 修改方法,調用方法時會自動把對應的數據放入緩存,@CachePut的參數和@Cacheable差不多

@CachePut(value="user", key = "#userId")
public User save(User user) {
	users.add(user);
	return user;
}



15.2.4、@CacheEvict註解 ( 刪除數據時 )

  • 用在刪除數據的方法上,調用方法時會從緩存中移除相應的數據

@CacheEvict(value = "user", key = "#userId")
void delete( Integer userId);

  • 這個註解除了和@Cacheable一樣的參數之外,還有另外兩個參數:
    • allEntries:預設為false,當為true時,會移除緩存中該註解該屬性所在的方法的所有數據
    • beforeInvocation:預設為false,在調用方法之後移除數據,當為true時,會在調用方法之前移除數據


15.2.5、@Cacheing組合註解 - 推薦


@Caching(
	put = {
		@CachePut(value = "user", key = "#userId"),
		@CachePut(value = "user", key = "#username"),
		@CachePut(value = "user", key = "#userAge"),
	}
)

  • 指的是:將userId、username、userAge放到名為user的緩存中存起來


15.3、SpringBoot集成Ehcache

15.3.1、配置Ehache

依賴


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>


application.yml配置文件中加入配置


	cache:
		ehcache:
			# 配置ehcache.xml配置文件所在地
			config: class:ehcache.xml


在主啟動類開啟緩存功能


@SpringBootAllication
@EnableCaching
public class Starter {
	public static void main(String[] args) {
		SpringApplication.run(Starter.class);
	}
}


編寫ehcache.xml配置文件

  • resources目錄下新建rhcache.xml,並編寫如下內容:

<ehcache name="myCache">
    <!--緩存磁碟保存路徑-->
    <diskStore path = "D:/test/cache"/>

    <!--預設的緩存配置
        maxElementsInMemory 緩存最大數目
        eternal 對象是否永久有效 一旦設置了,那麼timeout將不再起作用
        timeToIdleSeconds 設置對象在實效前能允許的閑置時間( 單位:秒 ),預設值是0,即:可閑置時間無窮大
                            僅當eternal=“false"對象不是永久有效時使用
        timeToLiveSeconds 設置對象失效前能允許的存活時間( 單位:秒 )
                             最大時間介於創建時間和失效時間之間
        maxElementsOnDisk 磁碟最大緩存個數
        diskExpiryThreadIntervalSeconds 磁碟失效時,線程運行時間間隔,預設是120秒
        memoryStoreEvictionPolicy 當達到設定的maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理記憶體
                                    預設策略是LRU( 即:最近最少使用策略 )
                                    還可以設定的策略:
                                        FIFO    先進先出策略
                                        LFU     最近最少被訪問策略
                                        LRU     最近最少使用策略
                                                    緩存的元素有一個時間戳,當緩存容量滿了,同時又需要騰出地方來緩存新的元素時,
                                                    那麼現有緩存元素中的時間戳 離 當前時間最遠的元素將被清出緩存

    -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"/>

    <!--下麵的配置是自定義緩存配置,可以複製粘貼,用多套
        name 起的緩存名
        overflowToDisk 當系統宕機時,數據是否保存到上面配置的<diskStore path = "D:/test/cache"/>磁碟中
        diskPersistent 是否緩存虛擬機重啟期數據

        另外的配置項:
            clearOnFlush  記憶體數量最大時是否清除
            diskSpoolBufferSizeMB 設置diskStore( 即:磁碟緩存 )的緩衝區大小,預設是30MB
                                    每個Cache都應該有自己的一個緩衝區
    -->
    <cache
        name="users"
        eternal="false"
        maxElementsInMemory="100"
        overflowToDisk="false"
        diskPersistent="false"
        timeToIdleSeconds="0"
        timeToLiveSeconds="300"
        memoryStoreEvictionPolicy="LRU"
    />
</ehcache>



15.3.2、在項目中使用ehcahe

  • 使用常用的@Cacheable註解舉例

查詢條件是單個時( service實現類中直接開註解 )


// 這裡的value值就是前面xml中配置的哪個cache name值
@Cacheable(value="users", key = "#username")
public User queryUserByUsername(String username) {
	return userMapper.selectUserByUsername(username);
}


查詢條件是多個時( service實現類中直接開註解 )

  • 本質:字元串的拼接

// 這裡的UserDAO.username+就是封裝的UserDAO,裡面的屬性有username、userage、userPhone
@Cache(value="users", key = "#UserDAO.username+'-'+#UserDAO.userage+'-'+#UserDAO.userPhone")
public User queryUserByUsername(UserDAO userDAO) {
	return userMapper.selectUserB

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Spring Ioc源碼分析系列--Bean實例化過程(一) 前言 上一篇文章Spring Ioc源碼分析系列--Ioc容器註冊BeanPostProcessor後置處理器以及事件消息處理已經完成了對IoC容器啟動方法也就是refresh()方法的簡單分析。但是之前的分析在對容器實例化Bean的過程 ...
  • 服務演變之路 單體應用架構 在剛開始的時候,企業的用戶量、數據量規模都⽐較⼩,項⽬所有的功能模塊都放在⼀個⼯程中編碼、編譯、打包並且部署在⼀個Tomcat容器中的架構模式就是單體應用架構,這樣的架構既簡單實用、便於維護,成本⼜低,成為了那個時代的主流架構⽅式。這時候由於業務以及規模都⽐較⼩,所以⽆論 ...
  • 在後面的漏洞研究的學習中,必須要會的幾個知識點。反射機制和動態代理機制。至於反射的前面已經講到過了,這裡就不做更多的贅述了。反射是通過class文件去獲取對象對象的方法. ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 場景說明 現有一個 10G 文件的數據,裡面包含了 18-70 之間的整數,分別表示 18-70 歲的人群數量統計,假設年齡範圍分佈均勻,分別表示系統中所有用戶的年齡數,找出重覆次數最多的那個數,現有一臺記憶體為 4G、2 核 CPU 的電腦,請寫一個演算法實現。 23,31,42,19,60,30,3 ...
  • Conda 創建 Python 虛擬環境不純凈的問題(2021.1.18) 1. 產生環境 Ubuntu 16.04; Conda 4.9.2; Python 3.6; 2. 問題描述 通過 Conda 命令創建 Python 虛擬環境後,利用 pip list 命令查看包列表,發現有很多多餘的包, ...
  • SpringBoot MySQL密碼等敏感信息加密方案(2021.04.27) 一、背景說明 SpringBoot 項目經常將連接資料庫的密碼明文放在配置文件里,安全性就比較低,尤其一些企業對安全性要求很高,因此我們就考慮如何對密碼等敏感信息進行加密。 二、解決方案 通過 Jasypt 對密碼等敏感 ...
  • IO問題一直是面試的重災區之一 但又是非常重要而且面試必問的知識點 一個工作了7年的粉絲私信我,他去面試了 4家互聯網公司, 有三個公司問他網路IO的問題,另外一個公司問了Netty,結果都沒回答上來。 好吧,對於“IO和NIO的區別”,看看普通人和高手的回答。 普通人: 嗯。。。。。。。。。。 高 ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...