SpringBoot整合Thymeleaf基于SpringBoot2.X版本

一、现在不都前后端分离了?为什么要用Thymeleaf模板引擎?

为什么开始用Thymeleaf模板引擎?不是使用jsp呢? 首先前端交给我们的页面,是html页面,如果是我们之前开发,我们需要把他们转成jsp页面,jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据的显示,及交互等。jsp支持非常强大的功能,包括能写Java代码。

但是呢,SpringBoot项目是以jar的方式,不是war方式,而且SpringBoot用的还是嵌入式的Tomcat,所以呢,他现在默认是不支持jsp的。

那不支持jsp,如果我们直接用纯静态页面的方式,那给我们开发会带来非常大的麻烦,那怎么办呢,SpringBoot推荐使用模板引擎。模板引擎有很多种,比如ThymeleafVelocityFreeMarker,不过思想都是一致的,springboot推荐使用Thymeleaf,当然基本上程序员用的都是Thymeleaf模板引擎,在业界Thymeleaf模板引擎是业界的一致好评。

现在不都前后端分离了么?Vue这么流行为什么还需要学习thymeleaf? 虽然现在慢慢在流行前后端分离开发,但是还是有一些的公司依旧在做前后端不分离的开发,而在前后端不分的开发中,我们就会需要后端页面模板引擎(即使前后端分离,也会在一些场景下需要使用页面模板,举个典型的栗子:邮件发送模板)。

二、SpringBoot整合Thymeleaf环境搭建

2.1.创建springboot项目

设置项目名称和包名

选择spring web项目,同时注意springboot的版本

2.2.在pom.xml中导入依赖

注意其中最为主要的就是 thymeleaf 模板,由于后续需要进行数据库连接操作,相关依赖也就一并导入导入了

 <!-- 引入thymeleaf模板引擎依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>2.7.5</version>
        </dependency>

        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <!--MySQL数据库连接的依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>

        <!--lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <scope>provided</scope>
        </dependency>

        <!-- pagehelper分页依赖 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.12</version>
        </dependency>

        <!--添加druid连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

2.3.在resources目录下创建配置文件

2.3.1.新增 application.yml 文件,内容如下:

关于Thymeleaf 默认配置了前缀和后缀(已经不需要我们特殊设置了),源码如下图:

 配置文件内容如下:

spring:
  datasource:
    # 使用阿里的Druid连接池
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 填写你数据库的url、登录名、密码和数据库名
    url: jdbc:mysql://127.0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: test
    password: 123456
  druid:
    # 连接池的配置信息
    # 初始化大小,最小,最大
    initial-size: 5
    min-idle: 5
    maxActive: 20
    # 配置获取连接等待超时的时间
    maxWait: 60000
    # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    timeBetweenEvictionRunsMillis: 60000
    # 配置一个连接在池中最小生存的时间,单位是毫秒
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    # 打开PSCache,并且指定每个连接上PSCache的大小
    poolPreparedStatements: true
    maxPoolPreparedStatementPerConnectionSize: 20
    # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,slf4j
    # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
    # 配置DruidStatFilter
    web-stat-filter:
      enabled: true
      url-pattern: "/*"
      exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"
    # 配置DruidStatViewServlet
    stat-view-servlet:
      url-pattern: "/druid/*"
      # IP白名单(没有配置或者为空,则允许所有访问)
      allow: 127.0.0.1,192.168.8.109
      # IP黑名单 (存在共同时,deny优先于allow)
      deny: 192.168.1.188
      #  禁用HTML页面上的“Reset All”功能
      reset-enable: false
      # 登录名
      login-username: admin
      # 登录密码
      login-password: 123456

#thymeleaf会自动设置前缀和后缀,这里就不需要手动添加了
#  thymeleaf:
#    suffix:
#    prefix:

mybatis:
  mapper-locations: classpath:mybatis/*.xml
  type-aliases-package: com.augus.pojo
server:
  servlet:
    context-path: /springboot08
  port: 8080

2.3.2创建 logback.xml 引入日志文件,方便调试

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
    <property name="LOG_HOME" value="${catalina.base}/logs/" />
    <!-- 控制台输出 -->
    <appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 日志输出格式 -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            </pattern>
        </layout>
    </appender>
    <!-- 按照每天生成日志文件 -->
    <appender name="RollingFile"  class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_HOME}/server.%d{yyyy-MM-dd}.log</FileNamePattern>
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            </pattern>
        </layout>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>
    <!-- 日志输出级别 -->
    <root level="debug">
        <appender-ref ref="Stdout" />
        <appender-ref ref="RollingFile" />
    </root>
    <logger name="com.augus.mapper" level="DEBUG"></logger>
    <!--日志异步到数据库 -->
    <!--<appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
            日志异步到数据库
            <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
               连接池
               <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
                  <driverClass>com.mysql.jdbc.Driver</driverClass>
                  <url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
                  <user>root</user>
                  <password>root</password>
                </dataSource>
            </connectionSource>
      </appender> -->
</configuration>

2.4.在resources下的templates中创建html文件

常见名为:show.html

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

注意:

  需要在html开始标签中引入命名空间:xmlns:th="http://www.thymeleaf.org"

2.5.在com.augus包中创建controller

在下面创建控制器:ShowController内容如下:

package com.augus.controller;

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

import java.util.Map;

@Controller
public class ShowController {
    @RequestMapping("/show")
    public String freeMarkerShow(Map<String, Object> map){
        //向前端传递数据
        map.put("name", "梦特娇");
        //返回模块文件名称
        return "show";
    }
}

2.6.测试

启动项目:浏览器访问 http://localhost:8080/springboot08/show,如下图所示表示环境搭建成功

三、标准变量表达式

Thymeleaf通过标准变量表达式完成数据的展示和处理

  • 标准变量表达式必须依赖标签,不能独立使用
  • 标准变量表达式一般在开始标签中,以 th开头
  • 语法为: <tag th:***="${key}" ></tag>
  • 表达式中可以通过${}取出域中的值并放入标签的指定位置
  • ${}在这里不能单独使用,必须在 th:后面的双引号里使用

要使用thymeleaf, 就需要进入命名空间,修改html页面中<html>标签为:

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

3.1. th:text属性

th:text可以实现向HTML标签内部输出信息的效果,例如之前项目搭建时候的案例。

controller中ShowController 代码如下

package com.augus.controller;

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

import java.util.Map;

@Controller
public class ShowController {
    @RequestMapping("/show")
    public String freeMarkerShow(Map<String, Object> map){
        //向前端传递数据
        map.put("name", "梦特娇");
        //返回模块文件名称
        return "show";
    }
}

页面代码:

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

3.2. th:value

th:value的方式可以实现给表单元素,设置HTML标签中表单元素value属性时使用。

    <!--向input标签中的value属性赋值-->
    <input type="text"  th:value="pageMessage"/>
    <!--从域中根据参数名取出参数值 向input标签中的value属性赋值-->
    <input type="text"  th:value="${msg}"/>

3.3. th:if

可以实现根据内容判断传值的效果

<!-- 如果username的值是limin则span标签的文本信息则显示boss,否则显示emp -->
<
span th:if="${username}=='limin'?boss:emp"></span>

3.4. 循环遍历.th:each

例如:以empList 遍历输出。

th:each="emp,i :${empList}" 其中i表示迭代状态。
  • index:当前迭代器的索引 从0开始
  • count:当前迭代对象的计数 从1开始
  • size:被迭代对象的长度
  • even(奇数) / odd(偶数):布尔值,当前循环是否是奇数/偶数 从0开始
  • first:布尔值,当前循环的是否是第一条,如果是返回true否则返回false
  • last:布尔值,当前循环的是否是最后一条,如果是则返回true否则返回false

案例演示

以查询emp表中信息为例演示:

a.在com.augus下创建pojo包,存放实体类

在下面创建emp实体类:

package com.augus.pojo;

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

import java.io.Serializable;
import java.util.Date;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class Emp implements Serializable {
    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private Double comm;
    private Integer deptno;
}

b.在com.augus下创建mapper包

在包下创建 EmpMapper接口文件

package com.augus.mapper;

import com.augus.pojo.Emp;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface EmpMapper {
    List<Emp> queryAllEmp();
}

c.在resources目录下创建包mybatis包

在里面创建EmpMapper.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.augus.mapper.EmpMapper">
    <!--查询所有的员工信息-->
    <select id="queryAllEmp" resultType="emp">
        select * from emp
    </select>
</mapper>

d.在com.augus下创建service包

在包下EmpService接口:

package com.augus.service;

import com.augus.pojo.Emp;
import com.github.pagehelper.PageInfo;

import java.util.List;

public interface EmpService {
    List<Emp> findAll();
}

在service下创建impl包存放实现类,创建EmpServiceImpl,内容如下:

package com.augus.service.impl;

import com.augus.mapper.EmpMapper;
import com.augus.pojo.Emp;
import com.augus.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class EmpServiceImpl implements EmpService {
    @Autowired
    private EmpMapper empMapper;

    @Override
    public List<Emp> findAll() {
        return empMapper.queryAllEmp();
    }
}

e.在controller包下创建 EmpController

package com.augus.controller;

import com.augus.pojo.Emp;
import com.augus.service.EmpService;
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;
import org.springframework.web.servlet.ModelAndView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/emp")
public class EmpController {
    @Autowired
    private EmpService empService;

    @RequestMapping("/findAllList")
    public String findAll(Map<String, Object> map){
        List<Emp> all = empService.findAll();
        //将员工信息添加到到视图,传递到前端页面
        map.put("empList", all);
        //只给前端传递一个员工过去
        map.put("empObj", all.get(0));
        return "showEmp";
    }
}

f.在resources下templates下创建 showEmp.html 模板文件内容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #empTable{
            width: 80%;
            border: 1px slategray slategray;
            margin: 0px auto;
        }
        #empTable th,td{
            border: 1px solid slategray;
            text-align: center;
        }
    </style>
</head>
<body>
    <h1 style="text-align: center">展示单个员工信息</h1>
    <table  id="empTable" cellpadding="0px" cellspacing="0px">
        <tr>
            <th>工号</th>
            <th>姓名</th>
            <th>岗位</th>
            <th>上级主管</th>
            <th>入职日期</th>
            <th>薪资</th>
            <th>补助</th>
            <th>部门号</th>
        </tr>
        <!--
        判断empObj不等于null了在输出内容
        -->
        <span th:if="${empObj} != null">
            <td th:text="${empObj.empno}"></td>
            <td th:text="${empObj.ename}"></td>
            <td th:text="${empObj.job}"></td>
            <td th:text="${empObj.mgr}"></td>
            <td th:text="${empObj.hiredate}"></td>
            <td th:text="${empObj.sal}"></td>
            <td th:text="${empObj.comm}"></td>
            <td th:text="${empObj.deptno}"></td>
        </span>
    </table>


    <h1 style="text-align: center">展示所有的员工信息</h1>
    <table  id="empTable" cellpadding="0px" cellspacing="0px">
        <tr>
            <th>当前迭代索引</th>
            <th>当前迭代对象的记数</th>
            <th>被迭代对象的长度</th>
            <th>循环是否为偶数</th>
            <th>循环是否为奇数</th>
            <th>当前循环是否为第一条</th>
            <th>当前循环是否为最后一条</th>
            <th>工号</th>
            <th>姓名</th>
            <th>岗位</th>
            <th>上级主管</th>
            <th>入职日期</th>
            <th>薪资</th>
            <th>补助</th>
            <th>部门号</th>
        </tr>
        <!--
        判断emplist的长度是否有值,如果有值了,在往出循环取值显示
        -->
        <span th:if="${empList.size()} ne 0">
            <tr th:each="emp,i:${empList}">
                <td th:text="${i.index}"></td>
                <td th:text="${i.count}"></td>
                <td th:text="${i.size}"></td>
                <td th:text="${i.odd}"></td>
                <td th:text="${i.even}"></td>
                <td th:text="${i.first}"></td>
                <td th:text="${i.last}"></td>
                <td th:text="${emp.empno}"></td>
                <td th:text="${emp.ename}"></td>
                <td th:text="${emp.job}"></td>
                <td th:text="${emp.mgr}"></td>
                <td th:text="${emp.hiredate}"></td>
                <td th:text="${emp.sal}"></td>
                <td th:text="${emp.comm}"></td>
                <td th:text="${emp.deptno}"></td>
            </tr>
        </span>
    </table>
</body>
</html>

j.测试

启动项目,在浏览器下访问 http://localhost:8080/springboot08/emp/findAllList,显示内容如下表示成功:

3.5. 对于运算符的支持

3.5.1.算数运算符:

算术运算:+ , - , * , / , %

实例演示:

<span th:text="2+1"></span>       结果:3
<span th:text="'2'+1"></span>     结果:21
<span th:text="${emp.empno}+1"></span> 
<span th:text="${emp.empno+1}"></span>

3.5.2.关系运算符:

  • gt:     great than(大于)>
  • ge: great equal(大于等于)>=
  • eq: equal(等于)==
  • lt:   less than(小于)<
  • le:  less equal(小于等于)<=
  • ne: not equal(不等于)!=

3.5.3.逻辑运算符

  • && 或 and: 表示并且
  • ||  或 or : 表示或者
<div th:text="1>0 and 2<3"></div>
<div th:text="1>0 and 2>3"></div>
<div th:text="1>0 or 2<3"></div>
<div th:text="1>0 or 2>3"></div>
<div th:text="${emp.sal ge 100}"></div>
<div th:text="${emp.sal} ge 1800"></div>
<div th:text="${emp.sal ge 800} and ${emp.deptno eq 20}"></div>
<div th:text="(${emp.sal }ge 1800) or (${emp.deptno } ne 20)"></div>
<div th:text="${emp.sal ge 1800 or emp.deptno ne 20 }"></div>

在早期版本的thymeleaf模板引擎框架中 逻辑运算符要写在${}的外边,目前我们2.7.5版本中,可以写在${}里面

3.5.4.三目运算符

<!-- 判断本次循环如果是偶数,则设置class属性的值为a,否则为b -->
<
tr th:each="emp,i:${empList}" th:class="${i.odd}?a:b">

3.6. th:href

设置标签的href属性值。取值使用@{}取值

案例:

根据员工编号和员工姓名删除用户信息

a.在mapper包下的的EmpMapper中添加内容后如下所示:

package com.augus.mapper;

import com.augus.pojo.Emp;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface EmpMapper {
    List<Emp> queryAllEmp();

    Integer deleteEmpByEmpnoAndEname(Integer empno, String ename);
}

b.在resources下的mybatis包下载EmpMapper.xml中添加根据员工编号和姓名删除员工信息SQL

<?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.augus.mapper.EmpMapper">
    <!--查询所有的员工信息-->
    <select id="queryAllEmp" resultType="emp">
        select * from emp
    </select>
    <!--根据员工编号的名字删除员工-->
    <delete id="deleteEmpByEmpnoAndEname">
        DELETE from emp where empno=#{param1} AND ename=#{param2};
    </delete>
</mapper>

c.在com.augus下的service包进行设置

给EmpService中添加删除接口

package com.augus.service;

import com.augus.pojo.Emp;
import java.util.List;

public interface EmpService {
    List<Emp> findAll();

    /**
     * 根据编号和姓名删除员工信息
     * @param empno 编号
     * @param ename 姓名
     * @return 删除的条数
     */
    Integer deleteEmpByEmpnoAndEname(Integer empno, String ename);
}

d.在controller,EmpController中添加内容

package com.augus.controller;

import com.augus.pojo.Emp;
import com.augus.service.EmpService;
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;
import org.springframework.web.servlet.ModelAndView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/emp")
public class EmpController {
    @Autowired
    private EmpService empService;

    @RequestMapping("/findAllList")
    public String findAll(Map<String, Object> map){
        List<Emp> all = empService.findAll();
        //将员工信息添加到到视图,传递到前端页面
        map.put("empList", all);
        //只给前端传递一个员工过去
        map.put("empObj", all.get(0));
        return "showEmp";
    }

    //这个是给测试 a:herf准备的
    @RequestMapping("/findEmp")
    public String findEmp(Map<String, Object> map){
        List<Emp> all = empService.findAll();
        //将员工信息添加到到视图,传递到前端页面
        map.put("empList", all);
        return "findEmp";
    }
    
    @RequestMapping("/deleteEmp")
    public String deleteEmp(Integer empno, String ename){
        //根据编号和姓名删除员工信息
        empService.deleteEmpByEmpnoAndEname(empno, ename);

        return "redirect:/emp/findEmp";
    }
}

e.在templates下添加  findEmp.html文件内容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #empTable{
            width: 80%;
            border: 1px slategray slategray;
            margin: 0px auto;
        }
        #empTable th,td{
            border: 1px solid slategray;
            text-align: center;
        }
        .a{
            background-color: red;
        }
        .b{
            background-color: yellow;
        }
    </style>
</head>
<body>
<h1 style="text-align: center">展示所有的员工信息</h1>
<!--这个只是点击删除,不会有确认事件-->
<table  id="empTable" cellpadding="0px" cellspacing="0px">
    <tr>
        <th>工号</th>
        <th>姓名</th>
        <th>岗位</th>
        <th>上级主管</th>
        <th>入职日期</th>
        <th>薪资</th>
        <th>补助</th>
        <th>部门号</th>
        <th>操作</th>
    </tr>
    <!--判断emplist的长度是否有值,如果有值了,在往出循环取值显示-->
    <span th:if="${empList.size()} ne 0">

        <!--判断这次循环是否是偶数,如果为偶数,则设置class属性的值为a,否则为b
        h:class="${i.odd}?a:b"-->

        <tr th:each="emp,i:${empList}" th:class="${i.odd}?a:b">
            <td th:text="${emp.empno}"></td>
            <td th:text="${emp.ename}"></td>
            <td th:text="${emp.job}"></td>
            <!--这里判断如果mgr为null, 这个字段就显示为boss,否则就显示原来内容-->
            <td th:text="${emp.mgr} eq null ?boss:${emp.mgr}"></td>
            <td th:text="${emp.hiredate}"></td>
            <td th:text="${emp.sal}"></td>
            <!--薪资这里判断一下 如果为null,则显示为0,不为null则显示原来的内容-->
            <td th:text="${emp.comm} eq null ?0:${emp.comm}"></td>
            <td th:text="${emp.deptno}"></td>
            <td>
                <a th:href="@{/emp/deleteEmp(empno=${emp.empno},ename=${emp.ename})}">删除</a>
            </td>
        </tr>
    </span>
</table>
</body>
</html>

注意:这里点击会直接删除,没有任何的提示,有可能会出现误操作

f.测试

重启项目,访问:http://localhost:8080/springboot08/emp/findEmp,如下图所示单击删除按钮即可删除员工信息:

3.7. th:onclick

给元素绑定事件,单击事件并传递参数,具体用法如下:

<!--一个参数-->
<button th:onclick="getNick([[${user.nick}]])">按钮1</button>
<!--多参-->
<button th:onclick="getNickAndPhone([[${user.nick}]], [[${user.phone}]])">按钮2</button>
<!--多参, 且包含三元运算符-->
<button th:onclick="getNickAndSex([[${user.nick}]], [[${user.sex==1?'男':'女'}]])">按钮3</button

案例演示在3.5中点击删除,会自动的删除掉,不会有任何提示,那么我们这里解决这个问题,点击后让出现弹窗,提示选择是否确认删除,这里还是3.5案例的环境,只是将 findEmp.html 文件内容修改如下即可实现:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style type="text/css">
        #empTable{
            width: 80%;
            border: 1px slategray slategray;
            margin: 0px auto;
        }
        #empTable th,td{
            border: 1px solid slategray;
            text-align: center;
        }
        .a{
            background-color: red;
        }
        .b{
            background-color: yellow;
        }
    </style>
</head>
<body>
    <h1 style="text-align: center">展示所有的员工信息</h1>
    <table  id="empTable" cellpadding="0px" cellspacing="0px">
        <tr>
            <th>工号</th>
            <th>姓名</th>
            <th>岗位</th>
            <th>上级主管</th>
            <th>入职日期</th>
            <th>薪资</th>
            <th>补助</th>
            <th>部门号</th>
            <th>操作</th>
        </tr>
        <!--&lt;!&ndash;
        判断emplist的长度是否有值,如果有值了,在往出循环取值显示
        &ndash;&gt;-->
        <span th:if="${empList.size()} ne 0">
            <!--
            判断这次循环是否是偶数,如果为偶数,则设置class属性的值为a,否则为b
            h:class="${i.odd}?a:b"
            -->
            <tr th:each="emp,i:${empList}" th:class="${i.odd}?a:b">
                <td th:text="${emp.empno}"></td>
                <td th:text="${emp.ename}"></td>
                <td th:text="${emp.job}"></td>
                <!--这里判断如果mgr为null, 这个字段就显示为boss,否则就显示原来内容-->
                <td th:text="${emp.mgr} eq null ?boss:${emp.mgr}"></td>
                <td th:text="${emp.hiredate}"></td>
                <td th:text="${emp.sal}"></td>
                <!--薪资这里判断一下 如果为null,则显示为0,不为null则显示原来的内容-->
                <td th:text="${emp.comm} eq null ?0:${emp.comm}"></td>
                <td th:text="${emp.deptno}"></td>
                <td>
                    <!--
                    这个位置采用 deleteEmpByEmpnoANDEname([[${emp.empno}]],[[${emp.ename}]] 这里idea会存在误报错
                    -->
                    <a href="javascript:void(0)" th:onclick="deleteEmpByEmpnoANDEname([[${emp.empno}]],[[${emp.ename}]])">删除</a>
                </td>
            </tr>
        </span>
    </table>
    <script>
        function deleteEmpByEmpnoANDEname(empno, ename) {
            var result = confirm("确定要删除的编号为:"+empno+",姓名为:"+ename)
            if(result){
                /*
                * 这个地方只需要具体的方法url地址就行,上下文路径做的响应重定向,会自动添加*/
                window.location.href="deleteEmp?empno="+empno+"&ename="+ename;
            }
        }
    </script>
</body>
</html>

测试,重启项目浏览器访问:http://localhost:8080/springboot08/emp/findEmp,如下,在删除的时候会有弹窗出现询问是否会删除,点击确定即可删除,点击取消则不会删除

四、内置对象

Thymeleaf提供了一些内置对象,内置对象可直接在模板中使用。这些对象是以#引用的。
使用内置对象的语法

  • 引用内置对象需要使用#
  • 大部分内置对象的名称都以s结尾。如:strings、numbers、dates
  • 常见内置对象如下
    1. #arrays:数组操作的工具;
    2. #aggregates:操作数组或集合的工具;
    3. #bools:判断boolean类型的工具;
    4. #calendars:类似于#dates,但是是java.util.Calendar类的方法;
    5. #ctx:上下文对象,可以从中获取所有的thymeleaf内置对象;
    6. #dates:日期格式化内置对象,具体方法可以参照java.util.Date;
    7. #numbers: 数字格式化;#strings:字符串格式化,具体方法可以参照String,如startsWith、contains等;
    8. #objects:参照java.lang.Object;
    9. #lists:列表操作的工具,参照java.util.List;
    10. #sets:Set操作工具,参照java.util.Set;#maps:Map操作工具,参照java.util.Map;
    11. #messages:操作消息的工具。

下面主要以:strings、dates、numbers和域对象

4.1.strings对象

4.2.dates

4.3.numbers

#numbers.formatDecimal(numbwe,整数位,整数位千分位标识符,小数位,小数位表示符)
${#numbers.formatDecimal(num,1,'COMMA',2,'POINT')}

案例:

表示整数位至少一位,不足以0补齐,如:num = 123,

${#numbers.formatDecimal(num,1,'COMMA',2,'POINT')}  则显示 123.00
${#numbers.formatDecimal(num,10,'COMMA',2,'POINT')} 则显示 0,000,000,123.00

COMMA表示:','

POINT表示:‘.’

4.4.域对象

 

 使用本章节环境搭建时候的测试文件,在controller中ShowController文件中添加内容如下:

package com.augus.controller;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Map;

@Controller
public class ShowController {
    @RequestMapping("/show")
    public String freeMarkerShow(Map<String, Object> map, HttpServletRequest httpServletRequest, HttpSession session){
        //给request域中放入数据
        httpServletRequest.setAttribute("msg","helloHttpServletRequest");
        //给session域中放入数据
        session.setAttribute("msg", "helloHttpSession");
        //向appilcation域中放入数据
        httpServletRequest.getServletContext().setAttribute("msg","helloAppilcation");

        //向前端传递数据
        map.put("name", "梦特娇");
        //返回模块文件名称
        return "show";
    }
}

在templates中修改show.html内容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
this is show.html
<div th:text="${name}"></div>
<br>
<h1>从HttpServletRequest中取出数据</h1><br>
<span th:text="${#httpServletRequest.getAttribute('msg')}"></span><br>
<span th:text="${#request.getAttribute('msg')}"></span><br>
<span th:text="${msg}"></span><br>

<h1>从httpSession中取出数据</h1><br>
<span th:text="${#httpSession.getAttribute('msg')}"></span><br>
<span th:text="${#session.getAttribute('msg')}"></span><br>
<span th:text="${session.msg}"></span><br>

<h1>从httpSession中取出数据的方式:</h1><br>
<span th:text="${#servletContext.getAttribute('msg')}"></span><br>
<span th:text="${application.msg}"></span>

</body>
</html>

重启项目,然后再浏览器访问 http://localhost:8080/springboot08/show,如下图可以从域中取出数据:

posted @ 2022-11-13 11:05  酒剑仙*  阅读(174)  评论(0)    收藏  举报