一、现在不都前后端分离了?为什么要用Thymeleaf模板引擎?
为什么开始用Thymeleaf模板引擎?不是使用jsp呢? 首先前端交给我们的页面,是html页面,如果是我们之前开发,我们需要把他们转成jsp页面,jsp好处就是当我们查出一些数据转发到JSP页面以后,我们可以用jsp轻松实现数据的显示,及交互等。jsp支持非常强大的功能,包括能写Java代码。
但是呢,SpringBoot项目是以jar的方式,不是war方式,而且SpringBoot用的还是嵌入式的Tomcat,所以呢,他现在默认是不支持jsp的。
那不支持jsp,如果我们直接用纯静态页面的方式,那给我们开发会带来非常大的麻烦,那怎么办呢,SpringBoot推荐使用模板引擎。模板引擎有很多种,比如Thymeleaf
、Velocity
、FreeMarker
,不过思想都是一致的,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>
<!--<!–
判断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>
<!--
这个位置采用 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
- 常见内置对象如下
- #arrays:数组操作的工具;
- #aggregates:操作数组或集合的工具;
- #bools:判断boolean类型的工具;
- #calendars:类似于#dates,但是是java.util.Calendar类的方法;
- #ctx:上下文对象,可以从中获取所有的thymeleaf内置对象;
- #dates:日期格式化内置对象,具体方法可以参照java.util.Date;
- #numbers: 数字格式化;#strings:字符串格式化,具体方法可以参照String,如startsWith、contains等;
- #objects:参照java.lang.Object;
- #lists:列表操作的工具,参照java.util.List;
- #sets:Set操作工具,参照java.util.Set;#maps:Map操作工具,参照java.util.Map;
- #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,如下图可以从域中取出数据: