快速开发架构Spring Boot 从入门到精通 附源码

👇👇关注后回复 “进群” ,拉你进程序员交流群👇👇

作者:陈彦斌

出处:https://www.cnblogs.com/chenyanbin/

# Spring Boot基础

Spring Boot简介

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。

简单来说,SpringBoot可以简化应用程序的开发,使我们不再需要spring配置文件及web.xml。

# SpringBoot工程和创建

IDEA中的创建

974e4c65a8c2b0aeedb907956df49047.png

19d6379d071700f2e279ddbc19857da5.png

83b4e32cd2779736f8c37d3acb37e812.png

00bdbe1467b97f02e50bbc3048303ae9.png

工程编辑

系统会在前面设置的包中自动生成一个启动类。

a0518ee114a8a7e9110f854f68f1964f.png

在启动类所在的包下再创建一个子包,在其中编写SpringMvc的处理器类。

注意,要求代码所在的包必须是启动类所在的包的子孙宝,不能是同级包。 

72f69f978ea4addbc4daecc18cacddfc.png

启动

ide方式

mac控制台方式(需maven打包)

9412feb1b8c615023124542e0981f1ae.png

官网创建

地址:https://start.spring.io/

配置及生成

00d9ad3682074d8d0a021eea5aa5445d.gif

配置项配置完成后,点击Generate按钮后,即可打开一个下载对话框。官网将配置好的Spring Boot工程生成一个zip压缩文件,只要我们将下载后的文件解压并添加到工程即可使用。

基于war的Spring Boot工程

前面2种方式创建的Spring Boot工程最终被打为了jar包,是以可执行文件的形式出现的,他们都使用了Spring Boot内嵌的Tomcat作为web服务器来运行web应用的。新版的Dubbo的监控中心工程就是典型的应用。但在实际生产环境下,对于web工程,很多时候我们需要的是war包,然后部署到企业级web服务器中。下面来演示如何使用Spring Boot将工程打为war包。

工程创建

24aa9bdbaead4e349c3a0ddd52794529.png

我们看一下pom.xml文件,可以知道,Tomcat打包的时候不打进去

3cbc035af6c3d2af99df10be609e3a0a.png

将项目打包后,仍到Tomcat的wabapps目录下

7d3e4833dfeeb693289c78134b8841ea.png

启动Tomcat

31049c0e987e1ac86e757a8914fa19ca.png

接下来我们查看Tomcat目录

199f49725f98a8f128135f98ca402dac.png

打开网页,注意加上项目名

cdba73369eb96aaf03aecabdae427d87.png

注:mac启动Tomcat过程中遇到点麻烦,1、需要赋予文件夹权限;2、执行shell脚本报错:Operation not permitted,博主参考了下面2个链接配成成功哒

大概配置步骤

1、切换Tomcat的bin目录下
    sudo chmod 755 *.sh


2、解决Operation not permitted
    xattr -d com.apple.quarantine ./*


3、启动Tomcat
    sudo sh ./startup.sh


4、停止Tomcat
  sudo sh ./shutdown.sh
参考链接:注:第一、二链接,赋权限,第三个链接解决Operation not permitted


https://blog.csdn.net/caoxiaohong1005/article/details/53463443 


https://blog.csdn.net/F_Feng0628/article/details/60583250 


https://blog.csdn.net/default7/article/details/80172340

工程解析

创建Spring Boot工程后,会自动生成工程的启动类Application。

21f5260cb6e63e040ba55dd0f856c09b.png

跟踪@SpringBootApplication注解源码可以看到,可以完成Spring Boot的自动配置。

cd98e024dcef015bd748a6e54f6de909.png

继续跟踪@SpringBootConfiguration源码可以看到,其本质是一个@Configuration,使用Java类充当Spring配置文件。

9e857775b717ca765e77467b8e38d141.png

 src/main/resources目录

bd86006a1f73e51a3f34000e113276b8.png

1.static:存放静态资源,如:css,js,images等 

2.templates目录:存放动态资源。Spring Boot不建议使用jsp作为动态数据展示页面,而是建议使用Thymeleaf。Thymeleaf是一种Java模板引擎,可以显示动态数据。Thymeleaf文件的扩展名为html,是对html的扩展。该目录用于存放Thymeleaf文件。

3.这两个目录中存放的资源都相当于存放当前web应用的根下。一般不适用他们存放资源。

4.application.properties:SpringBoot的主配置文件

查看当前工程

在pom.xml文件中包含SpringBoot的两个核心依赖及一个核心插件。一个是SpringBoot的Web启动依赖,一个是SpringBoot的测试启动依赖;而这个核心插件是用于完成对SpringBoot工程打包结果的再打包。

注:他们都没有版本号,这是为什么呢?

5cbb155025e938352d98053ada128b65.png

虽然他们都没有版本号,打开maven可以看到,他们版本均为2.2.2

de456622c8c3c07e6b1c05c39eb50c6b.png

他们的版本号均继承自父工程。从pom文件中可以看到,其父工程为spring-boot-starter-parent。

d95bc6e8ec2a141d4a0e4962784cd77f.png

8feec32014f5a90ca1e81b90e2c1af5c.png

9c70e8335ff8e57ba68b29fa91d584af.png

更换默认springframework的版本(视生产环境降默认版本)

460be0ba850b757aead7cb63488e5de0.png

查看spring-boot-starter-parent工程

打开Maven本地仓库,在org.springframework中找到工程spring-boot-starter-parent。

d832b4abc072c7a09d7ecb8c990ea574.png

打开spring-boot-starter-parent-2.2.2.RELEASE.pom文件,发现该工程的<pluginManagement>中有对该插件的配置信息。

注:<pluginManagement>中声明的插件是选择性继承插件,而非全部继承插件。

24d2a4cc373d8446666be0d4aa847bc2.png

从该插件的配置信息可以得出,其执行的目标是repackage,即对工程进行重新打包。

首次打包是由Maven的package插件完成,其打包的结果仅仅是将当前工程中自定义的类打包成了一个普通的jar包,没有Spring Boot的相关资源,无法直接运行。当然,其打包的结果是.jar文件。

重新打包是由spring-boot-maven-plugin插件完成的,其实将前面打成的jar包进行了二次打包,将原来的软件包变为了Spring Boot可执行包,在其中不仅添加了Spring Boot依赖,还添加了很多其他配置。同时,其还将原来的.jar文件扩展名变为了.orininal,而而二次打包后的文件扩展名成为了.jar。

af5a5f2af9990f0411932c63bcb01641.png

可以打开01-primary-0.0.1-SNAPSHOT.jar

54177ccdcb573554dac486a4d29f02f5.png

BOOT-INF目录:存放的是当前应用程序的类及其所依赖的类

META-INF目录:存放的是Maven相关的配置文件

org目录:存放的是SpringBoot启动所需的类

打开META-INF/MANIFEST.MF,不仅可以看到主类Main-Class,还可以看到当前工程的启动类Start-Class。

0adf0747f8fef4824165ae5269607816.png

maven打包

9a1186e8b88ef7dae75861c05192beb2.png

# Spring Boot热部署

idea中的Spring Boot工程若要使用热部署,需要2不操作:

1.导入devtools依赖

2.编辑工程的配置信息

注:Spring Boot工程在idea和Eclipse中的重启时机不同。Eclipse只要修改的文件保存过了,工程会立马重新部署。而idea则对文件修改后的保存是自动的,所以其重新部署的时机是idea整个ide窗口被钝化时,即窗口切换到其他窗口时,工程会重新部署。

添加依赖

pom.xml#

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

配置

3e0611d15d4ce199f004eb48995ee150.png

当idea被钝化时,即当idea窗口被切换时,更新类与资源。

在开发调试过程中,已经启动了工程的运行。此时又修改了代码或配置文件,若要使修改生效,则需要重新启动工程。这种方式降低了开发效率。

热部署,即修改了代码或配置文件后,一旦保存,系统马上对工程进行自动重启,无需手工重启。若要实现热部署,只需要在pom.xml中添加一个依赖即可。

热部署的使用有利有弊。利:无需手动重启工程;弊:在修改代码或配置后,只要保存系统就会重启工程,即使这个修改还未完毕,其他的会重启,从而导致代码重启后报错。

1、添加依赖

pom.xml

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

2、设置自动生成项目

6645f824a2a6f0166fcadba5e2743924.png

3、Ctrl+Shift+A,打开搜索框,输入:Registry

5c73534e234ecff3dc50c2184b7b761f.png

4、勾选即可 

c9c00e01a3b5dbdd9831c7881d330763.png

# Spring Boot主配置文件

配置文件形式一

Spring Boot的主配置文件是src/main/resources中默认创建的application.properties文件。

a13cf2b6cda31ecdbd5d238fc875f7a5.png

编辑配置文件

1186f65cf89e9c619c91591a686a4a6b.png

启动

555e53ca414770d24719dae45d4a2b83.png

注意事项

注:这里指定的Tomcat端口号,仅仅只针对内置Tomcat的,是测试时使用的。将工程打为war包后部署到真正的Tomcat,这些配置是不起作用的。

配置文件形式二

Spring Boot的主配置文件也可以使用application.yml文件。.yml也可以写成.yaml。

在开发之初YAML的本意是Yet Another Markup Language(仍是一种标记语言)。后来为了强调这种语言是以数据为中心,而不是以标记为中心,所以将标记为中心,所以将YAML解释为Yaml Ain't Markup Language(Yaml不是一种标记语言)。它是一种直观的能够被电脑识别的数据序列化格式,是一个可读性高并且容易被人阅读,容易和脚本语言交互,用来表达多级资源序列的编程语言。

yml与properties文件的主要区别是对于多级属性,即key的显示方式不同。yml文件在输入时,只需按照点(.)的方式输出key既可,输入完毕后回车即出现了如下形式。该形式要求冒号后与值之间有一个空格(语法格式)。

e8e9bab97c57a34f5355e9927ab9834b.png

注意事项

注:application.properties与application.yml这两个文件只能有一个。要求文件名必须是:application。

Actuator

Actuator是Spring Boot提供的对应用系统的自省和监控的集成功能,可以对应用系统进行配置查看、相关功能统计等。在Spring Colud中主要是完成微服务的监控,完成监控治理。可以查看微服务间的数据处理和调用,当它们之间出现了异常,就可以快速定位到出现问题的地方。

其功能与Dubbo的监控中心类似,不同的是,Dubbo的监控中心是需要专门部署的,而Spring Boot的Actuator是存在于每个工程中。

环境搭建

随便一个Spring Boot工程中都可以使用Actuator对其进行监控。

添加依赖

pom.xml

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

修改配置文件

application.properties

# 当前应用的端口与上下文路径
server.port=8888
server.servlet.context-path=/cyb




# Actuator监控的端口号与上下文路径
management.server.port=9999
management.server.servlet.context-path=/cyb2




# 指定监控终端的基本路径,默认为actuator
management.endpoints.web.base-path=/base

启动项目并测试

87227a0367313d3fa0ae0bf0a99d5278.png

添加Info信息

修改配置文件

在配置文件中添加如下Info信息,则可以通过Info控制终端查看到。

62276634cdf1f0d2aad4f3f1ad5eb676.png

测试

d4abbc8ae3a289736c9aafb593ef06f0.png

注:博主浏览器安装了JSON格式化工具,所以显示的是JSON格式化后的状态

ae3bdb33e6b680e98192eb0d20c13608.png

开发其他监控终端

默认情况下,Actuator仅开放了health与Info两个监控终端,但它还有很多终端可以监控,需手动开放。

修改配置文件

506ea86ff2e14d6232b51a0bf58cef93.png

mappings终端

mappings可以看到当前工程中所有的URI与处理器的映射关系,及详细的处理器方法以及其映射规则。很实用!!!

aaa5fe195c90c876df9de77d37a35f16.png

beans终端

419446c1b4fb34a3fffb4c467146216a.png

evn终端

可以看到当前应用程序运行主机的所有软硬件环境信息。

ba7e2e49a943eaaedde38619d6c419d3.png

单独关闭某些监控终端

在开放了所有监控终端的情况下,有些终端显示的信息并不想公开,此时可以单独关闭这些终端。

修改配置文件

5eda5f3d9b3f0041e452365ca2df73db.png

测试

其他的监控终端不受影响。

a0d03e1fb7a901fe35fa8a26762108c5.png

其他常用的监控终端如下

若没有你需要的,可以自行百度搜“springboot actuator”

fffaacfdf0a9b17a14557805d52b40e2.png

e308bec53f197605bc114ed67e50352b.png

# Spring Boot重要用法

自定义异常页面

对于404、405、500等异常页面,而这些异常页面一般都是英文的,非常不友好。我们可以通过简单的方式使用自定义异常页面,并将默认状态码页面进行替换。

定义目录

在src/main/resources目录下新建目录:public/error。

定义异常页面

在error目录中定义异常页面。这些异常页面的名称必须为相应的状态码,扩展名为html。

7b41f8ab343f62428167746d09a4c669.png

单元测试

添加依赖

pom.xml

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

接口类

ISomeService.java

package com.cyb.webdemo.controller;




public interface ISomeService {
    void doSome();
}

接口实现类

SomeServiceImpl.java

package com.cyb.webdemo.controller;




import org.springframework.stereotype.Service;




@Service
public class SomeServiceImpl implements ISomeService{
    @Override
    public void doSome() {
        System.out.println("执行Service的doSome");
    }
}

测试类

类上需添加两个注解:

1、@RunWith(SpringRunner.class)

2、@SpringBootTest(classes = Spring Boot启动类.class)

b554fe6cf13ab2a857423df16339c1af.png

# 多环境选择

什么是多环境选择?

在开发应用时,通常同一套程序被运行在多个环境,例如,开发、测试、生产环境等。每个环境的数据库地址、服务器端口号等配置都会不同。若在不同环境下运行时将配置文件修改为不同内容。那么,这种做法不仅非常繁琐,而且很容易发生错误。

在开发应用时,有时不同的环境,其需要运行的接口的实现类也是不同的。例如,若要开发一个具有短信发送功能的应用,开发环境中要执行的send()方法仅需要调用短信模拟器即可,而生产环境中要执行的send()则需要调用短信运营商所提供的短信发送接口。这种情况下,就需要开发两个相关接口的实现类去实现send()方法。

对于不同的环境,需要使用不同的配置文件,执行不同的类。而这个选择只需要在Spring Boot的主配置文件中指定即可。

下面以不同的环境“使用配置有不同的端口号的配置文件,以及调用不同的接口实现类”为例演示多环境选择问题的解决。

Example

1、创建几个配置文件,格式:application-xxxxx.properties

046d76b111df9bd8989a11147159441f.png

3aa46e6d6ccf1f47ad7ac832c96aadc5.png

4db4552eac2e511f185ba434ef9273e8.png

2、创建一个包,并创建一个接口,内容如下

5bd39e2f5cbf85f352a56cb291e954f7.png

3、创建DevMsgServiceImpl开发环境类

注:@Profile("xxx")中的值要和application-xxx.properties对应上

7072790fd4c2ca001abebb2e315e3ad7.png

4、创建ProMsgServiceImpl生产环境

注:@Profile("xxx")中的值要和application-xxx.properties对应上

3bc4a39a7428e07497e2a8387ae220b9.png

5、创建处理器:MsgController

5b59535e756d215a07eb63d8209b4e06.png

6、测试

正确请求

7fd9394b48601312f51eeb108ca739e4.png

错误请求

1cd5bedc84cb3c5cb6f1b7404303d599.png

说明

在Spring Boot中多环境配置文件名需满足:application-[profile].properties的格式,其中[profile]为对应的环境标识,例如

1.application-dev.properties:开发环境

2.application-pro.properties:生产环境

至于那个配置文件会被加载,取决于application.properties中的spring.profiles.active属性来设置,其值对应[profile]。例如spring.profiles.active=dev就会加载application-dev.properties配置文件内容。

在实现类上添加@Profile注解,并在注解参数中指定前述配置文件中的[profile]值,用于指定该实现类所使用的环境。

以上开发过程中碰到的问题都解决啦~~~~

7、在命令行下选择环境

将工程打为Jar包后,在命令行运行。若要想切换运行环境,必须要修改主配置文件吗?答案是否定的。只需添加一个命令参数即可动态指定。

例如,现在的主配置文件中指定的是dev环境

47c430bed13e740f11cfcbc81791d710.png

将当前工程打为Jar包后,在命令行运行时添加如下参数

eed5767691763f4d69962f4258063149.png

此时执行的就是生产环境,调用的就是ProduceServiceImpl类

e1fd2259e0c15e0862a1c12f8ace1071.png

读取自定义配置

自定义配置,可以是定义在主配置文件:application.properties中的自定义属性,也可以是自定义配置文件中的属性。

读取主配置文件中的属性

application.properties

a1e655a141b9d4030af77fca3f367b6c.png

SomeController.java

b5883ebd97fba5bf8baa50e045e3ca10.png

实现

31c55cdb1f59cbb8c067bf59656d895d.png

读取指定配置文件中的属性

创建配置文件:cybApplication.properties

579c762e5f6fb324eb9ff4f2c3f3cddc.png

SomeController.java 

596c99993fd87c77ef143c0476c2b33e.png

实现 

f74cf1469e01bf9a047ab8c6db20afb6.png

读取对象属性

cybApplication.properties

498ab6c558583d48d4300656c25c8e3b.png

实体类:cyb.java

905fe72a42c8cbc364188f316d08a62b.png

说明

1.@PropertySource:用于指定要读取的配置文件。

2.@ConfigurationProperties:用于指定要读取配置文件中的对象属性。

3.@Component:当前从配置文件读取来的对象,由Spring容器创建。

SomeController.java

7ee4a98566cc8055cdde00e7a604ab8b.png

实现

afab543b9a365a4672c80e912c73f1b9.png

读取List属性1

cybApplication.properties

16fff2837c7305cd6d93ef1ab6c44f26.png

实体类:UserName

0f33fee4d02db8ba7593f5ba34751035.png

SomeController.java

abad0eb12f8f8a55c091bdfb819f0d0f.png

实现

78de443843aefea0d88f04371a23a404.png

读取List属性2

cybApplication.properties

0c51627c4606742c495340bd9582beaf.png

Group.java

24360a884358ab3e0c2e0c8520a157b8.png

students.java

851db34d98febf92f8391eaa8764ffcc.png

SomeController.java

1518a8c658bbf1be46d7382c4382e605.png

实现

94a956ab5d9b5bac3ad0cf69e9c554f2.png

补充知识(lombok)

lombok方式配置实体类。没用过的小伙伴,可以参考Lombok介绍、使用方法和总结进行脑补,这里只演示使用

1、idea安装lombok

6516d90faab3769ac96e9979fd04340f.png

2、添加依赖

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

3、实体类上加@Data即可

package com.cyb.webdemo.controller;




import lombok.Data;




@Data
public class studens {
    private String name;
    private int age;




//    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;
//    }
}

注:lombok省去了get/set,让代码更简洁。

Spring Boot下使用JSP页面

添加JSP解析依赖#

pom.xml

<dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>

创建webapp目录

在src/main下创建webapp目录,用于存放jsp文件。创建的是一个普通目录,需要指定为web资源目录,然后才可以创建jsp文件。File->Project Structure

0c4b8ad2dddf3961c9a522d3fa560df1.png

fc07b1b46bf1c64d7f00f2a8414f95f3.png

添加JSP注册资源目录#

pom.xml

<build>
        <resources>
            <!--注册dao包下mybatis映射文件为资源目录-->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <!--注册webapp目录为资源目录-->
            <resource>
                <directory>src/main/webapp</directory>
                <targetPath>META-INF/resources</targetPath>
                <includes>
                    <include>**/*.*</include>
                </includes>
            </resource>
        </resources>
    </build>

创建JSP页面

0f46cf95aa7fec26f4c21b6bed06a9d0.png

实现

57d91691ea222fb2997e42628e2f363f.png

创建welcome.jsp

f1e925bac4c83eb72ac3c9f783e8fd66.png

创建home.jsp

82b5d65c036e38c150af35ba78374b72.png

SomeController.java

2006ba364ea5a38dc7ebd652318a8197.png

实现

da449af03d15bb54eec7b4e825e1d621.png

关于静态资源请求

Spring Boot已经处理好了静态资源访问问题。

视图前/后缀

c1f5c6d9a664b6a60f72ae02d56faf87.png

Spring Boot中使用MyBatis

添加依赖项

MyBatis与Spring Boot整合依赖#

pom.xml

<!--Mybatis与Spring Boot整合依赖,必须要版本号-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

MySql驱动依赖

pom.xml

<!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

Druid连接池依赖

pom.xml

<!--Druid连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

lombok依赖(可忽略,用于实体类)#

pom.xml

<!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

注:若使用lombok需配置ide。

注册资源目录文件

pom.xml

<build>
        <resources>
            <!--注册dao包下mybatis映射文件为资源目录-->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <!--注册webapp目录为资源目录-->
            <resource>
                <directory>src/main/webapp</directory>
                <targetPath>META-INF/resources</targetPath>
                <includes>
                    <include>**/*.*</include>
                </includes>
            </resource>
        </resources>
    </build>

注:若不注册dao包下的mybatis映射文件,需将xxx.xml文件放到:/resource,并且修改application.properties文件中的mybatis.mapper-locations映射路径!!!!!!!

资源文件

application.properties

# 视图的前缀和后缀
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp




# 注册映射文件
mybatis.mapper-locations=classpath:com/cyb/webdemo/dao/EmployeeDao.xml
# 注册实体类别名
mybatis.type-aliases-package=com.cyb.webdemo.bean.EmployeePo
# 注册数据源类型
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 数据库连接字符串
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/cyb
spring.datasource.username=root
spring.datasource.password=root

创建jsp

index.jsp

3729e9c41d0b79aefe61ebe571101c30.png

实体类(Po)

EmployeePo.java

83dd23f126b8ab0f71b20ab56451912b.png

注意

案例中使用了lombok依赖(idea中需要配置,可以参考前面讲解lombok配置环境方法),所以实体类中可以不设置get/set方法。

dao层(数据访问层)

EmployeeDao.java

41032f06f2715b177befa83146014a51.png

注:mybatis映射文件的存放位置!!!!!

代码拷贝区

package com.cyb.webdemo.dao;




import com.cyb.webdemo.bean.EmployeePo;
import org.apache.ibatis.annotations.Mapper;




@Mapper
public interface EmployeeDao {
    void insertEmployee(EmployeePo employeePo);
}
<?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE mapper
                PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cyb.webdemo.dao.EmployeeDao">
<insert id="insertEmployee">
    insert into employee (name,age) values (#{name},#{age})
</insert>
</mapper>

service层(业务层)

EmployeeService.java(接口)

51321129c579fd96841d37964b782dd8.png

代码拷贝区

package com.cyb.webdemo.service;




import com.cyb.webdemo.bean.EmployeePo;




public interface EmployeeService {
    void addEmployee(EmployeePo employee);
}
package com.cyb.webdemo.service;




import com.cyb.webdemo.bean.EmployeePo;
import com.cyb.webdemo.dao.EmployeeDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;




@Service
public class EmployeeServiceImpl implements EmployeeService{




    @Autowired(required = false)
    private EmployeeDao dao;
    @Override
    public void addEmployee(EmployeePo employee) {
        dao.insertEmployee(employee);
    }
}

Controller层

package com.cyb.webdemo.controller;




import com.cyb.webdemo.bean.EmployeePo;
import com.cyb.webdemo.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;




@RestController
public class RegisterHandler {
    @Autowired(required = false)
    private EmployeeService service;
    @PostMapping("register")
    public String RegisterHandler(EmployeePo employee){
        service.addEmployee(employee);
        return "ok";
    }
}

扫描dao层(可忽略)

c717f1fec2788c11439214cd35ee59e6.png

b775ff2ce561b839c7f235cf356ca446.png

Spring Boot事务支持

步骤

1.在启动类上添加@EnableTransactionManagement

注解,开启事务

2.在Service实现类的方法上添加@Transactional

注解

f6289609ca81d3354034b69911e4bf6c.png

Spring Boot对日志的控制 

logback日志技术

Spring Boot中使用日志技术为logback。其与Log4J都出自一人,性能要优于Log4J,是Log4J的替代者。

在Spring Boot中若要使用logback,则需要具有spring-boot-starter-logging依赖,而该依赖被spring-boot-starter-web依赖,即不用直接导入spring-boot-starter-logging依赖(间接依赖)。

1e96ae7eaf4931cdc59712b4e88e5ca1.png

方式一

xml方式

必须放到src/main/resources类路径下!!!。

cb824ec7230413424d105fdc77665ffb.png

代码拷贝区

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appender name="myConsole" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%-5level - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="WARN">
        <appender-ref ref="myConsole"></appender-ref>
    </root>
    <logger name="com.cyb.webdemo.dao.EmployeeDao" level="DEBUG"></logger>
</configuration>

方式二

application.properties#

1e619af796dca587b7e15569a5db0b69.png

代码拷贝区

application.properties

# 控制日志显示格式
logging.pattern.console=%leven %msg%n
logging.level.root=warn
# 格式:logging.level.dao层命名空间
logging.level.com.cyb.webdemo.dao.EmployeeDao=debug

实现

8f876cbc248e62f44812faf6f52863df.png

Spring Boot中使用Redis(解决高并发,重点!!)

注意

案例从头到尾,使用都是同一个项目,代码配置结构复杂,看红色圈中的代码,敲黑板划重点!!!!!

学前预习

Redis还不会的小伙伴,请先预习:分布式架构-Redis 从入门到精通 。

应用场景

使用Redis缓存的数据划分为两类:

1.DB表中的数据更新后,Redis缓冲的相关数据要清除,要不然客户端获取的不是最新数据。

2.对数据准确性要求不高的数据,可以与DB表中的数据不一致,但差别不能太大,所以该类数据一般会设置过期1时效。

启动redis服务器

44442110f8451fd936ec6e8dacb30f77.png

Spring Boot与Redis整合依赖#

完整pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.cyb</groupId>
    <artifactId>webdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>webdemo</name>
    <description>Demo project for Spring Boot</description>




    <properties>
        <java.version>13</java.version>
    </properties>




    <dependencies>
        <!--Mybatis与Spring Boot整合依赖,必须要版本号-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>




        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>




        <!--Druid连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>




        <!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>




        <!--Spring Boot与redis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>




        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>




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




        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>




    </dependencies>




    <build>
        <resources>
            <!--注册dao包下mybatis映射文件为资源目录-->
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <!--注册webapp目录为资源目录-->
            <resource>
                <directory>src/main/webapp</directory>
                <targetPath>META-INF/resources</targetPath>
                <includes>
                    <include>**/*.*</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>




</project>

修改主配置文件

application.properties

67d1b11e3d944c6b54790ff746867294.png

代码拷贝区

# 视图的前缀和后缀
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp




# 注册映射文件
mybatis.mapper-locations=classpath:com/cyb/webdemo/dao/EmployeeDao.xml
# 注册实体类别名
mybatis.type-aliases-package=com.cyb.webdemo.bean.EmployeePo
# 注册数据源类型
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 数据库连接字符串
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/cyb
spring.datasource.username=root
spring.datasource.password=root




# 控制日志显示格式
logging.pattern.console=%leven %msg%n
logging.level.root=warn
# 格式:logging.level.dao层命名空间
logging.level.com.cyb.webdemo.dao.EmployeeDao=debug




# 连接redis
spring.redis.host=192.168.31.200
spring.redis.port=6379
spring.redis.password=root
# 连接redis集群,redis利用哨兵机制实现高可用
# spring.redis.sentinel.master=mymaster
# spring.redis.sentinel.nodes=sentinel1:6370,sentinel2:6371,sentinel3:6372




# 指定缓存类型
spring.cache.type=redis
# 设置缓存名称
spring.cache.cache-names=realTimeCache

JSP页面

index.jsp

57c463f018cdcf278409311a0048241d.png

代码拷贝区

<%--
  Created by IntelliJ IDEA.
  User: chenyanbin
  Date: 2020/1/6
  Time: 7:13 下午
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="register" method="post">
    姓名:<input type="text" name="name"><br/>
    年龄:<input type="number" name="age"><br/>
    <input type="submit" value="注册">
</form>
<hr>
<form action="find" method="post">
    id:<input type="text" name="id">
    <input type="submit" value="查询">
</form>
<a href="count">查看员工总数</a>
</body>
</html>

实体类

EmployeePo.java

a25a7b7ed6fdd40154fb94555080cfda.png

数据库表字段

b668f8079df2622d1589e1a1e78cab58.png

Dao层(数据访问层)

EmployeeDao.java

660d020995806820a9e9ee16bc186673.png

映射文件

EmployeeDao.xml

d3d2b9cee3b1265560145542015cce28.png

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cyb.webdemo.dao.EmployeeDao">
    <insert id="insertEmployee">
    insert into employee (name,age) values (#{name},#{age})
</insert>
    <select id="selectEmployeeById" resultType="com.cyb.webdemo.bean.EmployeePo">
        select id,name,age from employee where id=#{id}
    </select>
    <select id="selectEmployeeCount" resultType="int">
        select count(1) from employee
    </select>
</mapper>

Service(业务层)

EmployeeService.java(接口)

deb87e39f931481cd5647a73bfc0af92.png

EmployeeServiceImpl.java(接口实现类)

注:双重检测锁非常重要!!!!

040b3afbeb322299943c28b5106308be.png

代码拷贝区

package com.cyb.webdemo.service;
import com.cyb.webdemo.bean.EmployeePo;
import com.cyb.webdemo.dao.EmployeeDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.concurrent.TimeUnit;
@Service
public class EmployeeServiceImpl implements EmployeeService {
    @Autowired(required = false)
    private EmployeeDao dao;
    @CacheEvict(value = "realTimeCache", allEntries = true)
    // 清除缓存,实际生产环境就这样玩,因为每个实体类设置不同的缓存区空间,范围小,清除缓存好操作
    @Transactional
    @Override
    public void addEmployee(EmployeePo employee) {
        dao.insertEmployee(employee);
    }
    @Cacheable(value = "realTimeCache", key = "'employee_'+#id")
    // 先会去缓存中查下key是否存在,存在:则直接拿缓存中的数据;不存在:去数据库中查,查完将结果放入缓存中
    @Override
    public EmployeePo findEmployeeById(int id) {
        return dao.selectEmployeeById(id);
    }
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    //使用双重检测锁,解决热点缓存问题
    //双重检测锁,解决了高并发下,对数据库访问的压力!!!!
    //热点缓存脑补,请参考:https://www.jianshu.com/p/6e37a1a9c160
    @Override
    public int findEmployeeCount() {
        //获取Redis操作对象
        BoundValueOperations<Object, Object> ops = redisTemplate.boundValueOps("count");
        //从缓存中读取数据
        Object count = ops.get();
        if (count == null) {
            synchronized (this) {
                count = ops.get();
                if (count == null) {
                    //从DB中查询
                    count = dao.selectEmployeeCount();
                    //将查询的数据,写入Redis缓存,并设置到期时限
                    ops.set(count,10, TimeUnit.SECONDS);
                }
            }
        }
        return (int) count;
    }
}

实现

def4934849b2f8afa779e33cea9f28c1.png

注:细心的小伙伴发现,一个问题,根据id查询数据库的时候,为什么控制台没有打印sql语句呢???对表进行增删改时,清除缓存,查询时设置缓存,因为之前演示的时候,已经将缓存写入到redis服务器中了,查询的时候,拿的是缓存数据!!

a22187057d3cd1dc451989d2c065758b.png

Redis自动生成key(高级用法)

自动生成类

RedisCacheConfig.java

package com.cyb.webdemo.controller;




import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Configuration;




@Configuration
public class RedisCacheConfig extends CachingConfigurerSupport {
    // 自定义生成key结构:类名_方法名_参数值
    // 本例:EmployeeServiceImpl_findEmployeeById_1
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> {
            //获取注解所标的方法所在类的类名
            String className = target.getClass().getName();
            //获取注解所标注的方法的方法名
            String methodName = method.getName();
            return className + "_" + methodName + "_" + params[0].toString();
        };
    }
}

6345d577bbd8426ea930279d92d6dcb2.png

实现

a634b76f3f009ea48f2f9e250105b03c.png

Spring Boot拦截器

在非Spring Boot工程中若要使用Spring Mvc的拦截器,在定义好拦截器后,需要在Spring配置文件中对其进行注册。但在Spring Boot工程中没有Spring的配置文件,那么如何使用拦截器呢?

Spring Boot对于原来在配置文件配置的内容,现在全部体现在一个类中,该类需要继承WebMvcConfigurationSupport类,并使用@Configuration进行注册,表示该类为一个JavaConfig/codeConfig类,充当配置文件的角色。

定义拦截器

SomeInterceptor.java#

package com.cyb.webdemo.controller;




import org.springframework.web.servlet.HandlerInterceptor;




import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;




public class SomeInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截器:"+request.getRequestedSessionId());
        return true;
    }
}

注:返回值 true:不拦截;false:拦截

配置文件类

MyMvcConfiguration.java#

package com.cyb.webdemo.controller;




import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;




@Configuration //表示该类充当配置文件
public class MyMvcConfiguration extends WebMvcConfigurationSupport {
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        SomeInterceptor someInterceptor = new SomeInterceptor();
        registry.addInterceptor(someInterceptor)
                .addPathPatterns("/one/**") //拦截one开头请求
                .excludePathPatterns("/two/**"); //允许two开头的请求
    }
}

注:**:代表多级目录;*:只有一级目录;

一般设置全部拦截addPathPatterns("/**");再设置局部的不拦截excludePathPatterns("/xx/**")

定义处理器

package com.cyb.webdemo.controller;




import com.cyb.webdemo.bean.EmployeePo;
import com.cyb.webdemo.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;




@Controller
public class SomeController {
    @RequestMapping("/two/index")
    public String RegisterHandler(){
        return "two";
    }
    @RequestMapping("/one/index")
    public String RegisterHandler2(){
        return "one";
    }
}

Spring Boot中使用Servlet

在Spring Boot中使用Servlet,根据Servlet注册方式的不同,有两种使用方式。若使用的是Servlet3.0+版本,则两种方式均可使用;若使用的是Servlet2.5版本,则只能使用配置类方式。

注解方式

若使用Servlet3.0+版本,可以使用注解方式,分两步。

1.在定义好的Servlet上使用@WebServlet注解

2.在入口类上添加@ServletComponentScan注解

cybServlet.java

package com.cyb.webdemo.servlet;




import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;




@WebServlet(name = "/cyb")
public class cybServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().println("hello spring boot servlet!");
    }
}

入口类

WebdemoApplication

2a7786b05a3b633e34ce62e2be535dc6.png

实现

c3879c1c902a8c196a2081266a6444ad.png

配置类方式

若使用的是Servlet2.5版本,没有Servlet注解,此时只能使用配置类方式。其总步骤有两步,无需再入口类上添加@ServletComponentScan注解

定义Servlet

package com.cyb.webdemo.servlet;




import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;




public class SomeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().println("servlet");
    }
}

定义配置类

package com.cyb.webdemo.servlet;




import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;




@Configuration //表示其为配置类,相当于applicationContext.xml文件
public class MyApplicationContext {
    @Bean //表示该方法返回的对象即为Spring容器中的Bean,方法名随意
    public ServletRegistrationBean<SomeServlet> getServletBean(){
        // 创建Servlet
        SomeServlet someServlet=new SomeServlet();
        // 注册Servlet
        return new ServletRegistrationBean<SomeServlet>(someServlet,"/cyb");
    }
}

实现

09dd86a7992f3b928b9133c8d81a1621.png

Spring Boot中使用Filter

在Spring Boot中使用Filter与前面的使用Servlet相似,根据Filter注册方式的不同,有两种使用方式。若使用的是Servlet3.0+版本,则两种方式均可使用;若使用的是Servlet2.5版本,则只能使用配置类方式。

注解方式

若使用的是Servlet3.0+版本,可以直接使用Filter的注解对Filter进行注册。有两步

1.在定义好的Filter上使用@WebFilter注解

2.在入口类添加@ServletComponentScan注解

SomeFilter.java

package com.cyb.webdemo.file;




import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter("/*")
public class SomeFilter implements Filter {




    @Override
    public void init(FilterConfig filterConfig) throws ServletException {




    }




    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("信息已被过滤");
        chain.doFilter(request,response);
    }




    @Override
    public void destroy() {




    }
}

修改入口类

package com.cyb.webdemo;




import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.transaction.annotation.EnableTransactionManagement;




@SpringBootApplication
@EnableTransactionManagement //开启事务
@EnableCaching //开启缓存
@ServletComponentScan("com.cyb.webdemo.file") //注意是包名
public class WebdemoApplication {




    public static void main(String[] args) {




        SpringApplication.run(WebdemoApplication.class, args);
    }
}

配置方式

若使用的是Servlet2.5版本,没有Filter注解,此时只能使用配置类方式。有两步,与@ServletComponentScan注解无关。

定义Filter#

package com.cyb.webdemo.file;




import javax.servlet.*;
import java.io.IOException;




public class SomeFilter implements Filter {




    @Override
    public void init(FilterConfig filterConfig) throws ServletException {




    }




    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("信息已被过滤");
        chain.doFilter(request, response);
    }




    @Override
    public void destroy() {




    }
}

修改配置类

package com.cyb.webdemo.file;




import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;




@Configuration
public class MyFilter {
    @Bean
    public FilterRegistrationBean<SomeFilter> getFilterBean(){
        FilterRegistrationBean<SomeFilter> registrationBean=new FilterRegistrationBean<SomeFilter>(new SomeFilter());
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
}

Thymeleaf

Thymeleaf,百里香叶。Thymeleaf是一个流行的模板引擎,该模板引擎采用Java语言开发。模板引擎为了使用户界面与业务数据(内容)分离而产生,它可以生成特定格式的文档。例如,用于网站的模板引擎就会生成一个标准的HTML文档。不同的语言体系中都有自己的模板引擎,例如,Java中常见的模板引擎有Velocity、Freemaker、Thymeleaf等。不同的模板引擎都会具有自己的特定的标签体系,而Thymeleaf以HTML标签为载体,在HTML的标签下实现对数据的展示。

Thymeleaf本身与Spring Boot没有关系,但Spring Boot官方推荐使用Thymeleaf作为前端页面的数据展示技术,Spring Boot很好地集成了这种模板技术。

官网:https://www.thymeleaf.org/

Spring Boot集成Thymeleaf

创建项目

1013473d469863f98e9e7b5fc169ef8e.png

配置文件

application.properties

bf0bf48795679c8e7de6339a1cb2d7da.png

处理器

9ee122ad7d19dafeda587ce7419bf568.png

index.html

在页面的<html>标签中添加Thymeleaf的命名空间属性:

<html lang="en" xmlns:th="https://www.thymeleaf.org/">

9b9e29be8a4cb1a565ea5846f77faccf.png

实现

47a585acd8b1400afd14b624ac21690d.png

Thymeleaf标准表达式

常用的Thymeleaf标准表达式有三种。标准表达式都是用于获取代码中存放到Model中的属性值,只不过获取方式不同罢了。

变量表达式:${...}#

使用${...}的表达式,称为变量表达式。该表达式的内容会显示在HTML标签体文本处。

该表达式一般都是通过th:text标签属性进行展示的。

实体类(Po)

13e5a0edcf7154a872dfca3bfef334fa.png

处理器

069571591c9dd6627c16cabefb998280.png

index.html

方式一,直接使用实体类属性

64cef4fbf9f663b337cfce28cfba6794.png

方式二:使用实体类get方法获取值

2833e8b1234de6c3e209195a94b3b377.png

注:两种获取值的方式效果都是一样的。

实现

25a234fa88c5fafda1426f976af4c77c.png

选择表达式:*{...}#

选择表达式,也称为星号表达式。一般用于展示对象的属性。该表达式的内容会显示在HTML标签体文本处。但其需要与th:object标签属性联用,先使用th:object标签选择了对象,再使用*{...}选择要展示的对象属性。该表达式可以有效降低页面中代码的冗余。

也可以不与th:object联用,在*{...}中直接使用“对象.属性”方式,这种写法与变量表达式相同。

该表达式一般都是通过th:text标签属性进行展示。

index.html修改#

73477101bcb36cbb081f2822d415302b.png

实现

8fcdd0542e0e9bc83574e47b2c654756.png

URL表达式:@{...}

其中只能写一个绝对URL或相对URL地址的表达式,称为URL表达式。这个绝对/相对URL地址中一般是包含有动态参数的,需要结合变量表达式${...}进行字符串拼接。

@{...}中的URL地址有3种写法。

以Http协议开头的绝对地址

在进行字符串拼接时使用“+”连接,容易出错。但使用双竖线则无需字符串拼接,简单易读。但是,在idea中的问号会报错,不影响程序运行,可能是idea的bug吧。

index.html

4190655c2cc43e8f8787c9564d920066.png

查看网页源码

65c727a5fd6d1f9a8a495c956189c94a.png

以/开头的相对地址

在URL表达式中,Thymeleaf会将/解析为当前工程的上下文路径ContextPath,而浏览器会自动为其添加"http://主机名:端口号",即为一个绝对路径

fcbdb360e97acf205c983eb9613d9cc6.png

不以/开头的相对地址

48c72b50ef82552a3b12943de297d36a.png

查看页面源码可以看到解析结果是没有添加任何东西的,没有上下文路径,其实相对于当前请求路径的一个绝对地址。

自行学习

授人以鱼不如授人以渔,其他具体的使用用法,请参照官网API:https://www.thymeleaf.org/documentation.html

-End-

最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!

90652c34e5b2c4f562d554dc521ddefd.png

点击👆卡片,关注后回复【面试题】即可获取

在看点这里84755761771297d158f94e0a0ab7ac7d.gif好文分享给更多人↓↓

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值