Spring Boot 2 学习笔记

12 篇文章 7 订阅

文章目录

0、他人笔记

SpringBoot2核心技术与响应式编程基于SpringBoot2.3与2.4版本

SpringBootWeb模块的默认规则研究

Spring Boot 2 学习笔记(1 / 2)

Spring Boot 2 学习笔记(2 / 2)

1、入门案例

1.1、创建一个新的 Module,选择类型为 Spring Initializr

在这里插入图片描述

1.2、指定 GAV 及 pom 配置信息

在这里插入图片描述

1.4、选择 Spring Boot 版本及依赖

会根据选择的依赖自动添加起步依赖并进行自动配置
在这里插入图片描述

1.5、修改 Content Root 路径及文件所在目录

在这里插入图片描述

1.6、对 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.3.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.bjpowernode.springboot</groupId>
    <artifactId>003-springboot-contextpath-port</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--SpringBoot框架web项目起步依赖-->
        <!--SpringBoot 框架 web 项目起步依赖,通过该依赖自动关联其它依赖,不需要我们一个一个去添加了
-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <!--SpringBoot项目编译打包的插件-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

1.7、对 SpringBoot 项目结构进行说明

在这里插入图片描述

➢ .mvn|mvnw|mvnw.cmd:使用脚本操作执行 maven 相关命令,国内使用较少,可删

➢ .gitignore:使用版本控制工具 git 的时候,设置一些忽略提交的内容
➢ static|templates:后面模板技术中存放文件的目录
➢ application.properties:SpringBoot 的配置文件,很多集成的配置都可以在该文件中
进行配置,例如:Spring、springMVC、Mybatis、Redis 等。目前是空的
➢ Application.java:SpringBoot 程序执行的入口,执行该程序中的 main 方法,SpringBoot
就启动了

1.8、创建一个 Spring MVC 的 Spring BootController

SpringBootController 类所在包:com.bjpowernode.springboot.web
注意:新创建的类一定要位于 Application 同级目录或者下级目录,否则 SpringBoot 加
载不到。

package com.bjpowernode.springboot.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class SpringBootController {

    @RequestMapping(value = "/say")
    public @ResponseBody Object index(){
        return "Hello SpringBoot!";
    }
}

1.9、在 IDEA 中右键,运行 Application 类中的 main 方法

通过在控制台的输出,可以看到启动 SpringBoot 框架,会启动一个内嵌的 tomcat,端
口号为 8080,上下文根为空
在这里插入图片描述

1.10、 在浏览器中输入 http://localhost:8080/springBoot/say 访问

在这里插入图片描述

1.11、入门案例分析

➢ Spring Boot 的父级依赖 spring-boot-starter-parent 配置之后,当前的项目就是 Spring
Boot 项目
➢ spring-boot-starter-parent 是一个 Springboot 的父级依赖,开发 SpringBoot 程序都需
要继承该父级项目,它用来提供相关的 Maven 默认依赖,使用它之后,常用的 jar
包依赖可以省去 version 配置
➢ Spring Boot 提供了哪些默认 jar 包的依赖,可查看该父级依赖的 pom 文件
➢ 如果不想使用某个默认的依赖版本,可以通过 pom.xml 文件的属性配置覆盖各个
依赖项,比如覆盖 Spring 版本

<spring-framework.version>5.0.0.RELEASE</ spring-framework.version >

➢ @SpringBootApplication 注解是 Spring Boot 项目的核心注解,主要作用是开启
Spring 自动配置,如果在 Application 类上去掉该注解,那么不会启动 SpringBoot
程序
➢ main 方法是一个标准的 Java 程序的 main 方法,主要作用是作为项目启动运行的入

➢ @Controller 及 @ResponseBody 依然是我们之前的 Spring MVC,因为 Spring Boot
的里面依然是使用我们的 Spring MVC + Spring + MyBatis 等框架

2、SpringBootController里面的用法

SpringBoot 中常用注解@Controller/@RestController/@RequestMapping/@SpringBootApplication介绍

@Controller/@RestController/@RequestMapping介绍

@SpringBootApplication:这是一个Springboot的应用

@RequestMapping与@GetMapping和@PostMapping等新注释

@RequestMapping与@GetMapping和@PostMapping等新注释

@PathVariable注解使用

@PathVariable注解使用

@RequestParam注解使用

@RequestParam注解使用

3、Spring Boot 自定义配置

在 SpringBoot 的核心配置文件中,除了使用内置的配置项之外,我们还可以在自定义配
置,然后采用如下注解去读取配置的属性值

3.1、 @Value

@Value
(11) @Value 注解
A、 项目名称:007-springboot-custom-configuration
用于逐个读取 application.properties 中的配置
案例演示
➢ 在核心配置文件 applicatin.properties 中,添加两个自定义配置项 school.name 和
website。在 IDEA 中可以看到这两个属性不能被 SpringBoot 识别,背景是桔色的
在这里插入图片描述
application.yml 格式配置文件
在这里插入图片描述
在 SpringBootController 中定义属性,并使用@Value 注解或者自定义配置值,并对其方法进行测试

在这里插入图片描述重新运行 Application,在浏览器中进行测试

在这里插入图片描述

3.2、@ConfigurationProperties

Spring注解@Component、@Repository、@Service、@Controller区别

Spring注解@Component、@Repository、@Service、@Controller区别

@component

@component

@component

@ConfigurationProperties

@ConfigurationProperties

@Autowired用法

@Autowired用法

项目名称:008-springboot-custom-configuration
将整个文件映射成一个对象,用于自定义配置项比较多的情况
案例演示
➢ 在 com.abc.springboot.config 包下创建 ConfigInfo 类,并为该类加上 Component 和
ConfigurationProperties 注解,并在 ConfigurationProperties 注解中添加属性 prefix,
作用可以区分同名配置

package com.bjpowernode.springboot.model;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component  //将此类加载到spring容器中
@ConfigurationProperties(prefix = "school")
public class School {

    private String name;

    private String website;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getWebsite() {
        return website;
    }

    public void setWebsite(String website) {
        this.website = website;
    }
}

application.properties 配置文件
在这里插入图片描述
在 SpringBootController 中利用@Autowired注入school 配置类

package com.bjpowernode.springboot.web;

import com.bjpowernode.springboot.model.City;
import com.bjpowernode.springboot.model.School;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class IndexController {

    @Autowired
    private School school;

    @Autowired
    private City city;

    @RequestMapping(value = "/school")
    public @ResponseBody Object school(){

        return "school.name="+school.getName()+",school.website="+school.getWebsite();
    }

    @RequestMapping(value = "/city")
    public @ResponseBody Object city(){

        return "city.name="+city.getName()+",city.website="+city.getWebsite();
    }
}

4、 Spring Boot 前端使用 JSP

4.1、在 pom.xml 文件中配置以下依赖项

<!--引入 Spring Boot 内嵌的 Tomcat 对 JSP 的解析包,不加解析不了 jsp 页面-->
<!--如果只是使用 JSP 页面,可以只添加该依赖-->
<dependency>
 <groupId>org.apache.tomcat.embed</groupId>
 <artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!--如果要使用 servlet 必须添加该以下两个依赖-->
<!-- servlet 依赖的 jar 包-->
<dependency>
 <groupId>javax.servlet</groupId>
 <artifactId>javax.servlet-api</artifactId>
</dependency>
<dependency>
 <groupId>javax.servlet.jsp</groupId>
 <artifactId>javax.servlet.jsp-api</artifactId>
 <version>2.3.1</version>
</dependency>
<!--如果使用 JSTL 必须添加该依赖-->
<!--jstl 标签依赖的 jar 包 start-->
<dependency>
 <groupId>javax.servlet</groupId>
 <artifactId>jstl</artifactId>
</dependency>

4.2、 在 pom.xml 的 build 标签中要配置以下信息

SpringBoot 要求 jsp 文件必须编译到指定的 META-INF/resources 目录下才能访问,否则
访问不到。其实官方已经更建议使用模板技术(后面会讲模板技术)

        <!--
            SpringBoot框架集成jsp,指定jsp文件编译的路径META-INF/resources
        -->
        <resources>
            <resource>
                <!--指定源文件路径-->
                <directory>src/main/webapp</directory>
                <!--指定编译的路径-->
                <targetPath>META-INF/resources</targetPath>
                <includes>
                <!--指定要把哪些文件编译进去,**表示 webapp 目录及子目录,*.*表示所有文件-->
                    <include>*.*</include>
                </includes>
            </resource>
        </resources>

4.3、在 application.properties 文件配置 Spring MVC 的视图展示为 jsp,这里相当于 Spring MVC 的配置

#SpringBoot 核心配置文件
#指定内嵌 Tomcat 端口号
server.port=8090
#配置 SpringMVC 视图解析器
#其中:/ 表示目录为 src/main/webapp
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp

如果使用application.yml 格式的配置文件,其配置文件应该为如下配置

#SpringBoot 核心配置文件
#指定内嵌 Tomcat 端口号
server:
 port: 8090
 servlet:
 context-path: /
#配置 SpringMVC 视图解析器
#其中:/ 表示目录为 src/main/webapp
spring:
 mvc:
 view:
 prefix: /
 suffix: .jsp

集成完毕之后,剩下的步骤和我们使用 Spring MVC 一样

4.4、 在 com.abc.springboot.controller 包下创建 JspController 类,并 编写代码

@Controller
public class SpringBootController {
 @RequestMapping(value = "/springBoot/jsp")
 public String jsp(Model model) {
 model.addAttribute("data","SpringBoot 前端使用 JSP 页面!");
 return "index";
 }
}

4.5、在 src/main 下创建一个 webapp 目录,然后在该目录下新建 index.jsp 页面

在这里插入图片描述

如果在webapp目录下右键,没有创建jsp的选项,可以在Project Structure中指定webapp
为 Web Resource Directory
在这里插入图片描述

4.6、在 jsp 中获取 Controller 传递过来的数据

在这里插入图片描述index.jsp在如下位置
在这里插入图片描述

4.7、重新运行 Application,通过浏览器访问测试

在这里插入图片描述

5、SpringBoot 工程下使用 Mybatis 反向工程

项目名称:010-springboot-web-mybatis

通过 SpringBoot +MyBatis 实现对数据库学生表的查询操作
数据库参考:springboot.sql 脚本文件
文件如下:


drop table if exists t_student;
create table t_student 
(
   id                   int(10)                        not null auto_increment,
   name                 varchar(20)                    null,
   age                  int(10)                        null,
   constraint PK_T_STUDENT primary key clustered (id)
);

insert into t_student(name,age) values("zhangsan",25);
insert into t_student(name,age) values("lisi",28);
insert into t_student(name,age) values("wangwu",23);
insert into t_student(name,age) values("Tom",21);
insert into t_student(name,age) values("Jck",55);
insert into t_student(name,age) values("Lucy",27);
insert into t_student(name,age) values("zhaoliu",75);

5.1、SpringBoot 工程下使用 Mybatis 反向工程

拷贝 Mybatis 反向工程配置文件到项目的根目录下
新建目录:GeneratorMapper.xml
在这里插入图片描述

5.2、根据项目及表的情况,修改 GeneratorMapper.xml 配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>

    <!-- 指定连接数据库的 JDBC 驱动包所在位置,指定到你本机的完整路径 -->
    <classPathEntry location="D:\course\dev\repository\mysql\mysql-connector-java\8.0.21\mysql-connector-java-8.0.21.jar"/>

    <!-- 配置 table 表信息内容体,targetRuntime 指定采用 MyBatis3 的版本 -->
    <context id="tables" targetRuntime="MyBatis3">
        <!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>


        <!-- 配置数据库连接信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/springboot?serverTimezone=Asia/Shanghai"
                        userId="root"
                        password="990325">
        </jdbcConnection>
        <!-- 生成 model 类,targetPackage 指定 model 类的包名, targetProject 指定
        生成的 model 放在 eclipse 的哪个工程下面-->
        <javaModelGenerator targetPackage="com.bjpowernode.springboot.model"
                            targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
            <property name="trimStrings" value="false"/>
        </javaModelGenerator>

        <!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的
        包名, targetProject 指定生成的 mapper.xml 放在 eclipse 的哪个工程下面 -->
        <sqlMapGenerator targetPackage="com.bjpowernode.springboot.mapper"
                         targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- 生成 MyBatis 的 Mapper 接口类文件,targetPackage 指定 Mapper 接口类的包
        名, targetProject 指定生成的 Mapper 接口放在 eclipse 的哪个工程下面 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.bjpowernode.springboot.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>

        <!-- 数据库表名及对应的 Java 模型类名 -->
        <table tableName="t_student" domainObjectName="Student"
               enableCountByExample="false"
               enableUpdateByExample="false"
               enableDeleteByExample="false"
               enableSelectByExample="false"
               selectByExampleQueryId="false"/>
    </context>
</generatorConfiguration>

5.3、在 pom.xml 文件中添加 mysql 反向工程依赖

<!--mybatis 代码自动生成插件-->
<plugin>
 <groupId>org.mybatis.generator</groupId>
 <artifactId>mybatis-generator-maven-plugin</artifactId>
 <version>1.3.6</version>
 <configuration>
 <!--配置文件的位置-->
 <configurationFile>GeneratorMapper.xml</configurationFile>
 <verbose>true</verbose>
 <overwrite>true</overwrite>
 </configuration>
</plugin>

5.4、双击红色选中命令,生成相关文件

在这里插入图片描述
结果如下:
将会自动产生mapper文件和model文件
在这里插入图片描述

5.5、对生成的StudentMapper.xml进行分析

<?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.bjpowernode.springboot.mapper.StudentMapper">
  <resultMap id="BaseResultMap" type="com.bjpowernode.springboot.model.Student">
  <!--    id标签只能修改主键-->
  <!--result除了主键以外的字段-->
  <!--    column数据库中的字段名称-->
  <!--    property映射对象的属性名称-->
  <!--    jdbcType列中数据库中字段的类型(可以省略不写)-->
    <!--  resultMap作用:
        1,当数据库中字段名称与实体类对象的属性名不一致时,可以进行转换
        2,当前查询的结果没有对象一个表的时候,可以自定义一个结果集-->
<!--    数据库表字段名称               实体对象属性名称-->
<!--    user name product_type      userName productType-->

<!--    如果数据库中字段名称由多个单词构成,通过MyBatis逆向工程生成的对象属也会按照驼峰命名法规则生成属性名称-->
<!--    其中:数据库中字段名称由多个单词构成的时候必须使用_下划线分隔-->

    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="age" jdbcType="INTEGER" property="age" />
  </resultMap>

<!--  sql语句片段,将公共的部分抽取出来
通过include标签引用sql语句片段
-->

  <sql id="Base_Column_List">
    id, name, age
  </sql>


  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from t_student
    where id = #{id,jdbcType=INTEGER}
  </select>


  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    delete from t_student
    where id = #{id,jdbcType=INTEGER}
  </delete>


  <insert id="insert" parameterType="com.bjpowernode.springboot.model.Student">
    insert into t_student (id, name, age
      )
    values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}
      )
  </insert>

<!--  suffixoverrides去除多余的逗号-->
  <insert id="insertSelective" parameterType="com.bjpowernode.springboot.model.Student">
    insert into t_student
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="name != null">
        name,
      </if>
      <if test="age != null">
        age,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=INTEGER},
      </if>
      <if test="name != null">
        #{name,jdbcType=VARCHAR},
      </if>
      <if test="age != null">
        #{age,jdbcType=INTEGER},
      </if>
    </trim>
  </insert>


  <update id="updateByPrimaryKeySelective" parameterType="com.bjpowernode.springboot.model.Student">
    update t_student
    <set>
      <if test="name != null">
        name = #{name,jdbcType=VARCHAR},
      </if>
      <if test="age != null">
        age = #{age,jdbcType=INTEGER},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>


  <update id="updateByPrimaryKey" parameterType="com.bjpowernode.springboot.model.Student">
    update t_student
    set name = #{name,jdbcType=VARCHAR},
      age = #{age,jdbcType=INTEGER}
    where id = #{id,jdbcType=INTEGER}
  </update>


</mapper>

6、Spring Boot 集成 MyBatis

6.1、创建一个新的 SpringBoot 的 Module

在这里插入图片描述

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

6.2在 pom.xml 中添加相关 jar 依赖

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

<!--        mybatis 集成springboot框架的起步依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>

6.3、在 Springboot 的核心配置文件 application.properties 中配 置数据源

注意根据自己数据库的信息修改以下内容

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=990325

6.4、开发代码 ➢ 使用 Mybatis 反向工程生成接口、映射文件以及实体 bean,具体步骤参见目录5在这里插入图片描述

6.5、 在 web 包下创建 StudentController 并编写代码

package com.bjpowernode.springboot.web;

import com.bjpowernode.springboot.model.Student;
import com.bjpowernode.springboot.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author ljm
 * @Date 2021/8/23 21:44
 * @Version 1.0
 */
@RestController
public class studentcontroller {

    @Autowired
    private StudentService studentService;
    @RequestMapping(value = "say")
    public Student queryById(Integer id){
        //调用业务层的方法
        Student student = studentService.queryById(id);


        return student;
    }
}

6.6、在service 包下创建 service 接口并编写代码

在这里插入图片描述

package com.bjpowernode.springboot.service;

import com.bjpowernode.springboot.model.Student;

/**
 * @Author ljm
 * @Date 2021/8/23 21:48
 * @Version 1.0
 */
public interface StudentService {
    //查询详情
    Student queryById(Integer id);
}

6.7、在 service.impl 包下创建 service 接口并编写代码

package com.bjpowernode.springboot.service.impl;

import com.bjpowernode.springboot.mapper.StudentMapper;
import com.bjpowernode.springboot.model.Student;
import com.bjpowernode.springboot.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Author ljm
 * @Date 2021/8/23 21:49
 * @Version 1.0
 */
@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;
    @Override
    public Student queryById(Integer id) {
        return studentMapper.selectByPrimaryKey(id);
    }
}

spring注解@Service注解的使用

spring注解@Service注解的使用

6.8、在pom.xml文件中指定资源文件夹(这个前题是Studentmapper.xml文件在src/main/java路径下)

默认情况下,Mybatis 的 xml 映射文件不会编译到 target 的 class 目录下,所
以我们需要在 pom.xml 文件中配置 resource

<!--        手动指定资源文件夹-->
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>

6.9、在 Mybatis 反向工程生成的 StudentMapper 接口上加一个 Mapper 注解

package com.bjpowernode.springboot.mapper;

import com.bjpowernode.springboot.model.Student;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface StudentMapper {
    int deleteByPrimaryKey(Integer id);

    int insert(Student record);

    int insertSelective(Student record);

    Student selectByPrimaryKey(Integer id);

    int updateByPrimaryKeySelective(Student record);

    int updateByPrimaryKey(Student record);
}

6.10、DAO 其它开发方式(替换6.9)

在 运 行 的 主 类 上 添 加 注 解 包 扫 描
@MapperScan(“com.abc.springboot.mapper”)
注释掉 StudentMapper 接口上的@Mapper 注解
在这里插入图片描述
在运行主类 Application 上加@MapperScan(“com.abc.springboot.mapper”)
在这里插入图片描述

SpringBoot集成MyBatis,最主要的是两个注解@Mapper,@Mapperscan
@Mapper需要在每一个Mapper接口类上添加,作用扫描dao接口
@Mapperscan是在SpringBoot启动入口类上添加的,它是扫描所有的包

6.11、启动 Application 应用,浏览器访问测试运行

在这里插入图片描述

6.12、将接口和映射文件分开(区别于6.8)

因为 SpringBoot 不能自动编译接口映射的 xml 文件,还需要手动在 pom 文件中指定,
所以有的公司直接将映射文件直接放到 resources 目录下
➢ 在 resources 目录下新建目录 mapper 存放映射文件,将 StudentMapper.xml 文件移
到 resources/mapper 目录下

6.8结构
在这里插入图片描述6.12移动后结构
在这里插入图片描述
在 application.properties 配置文件中指定映射文件的位置,这个配置只有接口和映
射文件不在同一个包的情况下,才需要指定

# 指定 Mybatis 映射文件的路径
mybatis.mapper-locations=classpath:mapper/*.xml

无须再配置 resource

关于Mapper映射文件存放的位置的写法有以下两种:
1,将Mapper接口和Mapper映射文件存放到src/main/java同一目录下,还需要在pom文件中手动指定资源文件夹路径resources
2·将Mapper接口和Mapper映射文件分开存放Mapper接口类存放到src/main/java目录下Mapper映射文件存放到resources(类路径)
在springboot核心配置文件中指定mapper映射文件存放到位置

7、Spring Boot 事务支持

Spring Boot 使用事务非常简单,底层依然采用的是 Spring 本身提供的事务管理
➢ 在入口类中使用注解 @EnableTransactionManagement 开启事务支持
➢ 在访问数据库的 Service 方法上添加注解 @Transactional 即可
通过 SpringBoot +MyBatis 实现对数据库学生表的更新操作,在 service 层的方法中构建
异常,查看事务是否生效
项目名称:012-springboot-web-mybatis-transacation
该项目是在 章节6 的基础上添加新增方法,在新增方法中进行案例的演示

7.1、在 StudentController 中添加更新学生的方法

@RequestMapping(value = "/springboot/modify")
public @ResponseBody Object modifyStudent() {
 int count = 0;
 try {
 Student student = new Student();
 student.setId(1);
 student.setName("Jack");
 student.setAge(33);
 count = studentService.modifyStudentById(student);
 } catch (Exception e) {
 e.printStackTrace();
 return "fail";
 }
 return count;
}

7.2、在 StudentService 接口中添加更新学生方法

/**
* 根据学生标识更新学生信息
* @param student
北京动力节点 www.bjpowernode.com
40
* @return
*/
int modifyStudentById(Student student);

7.3、在 StudentServiceImpl 接口实现类中对更新学生方法进 行实现,并构建一个异常,同时在该方法上加@Transactional 注解

@Override
@Transactional //添加此注解说明该方法添加的事务管理
public int update(Student student) {
 int updateCount = studentMapper.updateByPrimaryKeySelective(student);
 System.out.println("更新结果:" + updateCount);
 //在此构造一个除数为 0 的异常,测试事务是否起作用
 int a = 10/0;
 return updateCount;
}

在Application类上加@EnableTransactionManagement
开启事务支持
@EnableTransactionManagement 可选,但是业务方法上必须添加@Transactional 事务才生效

@SpringBootApplication
@MapperScan(basePackages = "com.abc.springboot.mapper")
@EnableTransactionManagement //开启事务支持(可选项,但@Transactional 必须添加)
public class Application {

7.4、启动 Application,通过浏览器访问进行测试

在这里插入图片描述
在这里插入图片描述

8、Spring Boot 下的 Spring MVC

Spring Boot 下的 Spring MVC 和之前的 Spring MVC 使用是完全一样的,主要有以下注解

8.1、 @Controller

Spring MVC 的注解,处理 http 请求

8.2、 @RestController

Spring 4 后新增注解,是@Controller 注解功能的增强
是 @Controller 与@ResponseBody 的组合注解
如果一个 Controller 类添加了@RestController,那么该 Controller 类下的所有方法都相当
于添加了@ResponseBody 注解
用于返回字符串或 json 数据
案例:
➢ 创建 MyRestController 类,演示@RestController 替代@Controller + @ResponseBody

@RestController
public class MyRestController {
 @Autowired
 private StudentService studentService;
 @RequestMapping("/boot/stu")
 public Object stu(){
 return studentService.getStudentById(1);
 }
}

➢ 启动应用,浏览器访问测试
在这里插入图片描述

8.3、@RequestMapping(常用)

支持 Get 请求,也支持 Post 请求

8.4 、@GetMapping

RequestMapping 和 Get 请求方法的组合
只支持 Get 请求
Get 请求主要用于查询操作

8.5、 @PostMapping

RequestMapping 和 Post 请求方法的组合
只支持 Post 请求
Post 请求主要用户新增数据

8.6 、@PutMapping

RequestMapping 和 Put 请求方法的组合
只支持 Put 请求
Put 通常用于修改数据

8.7、 @DeleteMapping

RequestMapping 和 Delete 请求方法的组合
只支持 Delete 请求
通常用于删除数据

8.8、Http 接口请求工具 Postman 介绍

因为通过浏览器输入地址,默认发送的只能是 get 请求,通过 Postman 工具,可以模拟
发送不同类型的请求,并查询结果,在安装的时候,有些机器可能会需要安装 MicroSort .NET
Framework
在这里插入图片描述

9、Spring Boot 使用拦截器

9.1、创建一个 SpringBoot 框架 Web 项目

在这里插入图片描述
在这里插入图片描述

9.2、 实现一个登录拦截器

package com.bjpowernode.springboot.interceptor;

import com.bjpowernode.springboot.model.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class UserInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //拦截的规则
        //从session中获取用户的信息
        User user = (User) request.getSession().getAttribute("user");

        //判断用户是否为空
        if (null == user){
            response.sendRedirect(request.getContextPath() + "/user/page/login");
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

9.3、 创建一个控制层

package com.bjpowernode.springboot.web;

import com.bjpowernode.springboot.model.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

@RestController
public class IndexController {


    /**
     * 无需用户登录
     * @return
     */
    @RequestMapping(value = "/index")
    public String index(){
        return "INDEX";
    }


    /**
     * 无需用户登录
     * @return
     */
    @RequestMapping(value = "/user/page/login")
    public String loginPage(){
        return "Login Page";
    }

    @RequestMapping(value = "/user/login")
    public String login(HttpServletRequest request){
        User user = new User();
        user.setId(1);
        user.setUsername("lisi");

        request.getSession().setAttribute("user",user);

        return "Logged";
    }

    /**
     * 需要用户是登录状态
     * @return
     */
    @RequestMapping(value = "/user/center")
    public String center(){
        return "User Center";
    }
}

9.4、@Configuration 定义配置类-拦截器

在 项 目 中 创 建 一 个 config 包,创建 一 个 配 置 类 SystemConfig, 并 实 现
WebMvcConfigurer 接口, 覆盖接口中的 addInterceptors 方法,并为该配置类添加
@Configuration 注解,标注此类为一个配置类,让 Spring Boot 扫描到,这里的操作就相当
于 SpringMVC 的注册拦截器 ,@Configuration 就相当于一个 applicationContext-mvc.xml

package com.bjpowernode.springboot.config;

import com.bjpowernode.springboot.interceptor.UserInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration  //只要类上加@Configuration,就说明此类为一个配置类,就相当于一个xml配置文件
public class SystemConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        //定义要拦截的路径
        String[] addPathPatterns = {
                "/user/**"
        };

        //排除不需要拦截的路径
        String[] excludePathPatterns = {
                "/user/page/login",
                "/user/login"
        };

        registry.addInterceptor(new UserInterceptor())
                .addPathPatterns(addPathPatterns)
                .excludePathPatterns(excludePathPatterns);
    }
}

10、 SpringBoot 集成 logback 日志

10.1、使用该功能步骤

项目名称:036-springboot-logback

10.2、创建 SpringBoot 框架 web 项目

在这里插入图片描述

10.3、通过 MyBatis 逆向工程生成 DAO

添加mysql和mybatis集成springboot依赖

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

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

将逆向生成文件放到项目根目录

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>

    <!-- 指定连接数据库的 JDBC 驱动包所在位置,指定到你本机的完整路径 -->
    <classPathEntry location="D:\course\dev\repository\mysql\mysql-connector-java\8.0.21\mysql-connector-java-8.0.21.jar"/>

    <!-- 配置 table 表信息内容体,targetRuntime 指定采用 MyBatis3 的版本 -->
    <context id="tables" targetRuntime="MyBatis3">
        <!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>


        <!-- 配置数据库连接信息 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/springboot?serverTimezone=Asia/Shanghai"
                        userId="root"
                        password="990325">
        </jdbcConnection>
        <!-- 生成 model 类,targetPackage 指定 model 类的包名, targetProject 指定
        生成的 model 放在 eclipse 的哪个工程下面-->
        <javaModelGenerator targetPackage="com.bjpowernode.springboot.model"
                            targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
            <property name="trimStrings" value="false"/>
        </javaModelGenerator>

        <!-- 生成 MyBatis 的 Mapper.xml 文件,targetPackage 指定 mapper.xml 文件的
        包名, targetProject 指定生成的 mapper.xml 放在 eclipse 的哪个工程下面 -->
        <sqlMapGenerator targetPackage="com.bjpowernode.springboot.mapper"
                         targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- 生成 MyBatis 的 Mapper 接口类文件,targetPackage 指定 Mapper 接口类的包
        名, targetProject 指定生成的 Mapper 接口放在 eclipse 的哪个工程下面 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.bjpowernode.springboot.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>

        <!-- 数据库表名及对应的 Java 模型类名 -->
        <table tableName="t_student" domainObjectName="Student"
               enableCountByExample="false"
               enableUpdateByExample="false"
               enableDeleteByExample="false"
               enableSelectByExample="false"
               selectByExampleQueryId="false"/>
    </context>
</generatorConfiguration>

在 pom.xml 文件 -> build -> plugins 中添加插件

<!--mybatis 代码自动生成插件-->
<plugin>
 <groupId>org.mybatis.generator</groupId>
 <artifactId>mybatis-generator-maven-plugin</artifactId>
 <version>1.3.6</version>
 <configuration>
 <!--配置文件的位置-->
 <configurationFile>GeneratorMapper.xml</configurationFile>
 <verbose>true</verbose>
 <overwrite>true</overwrite>
 </configuration>
</plugin>

双击生成
在这里插入图片描述配置application.proprietary

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=990325

10.4、手动指定资源文件夹

在build下面配置
默认情况下,Mybatis 的 xml 映射文件不会编译到 target 的 class 目录下,所
以我们需要在 pom.xml 文件中配置 resource

        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>

10.5 编写 StudentController

@Slf4j

@Slf4j

package com.bjpowernode.springboot.web;

import com.bjpowernode.springboot.service.StudentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Author ljm
 * @Date 2021/8/25 11:58
 * @Version 1.0
 */
@RestController
@Slf4j
public class StudentController {

    @Autowired
    private StudentService studentService;
    @RequestMapping(value = "/count")
    public String studentCount(){
        log.info("我是卷王");
        Integer studentCount = studentService.queryStudentCount();
        return "学生人数是:"+studentCount;
    }
}

10.6 编写 StudentService 接口及实现类

package com.bjpowernode.springboot.service;

/**
 * @Author ljm
 * @Date 2021/8/25 12:01
 * @Version 1.0
 */
public interface StudentService {
    Integer queryStudentCount();

}

package com.bjpowernode.springboot.service.impl;

import com.bjpowernode.springboot.mapper.StudentMapper;
import com.bjpowernode.springboot.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Author ljm
 * @Date 2021/8/25 12:02
 * @Version 1.0
 */
@Service
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentMapper studentMapper;

    @Override
    public Integer queryStudentCount() {
        return studentMapper.selectStudentCount();
    }
}

10.7 数据持久层

StudentMapper.java

    //获取学生总人数
    Integer selectStudentCount();

StudentMapper.xml

  <select id="selectStudentCount" resultType="java.lang.Integer">
    select count(*) from  t_student
  </select>

10.8、日志文件

Spring Boot 官方推荐优先使用带有 -spring 的文件名作为你的日志配置(如使用
logback-spring.xml ,而不是 logback.xml),命名为 logback-spring.xml 的日志配置文件。
默认的命名规则,并且放在 src/main/resources 下如果你即想完全掌控日志配置,但又不想
用 logback.xml 作为 Logback 配置的名字,application.yml 可以通过 logging.config 属性指定自
定义的名字:

logging.config=classpath:logging-config.xml

(1) 我们一般针对 DAO 的包进行 DEBUG 日志设置:

<logger name="com.abc.springboot.mapper" level="DEBUG" />

这样的话,只打印 SQL 语句:
在这里插入图片描述
代码里打印日志
之前我们大多数时候自己在每个类创建日志对象去打印信息,比较麻烦:

private static final Logger logger = LoggerFactory.getLogger(StudentServiceImpl.class);
logger.error("xxx");

现在可以直接在类上通过 @Slf4j 标签去声明式注解日志对象
在 pom.xml 中添加依赖

<!--@Slf4j 自动化日志对象-->
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.18.2</version>
</dependency>

logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为 TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果
设置为 WARN,则低于 WARN 的信息都不会输出 -->
<!-- scan:当此属性设置为 true 时,配置文件如果发生改变,将会被重新加载,默认值为
true -->
<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认
单位是毫秒。当 scan 为 true 时,此属性生效。默认的时间间隔为 1 分钟。 -->
<!-- debug:当此属性设置为 true 时,将打印出 logback 内部日志信息,实时查看 logback
运行状态。默认值为 false。通常不打印 -->
<!--根标签-->
<configuration scan="true" scanPeriod="10 seconds">
    <!--输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志 appender 是为开发使用,只配置最底级别,控制台输出的日志级别是大
        于或等于此级别的日志信息-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>debug</level>
        </filter>
        <encoder>
            <Pattern>%date [%-5p] [%thread] %logger{60} [%file : %line] %msg%n
            </Pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--<File>/home/log/stdout.log</File>-->
        <File>D:/log/stdout.log</File>
        <encoder>
            <pattern>%date [%-5p] %thread %logger{60} [%file : %line] %msg%n</pattern>
        </encoder>
        <rollingPolicy
                class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 添加.gz 历史日志会启用压缩 大大缩小日志文件所占空间 -->
            <!--<fileNamePattern>/home/log/stdout.log.%d{yyyy-MM-dd}.log</fileNam ePattern>-->
            <fileNamePattern>D:/log/stdout.log.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory><!-- 保留 30 天日志 -->
        </rollingPolicy>
    </appender>

    <logger name="com.bjpowernode.springboot.mapper" level="DEBUG"/>

    <root level="INFO">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

10.9 Application 启动类

**@MapperScan(basePackages = “com.bjpowernode.springboot.mapper”)**用于扫描mapper包

package com.bjpowernode.springboot;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(basePackages = "com.bjpowernode.springboot.mapper")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

10.10、启动测试

在这里插入图片描述

11、SpringBoot 集成 Thymeleaf 模板

Thymeleaf 是一个流行的模板引擎,该模板引擎采用 Java 语言开发

SpringBoot 集成了 Thymeleaf 模板技术,并且 Spring Boot 官方也推荐使用 Thymeleaf 来
替代 JSP 技术,Thymeleaf 是另外的一种模板技术,它本身并不属于 Spring Boot,Spring Boot
只是很好地集成这种模板技术,作为前端页面的数据展示,在过去的 Java Web 开发中,我
们往往会选择使用 Jsp 去完成页面的动态渲染,但是 jsp 需要翻译编译运行,效率低

11.1 项目名称:037-springboot-thymeleaf-first

创建 Spring Boot 项目,添加 web 和 Thymeleaf 依赖

new module
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述按照这种方式创建后,pom.xml 文件下会自动添加如下依赖

<!--SpringBoot 集成 Thymeleaf 的起步依赖-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--SpringBoot 开发 web 项目的起步依赖-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
</dependency>

11.2 在 Spring boot 的核心配置文件 application.properties 中对 Thymeleaf 进行配置、

#thymeleaf 页面的缓存开关,默认 true 开启缓存
#建议在开发阶段关闭 thymeleaf 页面缓存,目的实时看到页面
spring.thymeleaf.cache=false

下面的配置可有可无,没有也可以工作,因为基本 Thymeleaf 的配置都有默认值

前缀:
#thymeleaf 模版前缀,默认可以不写
spring.thymeleaf.prefix=classpath:/templates/
后缀:
#thymeleaf 模版后缀,默认可以不写
spring.thymeleaf.suffix=.html

如果仅仅将spring.thymeleaf.cache设置成false
再刷新没有任何效果

需要接下来修改项目的configuration
在这里插入图片描述
所有说关闭缓存需要两步,第一在application.properties中设置spring.thymeleaf.cache设置成false,第二
在启动入口类上把configuration修改为update resources

11.3 创建 ThymeleafControlle 去映射到模板页面(和 SpringMVC 基 本一致)

@Controller
public class ThymeleafController {
 @RequestMapping(value = "/thymeleaf/index")
 public String index(Model model) {
 model.addAttribute("data","SpringBoot 成功集成 Thymeleaf 模版!");
 return "index";
 }
}

11.4 在 src/main/resources 的 templates 下新建一个 index.html 页 面用于展示数据

HTML 页面的元素中加入以下属性:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>SpringBoot 集成 Thymeleaf</title>
</head>
<body >
 <!--Thymeleaf 前端框架以 Html 为载体-->
 <span th:text="${data}"></span>
 <span th:text="${data}"></span>
 <p th:text="${data}"></p>
 <div th:text="${data}"></div>
</body>
</html>

11.5 启动程序,浏览器访问 http://localhost:8080/index在这里插入图片描述

右键->查看页面源代码

注意: Springboot 使 用 thymeleaf 作 为 视 图 展 示 , 约 定 将 模 板 文 件 放 置 在
src/main/resource/templates 目录下,静态资源放置在 src/main/resource/static 目录下
在这里插入图片描述

12 Thymeleaf 的表达式

12.1 项目名称:038-springboot-thymeleaf-expression

(1) 创建 SpringBoot 的 web 项目并使用模版引擎
在这里插入图片描述
在这里插入图片描述
(2)pom.xml 中应该有如下两个依赖

<!--SpringBoot 集成 Thymeleaf 模版引擎的起步依赖-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--SpringBoot 的 web 项目起步依赖-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
</dependency

(3)在 application.properties 中设置 thymeleaf 参数

#设置 thymeleaf 页面缓存失效
spring.thymeleaf.cache=false
#thymeleaf 模版前缀,默认值,可选项
spring.thymeleaf.prefix=classpath:/templates/
#thymeleaf 模版后缀,默认值,可选项
spring.thymeleaf.suffix=.html

(4) 创建实体 User 实体类

创建 User 实体类,为后续演示提供数据

@Data
public class User {
 private Integer id;
 private String name;
 private String phone;
 private String address;
}

(5) 创建 ThymeleafController 类

@Controller
public class ThymeleafController {
 @RequestMapping(value = "/thymeleaf/index")
 public String index(Model model) {
 model.addAttribute("data","SpringBoot 集成 Thymeleaf 模版!");
 return "index";
 }
//另一种写法
    @RequestMapping(value = "/index1")
    public ModelAndView index1(){
        ModelAndView mv = new ModelAndView();
        //添加视图名称
        mv.setViewName("index");
        mv.addObject("data","Spring");
        return mv;


    }


}
 

(6) 在 src/main/resources/templates 在创建 html 页面
文件名字是index.html。这样才能在controller返回出来

xmlns:th="http://www.thymeleaf.org xmlns->命名空间
名空间后面的地址是一约束文件,约束你使用thymeleaf表达式的一个规则文件,就好比我们之前在xml文件中的一此dtd文件

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>Thymeleaf'Index</title>
</head>
<body>
<span th:text="${data}"></span>
</body>
</html>

(7) 测试

在这里插入图片描述发出请求,然后找到了htmil台会直接把html转发给浏器

12.2、 标准变量表达式

注意:th:text="" 是 Thymeleaf 的一个属性,用于文本的显示

(8) 语法 ${…}
(9) 说明

标准变量表达式用于访问容器(tomcat)上下文环境中的变量,功能和 EL 中的 ${} 相
同。Thymeleaf 中的变量表达式使用 ${变量名} 的方式获取 Controller 中 model 其中的数据

(10) 案例演示
创建一个方法,将用户信息存放到 model 中,thymeleaf 模版页面获取对象信息

  1. 在 ThymeleafController 中添加方法,向 model 放入 User 对象
@RequestMapping(value = "/thymeleaf/user")
public String user(Model model) {
 User user = new User();
 user.setId(1);
 user.setName("张三");
 user.setPhone("13700000000");
 user.setAddress("北京市亦庄经济开发区");
 model.addAttribute("user",user);
 return "user";
}
  1. 在 templates 目录下创建 user.html 页面获取 User 对象数据
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>展示用户对象信息</title>
</head>
<body>
<h2>展示 User 用户信息:</h2>
用户编号:<span th:text="${user.id}"></span><br/>
用户姓名:<span th:text="${user.name}"></span><br/>
用户手机号:<span th:text="${user.phone}"></span><br/>
用户地址:<span th:text="${user.address}"></span><br/>
</body>
</html>

  1. 浏览器访问 http://localhost:8080/thymeleaf /user 测试

在这里插入图片描述
选择变量表达式(了解,不推荐使用)
(11) 语法:*{…}
(12) 说明
选择变量表达式,也叫星号变量表达式,使用 th:object 属性来绑定对象
选择表达式首先使用 th:object 来绑定后台传来的 User 对象,然后使用 * 来代表这个对
象,后面 {} 中的值是此对象中的属性。
选择变量表达式 *{…} 是另一种类似于标准变量表达式 . . . 表 示 变 量 的 方 法 选 择 变 量 表 达 式 在 执 行 时 是 在 选 择 的 对 象 上 求 解 , 而 {...} 表示变量的方法 选择变量表达式在执行时是在选择的对象上求解,而 ...{…}是在上下文的变量 Model 上求
解,这种写法比标准变量表达式繁琐,只需要大家了解即可

(13) 案例演示

  1. 在 user.html 通过选择变量表达式(星号表达式)获取用户数据
<h2>展示 User 用户信息(星号表达式,仅在 div 范围内有效):</h2>
<div th:object="${user}">
 用户编号:<span th:text="*{id}"></span><br/>
 用户姓名:<span th:text="*{name}"></span><br/>
 用户手机号:<span th:text="*{phone}"></span><br/>
 用户地址:<span th:text="*{address}"></span><br/>
</div

在这里插入图片描述
标准变量表达式和选择变量表达式混合使用

  1. 标准变量和选择变量表达式可以混合使用,也可以不混合使用,使用 th:object 进行对
    象的选择,也可以直接使用 *{…} 获取数据
    在 user.html 模版中添加如下代码:
<h2>标准变量表达式和选择变量表达式混用</h2>
<h3>=======标准变量表达式=======</h3>
用户编号:<span th:text="${user.id}"></span><br/>
用户姓名:<span th:text="${user.name}"></span><br/>
用户手机号:<span th:text="${user.phone}"></span><br/>
用户地址:<span th:text="${user.address}"></span><br/>
<h3>=======选择变量表达式=======</h3>
用户编号:*{user.id} ==> <span th:text="*{user.id}"></span><br/>
用户姓名:*{user.name} ==> <span th:text="*{user.name}"></span><br/>
用户手机号:*{user.phone} ==> <span th:text="*{user.phone}"></span><br/>
用户地址:*{user.address} ==> <span 
th:text="*{user.address}"></span><br/>

html中的span、div标签

span
div
2) 测试查看结果
在这里插入图片描述

文章目录

12.3、URL 表达式

语法@{…}
(15) 说明
主要用于链接、地址的展示,可用于<script src="...">、<link href="...">、<a href="...">、<form action="...">、<img src="">等,可以
在 URL 路径中动态获取数据

(16) 案例演示

  1. 创建 url.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>URL 路径表达式 -> @{}</title>
</head>
<body>
<h1>URL 路径表达式:@{...}</h1>
<h2>绝对路径(没有参数)</h2>
<a th:href="@{http://localhost:8080/thymeleaf/info}">查看:绝对路径</a>
<h2>绝对路径(路径中有参数)</h2>
<a th:href="@{'http://localhost:8080/thymeleaf/user/info?id=' + 
${user.id}}">查看用户信息:绝对路径(带参数)</a>
<h2 style="color: red">实际开发推荐使用:相对路径(没有参数)</h2>
<a th:href="@{/thymeleaf/info}">查看:相对路径</a>
<h2 style="color: red">实际开发推荐使用:相对路径(路径中有参数)</h2>
<a th:href="@{'/thymeleaf/user/info?id=' + ${user.id}}">查看用户信息:相
对路径(带参数)</a>
<a th:href="@{/thymeleaf/info(id=${user.id})}">推荐使用:优雅的带参数路径
写法</a>
</body>
</html>
  1. 为了演示加上下文的效果,在 application.properties 中配置项目上下文
#设置上下文根
server.servlet.context-path=/url-expression
  1. 在 ThymeleafController 中添加如下方法:
@RequestMapping(value = "/thymeleaf/url")
public String url(Model model) {
 User user = new User();
 user.setId(2);
 user.setName("赵六");
 user.setPhone("13800000000");
 user.setAddress("上海市");
 model.addAttribute("user",user);
 return "url";
}
@RequestMapping(value = "/thymeleaf/info")
public String info(Integer id) {
 System.out.println("用户编号:" + id);
 return "info";

  1. 浏览器访问,右键查看源代码
    在这里插入图片描述
    在这里插入图片描述

12.4 Thymeleaf 的常见属性

大部分属性和 html 的一样,只不过前面加了一个 th 前缀
1 项目名称:041-springboot-thymeleaf-property
(17) 创建 SpringBoot 的 web 项目并使用模版引擎
在这里插入图片描述
在这里插入图片描述
(18) pom.xml 中应该有如下两个依赖

<!--SpringBoot 框架集成 Thymeleaf 模版起步依赖-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--SpringBoot 框架 web 项目起步依赖-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
</dependency>

(19) 在 application.properties 中设置 thymeleaf 参数

设置端口号
server.port=8090

#设置上下文根
server.servlet.context-path=/property
#thymeleaf 缓存默认开启,开发阶段关闭
spring.thymeleaf.cache=false
#设置 thymeleaf 前缀
spring.thymeleaf.prefix=classpath:/templates/
#设置 thymeleaf 后缀
spring.thymeleaf.suffix=.html

(20) 创建实体 User 实体类

@Data
public class User {
 private Integer id;
 
 private String name;
 
 private String phone;
 
 private String address;
}

(21) 创建 ThymeleafController

@Controller
public class ThymeleafController {
 @RequestMapping(value = "/index")
 public String index(Model model) {
 model.addAttribute("data","Hello,SpringBoot 集成 Thymeleaf 模版");
 return "index";
 }

(22) 在 src/main/resources/templates 在创建 Index 页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>Title</title>
</head>
<body>
<h1 th:text="${data}"></h1>
</body>
</html>

(23) 测试
在这里插入图片描述

12.4.1、th:action

th:action 定义后台控制器的路径,类似标签的 action 属性,主要结合 URL 表达式,获
取动态变量
(24) index.html 页面上添加以下内容

<h1>th:action 属性的使用</h1>
<h2>请求路径中需要动态获取变量数据时,必须添加 th 前缀</h2>
<form th:action="@{'/user/login?id='+${user.id}}"></form>
<h2>以下两种方式获取不到用户 id</h2>

<form action="'/user/login?id='+${user.id}"></form>
<form action="/user/login"+${user.id}></form>

(25) ThymeleafController 中 index 方法添加

@RequestMapping(value = "/index")
public String index(Model model) {
 model.addAttribute("data","Hello,SpringBoot 集成 Thymeleaf 模版");
 User user = new User();
 user.setId(10001);
 user.setName("王五");
 user.setPhone("13888880000");
 user.setAddress("天津市");
 model.addAttribute("user",user);
 return "index";
}

(26) 测试

在这里插入图片描述在这里插入图片描述

12.4.2、th:method

设置请求方法

<form id="login" th:action="@{/login}" th:method="post">......</form>
<h1>th:method 属性的使用</h1>
<form th:action="@{/user/login}" th:method="post"></form>

th:href
定义超链接,主要结合 URL 表达式,获取动态变量

<h1>th:href 使用</h1>

<a href="http://www.baidu.com">超链接百度</a><br/>
<a th:href="'http://www.baidu.com?id=' + ${user.id}">th:href 链接</a>

th:src

用于外部资源引入,比如

<h1>th:src 属性的使用</h1>
<!--以下方式无法引入 js-->
<script src="/static/js/jquery-1.7.2.min.js"></script>
<!--该方法是常用方法-->
<script type="text/javascript" 
th:src="@{/jquery-1.7.2.min.js}"></script>
<script>
 $(function () {
 alert("引入 js 文件");
 });
</script>

这种方式比传统方式的好处是,在 URL 表达式前加/,会自动加上上下文根,避免 404 找不
到资源的情况。
th:id
类似 html 标签中的 id 属性

<span th:id="${hello}">aaa</span>

12.4.3、th:name

设置名称

<input th:type="text" th:id="userName" th:name="userName">

th:value
类似 html 标签中的 value 属性,能对某元素的 value 属性进行赋值

<input type="hidden" id="userId" name="userId" th:value="${userId}">

12.4.4、 th:attr

该属性也是用于给 HTML 中某元素的某属性赋值,好处是可以给 html 中没有定义的属性动态的赋值。

<h1>th:attr 属性的使用</h1>
<span zhangsan="${user.name}"></span>
<!--通过 th:attr 对自定义的属性赋值-->
<span th:attr="zhangsan=${user.name}"></span>

在这里插入图片描述

12.4.5、th:text

用于文本的显示,该属性显示的文本在标签体中,如果是文本框,数据会在文本框外显示,
要想显示在文本框内,使用 th:value

<input type="text" id="realName" name="reaName" th:text="${realName}">

12.4.6、th:object

用于数据对象绑定
通常用于选择变量表达式(星号表达式)

12.4.7、th:onclick

<h1>th:onclick 的使用</h1>
<!--目前 thymeleaf 版本要求只能传递数字和布尔值-->
<a th:onclick="'show('+${user.id}+')'">点击:显示学生编号</a>
<script type="text/javascript">
 function show(id) {
 alert("用户编号为:" + id);
 }
</script>

12.4.8、th:style

设置样式

<a th:onclick="'show('+${user.id}+')'" 
th:style="'font-size:40px;color:red;'">点击:显示学生编号</a>

12.4.9、th:each

这个属性非常常用,比如从后台传来一个对象集合那么就可以使用此属性遍历输出,它与JSTL 中的<c: forEach>类似,此属性既可以循环遍历集合,也可以循环遍历数组及 Map

(28) 遍历 List 集合
A、 在 ThymeleafController 中添加 eachList 方法,准备集合数据

@RequestMapping("/each/list")
public String eachList(Model model){
 List<User> userList = new ArrayList<User>();
 for (int i = 0;i < 10;i++){
 User user = new User();
 user.setId(100 + i);
 user.setNick("张" + i);
 user.setPhone("1361234567" + i);
 user.setAddress("北京市大兴区" + i);
 userList.add(user);
 }
 model.addAttribute("userList",userList);

 return "each";
}

B、 创建 eachList.html 对 List 集合进行遍历

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>循环遍历 List 集合</title>
</head>
<body>
<h1>th:each 循环遍历 List 集合</h1>
<div style="color: red">
 1.user:当前对象的变量名<br/>
 2.userStat:当前对象的状态变量名<br/>
 3.${userList}:循环遍历的集合<br/>
 4.变量名自定义
</div>
<div th:each="user,userStat:${userList}">
 <span th:text="${userStat.index}"></span>
 <span th:text="${user.id}"></span>
 <span th:text="${user.name}"></span>
 <span th:text="${user.phone}"></span>
 <span th:text="${user.address}"></span>
</div>
</body>
</html>

代码说明
th:each="user, iterStat : ${userlist}"中的 u s e r L i s t 是 后 台 传 过 来 的 集 合 u s e r 定 义 变 量 , 去 接 收 遍 历 {userList} 是后台传过来的集合 user 定义变量,去接收遍历 userListuser{userList}集合中的一个数据
◼ iterStat
${userList} 循环体的信息
◼ 其中 user 及 iterStat 自己可以随便取名
◼ interStat 是循环体的信息,通过该变量可以获取如下信息
index: 当前迭代对象的 index(从 0 开始计算)
count: 当前迭代对象的个数(从 1 开始计算)这两个用的较多
size: 被迭代对象的大小
current: 当前迭代变量
even/odd: 布尔值,当前循环是否是偶数/奇数(从 0 开始计算)
first: 布尔值,当前循环是否是第一个
last: 布尔值,当前循环是否是最后一个
注意:循环体信息 interStat 也可以不定义,则默认采用迭代变量加上 Stat 后缀,即 userStat

在这里插入图片描述
(29) 遍历 Map 集合
D、 在 ThymeleafController 中添加 eachMap 方法

@RequestMapping(value = "/each/map")
public String eachMap(Model model) {
 Map<Integer,Object> userMaps = new HashMap<Integer, Object>();
 for (int i = 0; i < 10; i++) {
 User user = new User();
 user.setId(i);
 user.setName("李四"+i);
 user.setPhone("1390000000"+i);
 user.setAddress("天津市"+i);
 userMaps.put(i,user);
 }
 model.addAttribute("userMaps",userMaps);
 return "eachMap";
}

E、添加 eachMap.html 页面对 Map 集合进行遍历

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>循环遍历 Map 集合</title>
</head>
<body>
<h1>th:each 循环遍历 Map 集合</h1>
<div th:each="userMap,userMapStat:${userMaps}">
 <span th:text="${userMapStat.count}"></span>
 <span th:text="${userMap.key}"></span>
 <span th:text="${userMap.value}"></span>

 <span th:text="${userMap.value.id}"></span>
 <span th:text="${userMap.value.name}"></span>
 <span th:text="${userMap.value.phone}"></span>
 <span th:text="${userMap.value.address}"></span>
</div>
</body>
</html>

代码说明
th:each=“userMap,userMapStat:${userMaps}” ,用 userMap 变量接收每次遍历的结果,封装
为一个键值对,userMapStat 状态
userMap.key:获取当前键值对中的 key
userMap.value:获取当前键值对中的 value

在这里插入图片描述
(30) 遍历 Array 数组
G、 在 ThymeleafController 中的 eachArray 方法中准备数组数据

@RequestMapping(value = "/each/array")
public String eachArray(Model model) {
 User[] userArray = new User[10];
 for (int i = 0; i < 10; i++) {
 User user = new User();
 user.setId(i);
 user.setName("赵六"+i);
 user.setPhone("1380000000"+i);
 user.setAddress("深圳市"+i);
 userArray[i] = user;
 }
 model.addAttribute("userArray",userArray);
 return "eachArray";

H、 在 eachArray.html 页面对数组进行遍历(和 List 一样)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>循环遍历 Array 数组</title>
</head>
<body>
<div th:each="user,userStat:${userArray}">
 <span th:text="${userStat.count}"></span>
 <span th:text="${user.id}"></span>
 <span th:text="${user.name}"></span>
 <span th:text="${user.phone}"></span>
 <span th:text="${user.address}"></span>
</div>
</body>
</html>

在这里插入图片描述
(31) 比较复杂的循环案例
在这里插入图片描述J、在 ThymeleafController 的 each 方法中构造数据

@RequestMapping(value = "/each/all")
public String eachAll(Model model) {
 //list -> Map -> List -> User
 List<Map<Integer,List<User>>> myList = new ArrayList<Map<Integer, 
List<User>>>();
 for (int i = 0; i < 2; i++) {
 Map<Integer,List<User>> myMap = new HashMap<Integer, 
List<User>>();
 for (int j = 0; j < 2; j++) {
 List<User> myUserList = new ArrayList<User>();
 for (int k = 0; k < 3; k++) {
 User user = new User();
 user.setId(k);
 user.setName("张三"+k);
 user.setPhone("1350000000"+k);
 user.setAddress("广州市"+i);
 myUserList.add(user);
 }
 myMap.put(j,myUserList);
 }
 myList.add(myMap);
 }
 model.addAttribute("myList",myList);
 return "eachAll";
}

K、 在 eachAll.html 页面对复杂集合关系进行遍历

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>循环遍历复杂集合</title>
</head>
<body>
<h1>循环遍历复杂集合:list -> Map -> List -> User</h1>
<div th:each="myListMap:${myList}">
 <div th:each="myListMapObj:${myListMap}">
 Map 集合的 key:<span th:text="${myListMapObj.key}"></span>
 <div th:each="myListMapObjList:${myListMapObj.value}">
 <span th:text="${myListMapObjList.id}"></span>
 <span th:text="${myListMapObjList.name}"></span>
 <span th:text="${myListMapObjList.phone}"></span>
 <span th:text="${myListMapObjList.address}"></span>
 </div>
 </div>
</div>
</body>
</html>

在这里插入图片描述
条件判断

12.4.10、 th:if

12.4.11、 th:unless

@RequestMapping(value = "/condition")
public String condition(HttpServletRequest request,Model model) {
 User user1 = null;
 model.addAttribute("user1",user1);
 User user2 = new User();
 user2.setId(1001);

 user2.setName("小岳岳");
 user2.setPhone("13900000000");
 user2.setAddress("北京市");
 model.addAttribute("user2",user2);
 model.addAttribute("sex",1);
 User user3 = new User();
 user3.setId(1002);
 user3.setName("孙悦");
 user3.setPhone("13200000000");
 user3.setAddress("北京市");
 model.addAttribute("user3",user3);
 request.getSession().setAttribute("user3",user3);
 return "condition";
}

condition.html 页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>条件判断</title>
</head>
<body>
<h1>th:if 用法:如果满足条件显示,否则相反</h1>
<div th:if="${sex eq 1}">
 男:<input type="radio" name="sex" th:value="1"/>
</div>
<div th:if="${sex eq 0}">
 女:<input type="radio" name="sex" th:value="0"/>
</div>
<h1>th:unless 用法:与 th:if 用法相反,即对条件判断条件取反</h1>
<div th:unless="${sex == 1}">
 男:<input type="radio" name="sex" th:value="1"/>
</div>
<div th:unless="${sex eq 0}">
 女:<input type="radio" name="sex" th:value="0"/>
</div>
<div th:if="${user1 eq null}">
 <h3 style="color: red">用户未登录</h3>
</div>
<div th:unless="${user2 == null}">
 用户姓名:<span th:text="${user2.name}"></span>
</div>
<h1>从 session 中获取值</h1>
<div th:if="${user3 != null}">
 <span th:text="${user3.name}"></span>
</div>
</body>
</html>

12.4.12、th:switch/th:case

switch,case 判断语句

<h1>th:switch/th:case 用法</h1>
<div th:switch="${sex}">
 <span th:case="1">性别:男</span><br/>
 <span th:case="2">性别:女</span><br/>
 <span th:case="*">性别:保密</span>
</div>

一旦某个 case 判断值为 true,剩余的 case 默认不执行,“*”表示默
认的 case,前面的 case 都不匹配时候,执行默认的 case

在这里插入图片描述

12.4.13、th:inline

th:inline 有三个取值类型 (text, javascript 和 none),值为 none 什么都不做,没有效果
(1) 内敛文本(th:inline=”text”)
内敛文本表达式不依赖于 html 标签,直接使用**内敛表达式[[表达式]]**即可获取动态数据,但
必须要求在父级标签上加 th:inline = “text”属性
A、 在 ThymeleafController 类中添加方法

@RequestMapping(value = "/inline")
public String inlineText(Model model) {
 User user = new User();
 user.setId(1003);
 user.setName("杰克");
 user.setPhone("13899990000");
 user.setAddress("天津市");
 model.addAttribute("user",user);
 return "inline ";
}

B、 创建 inline.html 页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>内敛文本</title>
</head>
<body>
<h1>标准变量表达式(展示数据)</h1>
用户编号:<span th:text="${user.id}"></span><br/>

用户姓名:<span th:text="${user.name}"></span><br/>
用户手机号:<span th:text="${user.phone}"></span><br/>
用户地址:<span th:text="${user.address}"></span><br/>
<h1>内敛文本 th:inline="text"</h1>
<div th:inline="text">
 用户编号:<div>[[${user.id}]]</div><br/>
 用户姓名:[[${user.name}]]<br/>
 用户手机号:[[${user.phone}]]<br/>
 用户地址:[[${user.address}]]<br/>
</div>
</body>
</html>

在这里插入图片描述
注意:一般我们将 th:inline="text"放到标签中
(2) 内敛脚本(th:inline=”javascript”)
th:inline=”javascript”在 js 代码中获取后台的动态数据
D、 在 inline.html 页面上,添加如下代码

<script type="text/javascript" th:inline="javascript">
 function showInlineJavaScript() {
 alert("欢迎 " + [[${user.name}]] + " 到我院指导工作!联系方式: " + 
[[${user.phone}]]);
 }
</script>
<button th:onclick="showInlineJavaScript()">展示内容</button>

在这里插入图片描述

12.5 Thymeleaf 字面量

字面量:对应数据类型的合法取值,可以在 html 页面直接使用,不需要后台传递

  1. 在 ThymeleafController 类中添加方法并准备数据
@RequestMapping(value = "/literal")
public String literal(Model model) {

 model.addAttribute("success",true);
 model.addAttribute("flag",false);
 User user = new User();
 user.setId(1004);
 user.setName("贾玲");
 user.setPhone("13777777777");
 user.setAddress("北京市");
 model.addAttribute("user",user);
 return "literal";
}
  1. 创建 literal.html 页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>Thymeleaf 字面量</title>
</head>
<body>
</body>
</html>

12.5.1 文本字面量

用单引号’…'包围的字符串为文本字面量

<h1>文本字面量:用单引号'...'包围的字符串</h1>
<a th:href="@{'/user/info?id=' + ${user.id}}">查看用户:文本字面的路径使用</a><br/>
<span th:text="您好"></span>

12.5.2 数字字面量

<h1>数字字面量</h1>
今年是<span th:text="2019">1949</span><br/>
20 年后,将是<span th:text="2019 + 20">1969</span><br/>

12.5.3 boolean 字面量

<h1>boolean 字面量</h1>
<div th:if="${success}">执行成功</div>
<div th:unless="${flag}">执行不成功</div>

12.5.4 null 字面量

<h1>null 字面量</h1>
<span th:if="${user ne null}">用户不为空</span><br/>
<span th:unless="${user eq null}">用户不为空(使用 th:unless 取反)</span><br/>

12.5.5 Thymeleaf 字符串拼接

<h1>文本字面量使用"+"拼接字符串</h1>
<span th:text="'共'+${totalRows}+'条'+${totalPage}+'页,当前第'+${currentPage}+'
页'"></span>
<h1>另一种更优雅的方式:使用"|要拼接的内容|"减少字符串拼接的加号</h1>
<span th:text="|共${totalRows}条${totalPage}页,当前第${currentPage}页|"></span>

12.6 Thymeleaf 运算符

三元运算:表达式?”正确结果”:”错误结果”
算术运算:+ , - , * , / , %
关系比较::> , < , >= , <= ( gt , lt , ge , le )
相等判断:== , != ( eq , ne )

@RequestMapping(value = "/operator")
public String operator(Model model) {
 model.addAttribute("sex",1);
 return "operator";
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>运算符</title>
</head>
<body>
<h1>三元运算符</h1>
<span th:text="${sex eq 1 ? '':''}"></span><br/>
<span th:text="${sex == 1 ? '':''}"></span><br/>
20*8=<span th:text="20 * 8"></span><br/>
20/8=<span th:text="20 / 8"></span><br/>
20+8=<span th:text="20 + 8"></span><br/>
20-8=<span th:text="20 - 8"></span><br/>
<div th:if="5 > 2">5>2 是真的</div>
<div th:if="5 gt 2">5 gt 2 是真的</div>
</body>
</html>

在这里插入图片描述

12.7 Thymaleaf 表达式基本对象

模板引擎提供了一组内置的对象,这些内置的对象可以直接在模板中使用,这些对象由
#号开始引用,我们比较常用的内置对象

12.7.1 创建 SpringBoot 项目并集成 thymeleaf 框架

在这里插入图片描述在这里插入图片描述

12.8.2 #request
#request 相 当 于 httpServletRequest 对 象 , 这 是 3.x 版 本 , 若 是 2.x 版 本 使 用
#httpServletRequest,在页面获取应用的上下文根,一般在 js 中请求路径中加上可以避免 404

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
 <meta charset="UTF-8">
 <title>Thymeleaf 表达式基本对象</title>
</head>
<body>
<script type="text/javascript" th:inline="javascript">
 var basePath = [[${#httpServletRequest.getScheme() + "://" + 
#httpServletRequest.getServerName() + ":" + 
#httpServletRequest.getServerPort() + 
#httpServletRequest.getContextPath()}]];
 //http://localhost:8080/springboot/user/login

 //获取协议名称
 var scheme = [[${#request.getScheme()}]];
 //获取服务 IP 地址
 var serverName = [[${#request.getServerName()}]];
 //获取服务端口号
 var serverPort = [[${#request.getServerPort()}]];
 //获取上下文根
 var contextPath = [[${#request.getContextPath()}]];
 var allPath = scheme+"://"+serverName+":"+serverPort+contextPath;
 alert(allPath);
</script>
</body>
</html>

12.8.3 #session
相当于 HttpSession 对象,这是 3.x 版本,若是 2.x 版本使用#httpSession
在后台方法中向 session 中放数据

@RequestMapping(value = "/index")
public String index(HttpServletRequest request) {
 request.getSession().setAttribute("username","zhangsan");
 return "index";
}

从页面获取数据

<h1>从 SESSION 中获取用户名称</h1>
<span th:text="${#session.getAttribute('username')}"></span><br/>
<span th:text="${#httpSession.getAttribute('username')}"></span>

13、综合案例

通过上面内容的学习,我们完成一个综合案例:
采用 SpringBoot + Dubbo + MyBatis + Redis + Thymeleaf 实现对数据库的增删改查、缓存操作。
主要目的是练习 Springboot 如何集成各类技术进行项目开发
多模块管理

13.0、Dubbo与SpringBoot的集成以及创建多模块项目时遇到的坑

Dubbo与SpringBoot的集成以及创建多模块项目时遇到的坑

13.1、父工程创建

在这里插入图片描述
在这里插入图片描述父工程遵循两点要求
1、packing标签值设置为pom
在这里插入图片描述2、去掉src
在这里插入图片描述
加入以下代码使其变成springboot工程
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.4</version> <relativePath/> <!-- lookup parent from repository --> </parent>
创建接口工程
在这里插入图片描述
创建提供者
在这里插入图片描述直接是springbweb工程就好了

创建消费者
在这里插入图片描述
在消费者和提供者这里的pom文件这里
把parent换为

<parent>
    <artifactId>050-springboot-parent</artifactId>
    <groupId>com.bjpowernode.springboot</groupId>
    <version>1.0.0</version>
</parent>

删除子工程的groupId和version
在这里插入图片描述
在springboot-dubbo-ssm-provider添加依赖

<!--        springboot框架的web项目起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

<!--        Dubbo集成springboot-->
        <dependency>
            <groupId>com.alibaba.spring.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>

<!--        zookeeper注册中心-->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.10</version>
        </dependency>

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

<!--        mybatis集成springtboot框架起步依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>

        <!--springboot集成Redis起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!--接口工程-->
        <dependency>
            <groupId>com.bjpowernode.springboot</groupId>
            <artifactId>051-springboot-dubbossm-interface</artifactId>
            <version>1.0.0</version>
        </dependency>





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

在050-springboot-parent中管理版本号

    <properties>
        <java.version>1.8</java.version>
        <dubbo-spring-boot-starter-version>2.0.0</dubbo-spring-boot-starter-version>
        <zkclient-version>0.10</zkclient-version>
        <mybatis-spring-boot-starter-version>2.0.0</mybatis-spring-boot-starter-version>
    </properties>


    <packaging>pom</packaging>
<!--    管理springboot父工程没有管理的这些依赖-->
    <dependencyManagement>
        <dependencies>

            <!--        Dubbo集成springboot-->
            <dependency>
                <groupId>com.alibaba.spring.boot</groupId>
                <artifactId>dubbo-spring-boot-starter</artifactId>
                <version>${dubbo-spring-boot-starter-version}</version>
            </dependency>

            <!--        zookeeper注册中心-->
            <dependency>
                <groupId>com.101tec</groupId>
                <artifactId>zkclient</artifactId>
                <version>${zkclient-version}</version>
            </dependency>

            <!--        mybatis集成springtboot框架起步依赖-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis-spring-boot-starter-version}</version>
            </dependency>


        </dependencies>

    </dependencyManagement>

接口工程不需要被父工程管理,否则会出现冲突

        <!--接口工程-->
        <dependency>
            <groupId>com.bjpowernode.springboot</groupId>
            <artifactId>051-springboot-dubbossm-interface</artifactId>
            <version>1.0.0</version>
        </dependency>

在被父工程管理后我们发现我们只需要删除子工程也就是052-springboot-dubbo-ssm-provider里面对应的版本号就好了
如删除 mybatis集成springtboot框架起步依赖的版本号

<!--        mybatis集成springtboot框架起步依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>

        </dependency>

更新消费者所需要的依赖

<!--    dubbo,zookeeper,thymeleaf,接口工程-->
    <dependencies>
<!--        springboot框架集成thymeleaf前端模版引擎起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
<!--        springboot框架web起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--dubbo集成springboot起步依赖-->
        <dependency>
            <groupId>com.alibaba.spring.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
        </dependency>

<!--        zookeeper注册中心-->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
        </dependency>

        <!--接口工程-->
        <dependency>
            <groupId>com.bjpowernode.springboot</groupId>
            <artifactId>051-springboot-dubbossm-interface</artifactId>
            <version>1.0.0</version>
        </dependency>


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

在provider中添加
添加逆向工程
添加逆向工程的插件

<!--mybatis 代码自动生成插件-->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <!--配置文件的位置-->
                    <configurationFile>GeneratorMapper.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>

开启mysql服务

13.2、各层的情况

13.2.3、parent文件

在这里插入图片描述

13.2.4、consumer文件

consumer项目情况,
建立controller.java,配置了studentcount.html和studentDetail.html文件
studentController.java

对@Reference 、@Resource和@Autowired的简单理解

对@Reference 、@Resource和@Autowired的简单理解

package com.bjpowernode.springboot.web;

import com.alibaba.dubbo.config.annotation.Reference;
import com.bjpowernode.springboot.model.Student;
import com.bjpowernode.springboot.service.StudentService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class StudentController {

    @Reference(interfaceClass = StudentService.class,version = "1.0.0",check = false)
    private StudentService studentService;

    @GetMapping(value = "/student/detail/{id}")
    public String studentDetail(Model model,
                                @PathVariable("id") Integer id){

        Student student = studentService.queryStudentById(id);
        model.addAttribute("student",student);
        return "studentDetail";
    }

    @GetMapping(value = "/student/count")
    public String studentCount(Model model){

        Integer allStudentCount = studentService.queryAllStudentCount();
        model.addAttribute("allStudentCount",allStudentCount);


        return "studentCount";
    }
}

在这里插入图片描述他的application.properties

spring.thymeleaf.cache=false

#配置dubbo
spring.application.name=051-springboot-all-consumer
spring.dubbo.registry=zookeeper://192.168.80.129:2181


创建的studentDetail.html文件

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>学生详情</title>
</head>
<body>
学生编号:<span th:text="${student.id}"></span><br/>
学生姓名:<span th:text="${student.stuName}"></span><br/>
学生年龄:<span th:text="${student.stuAge}"></span><br/>
</body>
</html>

他的application.java工程

package com.bjpowernode.springboot;

import com.alibaba.dubbo.spring.boot.annotation.EnableDubboConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@EnableDubboConfiguration   //开启dubbo配置
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

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>
        <artifactId>048-springboot-all-parent</artifactId>
        <groupId>com.bjpowernode.springboot</groupId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../048-springboot-all-parent/pom.xml</relativePath>
    </parent>

    <artifactId>051-springboot-all-consumer</artifactId>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--SpringBoot框架集成Thymeleaf起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!--SpringBoot框架web项目起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--Dubbo整合springboot框架起步依赖-->
        <dependency>
            <groupId>com.alibaba.spring.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>

        <!--zookeeper注册中心-->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.10</version>
        </dependency>

        <!--接口工程-->
        <dependency>
            <groupId>com.bjpowernode.springboot</groupId>
            <artifactId>049-springboot-all-interface</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

13.2.3、interface

三个文件如下
在这里插入图片描述在这里插入图片描述在这里插入图片描述

13.2.4、provider

提供者里面有GeneratorMapper.xml
这里面根据生成的studentMapper.xml有两种方法
这里是把生成文件放到resource下的mapper文件下,然后在application.proprieties指定就可以了
另一种是还是和studentMapper.java是一个文件夹,但是文件识别不到
需要在pom.xml中进行配置

application.proprieties
在这里插入图片描述实现类
StudentImpl.java

`package com.bjpowernode.springboot.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.bjpowernode.springboot.mapper.StudentMapper;
import com.bjpowernode.springboot.model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
@Service(interfaceClass = StudentService.class,version = "1.0.0",timeout = 35000)
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;

    @Override
    public Student queryStudentById(Integer id) {
        return studentMapper.selectByPrimaryKey(id);
    }

    @Override
    public Integer queryAllStudentCount() {

        //首先去redis缓存中获取值
        Integer allStudentCount = (Integer) redisTemplate.opsForValue().get("allStudentCount");

        //判断是否有值
        if (null == allStudentCount){

            //设置同步代码块
            synchronized (this){

                //再次从redis缓存中获取
                allStudentCount = (Integer) redisTemplate.opsForValue().get("allStudentCount");

                //再次判断是否为空
                if (null == allStudentCount){

                    //去数据库查询
                    allStudentCount = studentMapper.selectAllStudentCount();

                    //并存放到redis缓存中
                    redisTemplate.opsForValue().set("allStudentCount",allStudentCount,15, TimeUnit.SECONDS);
                }

            }

        }

        return allStudentCount;
    }
}
`

如果在StudentMapper中新增了方法,studentMapper.xml中也应该增加相应的方法
在这里插入图片描述
在这里插入图片描述

application.java
在这里插入图片描述
在这里插入图片描述

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>
        <artifactId>048-springboot-all-parent</artifactId>
        <groupId>com.bjpowernode.springboot</groupId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../048-springboot-all-parent/pom.xml</relativePath>
    </parent>

    <artifactId>050-springboot-all-provider</artifactId>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <!--SpringBoot框架web项目起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

        <!--MyBatis整合springboot框架起步依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.1</version>
        </dependency>

        <!--SpringBoot框架集成redis起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <!--Dubbo整合springboot框架起步依赖-->
        <dependency>
            <groupId>com.alibaba.spring.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>

        <!--zookeeper注册中心-->
        <dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.10</version>
        </dependency>

        <!--接口工程-->
        <dependency>
            <groupId>com.bjpowernode.springboot</groupId>
            <artifactId>049-springboot-all-interface</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <!--mybatis 代码自动生成插件-->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.6</version>
                <configuration>
                    <!--配置文件的位置-->
                    <configurationFile>GeneratorMapper.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

可以对运行的application重命名
在这里插入图片描述
在这里插入图片描述需要把一些包发布要不找不到
在这里插入图片描述

13.3DAO层,Service层,Controller层、View层

DAO层,Service层,Controller层、View层

  • 39
    点赞
  • 162
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值