spring boot: 用thymeleaf嵌套循环展示多层数据(spring boot 2.3.2)
一,什么情况下会用到嵌套循环?
当我们展示多个分类时,每个分类下又展示出推荐的前几个商品,
这时我们需要用到嵌套循环
看一个例子:

说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest
对应的源码可以访问这里获取: https://github.com/liuhongdi/
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,演示项目的相关信息
1,项目地址:
https://github.com/liuhongdi/templateloop
2,项目功能说明:
演示了模板中常用的嵌套循环
3,项目结构;如图:

三,配置文件说明
1,pom.xml
<!--thymeleaf begin-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--thymeleaf end-->
2,application.properties
#error
server.error.include-stacktrace=always
#error
logging.level.org.springframework.web=trace #thymeleaf
spring.thymeleaf.cache=false
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode=HTML
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
四,java程序说明
1,Category.java
//分类模型
public class Category { //分类id
Long categoryId;
public Long getCategoryId() {
return this.categoryId;
}
public void setCategoryId(Long categoryId) {
this.categoryId = categoryId;
} //分类名称
private String categoryName;
public String getCategoryName() {
return this.categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
} //打印
public String toString(){
return " Category:categoryId=" + categoryId +" categoryName=" + categoryName;
}
}
2,Goods.java
//商品模型
public class Goods {
//商品id
Long goodsId;
public Long getGoodsId() {
return this.goodsId;
}
public void setGoodsId(Long goodsId) {
this.goodsId = goodsId;
} //商品名称
private String goodsName;
public String getGoodsName() {
return this.goodsName;
}
public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
} //商品标题
private String subject;
public String getSubject() {
return this.subject;
}
public void setSubject(String subject) {
this.subject = subject;
} //商品价格
private BigDecimal price;
public BigDecimal getPrice() {
return this.price;
}
public void setPrice(BigDecimal price) {
this.price = price;
} //库存
int stock;
public int getStock() {
return this.stock;
}
public void setStock(int stock) {
this.stock = stock;
} //打印
public String toString(){
return " Goods:goodsId=" + goodsId +" goodsName=" + goodsName+" subject=" + subject+" price=" + price+" stock=" + stock;
}
}
3,HomeController.java
@Controller
@RequestMapping("/home")
public class HomeController { //返回分栏目的商品列表
@GetMapping("/category")
public String home(Model model) {
//统一使用一个list返回
ArrayList<Map<String,Object>> list = new ArrayList<>(); //每个分类及分类下的推荐商品,用一个map来保存
//第一个分类
Map<String,Object> map1 = new HashMap<String,Object>();
Category category1 = new Category(); category1.setCategoryId(1L);
category1.setCategoryName("家居");
map1.put("category",category1); //保存商品用的list
ArrayList<Goods> listGoods1 = new ArrayList<Goods>(); Goods goods1 = new Goods();
goods1.setGoodsId(1L);
goods1.setGoodsName("无线智能感应灯");
listGoods1.add(goods1);
Goods goods2 = new Goods();
goods2.setGoodsId(2L);
goods2.setGoodsName("朱之光落地灯");
listGoods1.add(goods2);
Goods goods3 = new Goods();
goods3.setGoodsId(3L);
goods3.setGoodsName("儿童抗首菌枕头");
listGoods1.add(goods3);
Goods goods4 = new Goods();
goods4.setGoodsId(4L);
goods4.setGoodsName("按摩床垫升级款");
listGoods1.add(goods4);
Goods goods5 = new Goods();
goods5.setGoodsId(5L);
goods5.setGoodsName("北欧简约金属茶几");
listGoods1.add(goods5);
map1.put("goodslist",listGoods1); //把map1添加到list
list.add(map1); //第二个分类
Map<String,Object> map2 = new HashMap<String,Object>();
Category category2 = new Category();
category2.setCategoryId(2L);
category2.setCategoryName("美护");
map2.put("category",category2);
ArrayList<Goods> listGoods2 = new ArrayList<Goods>(); Goods goods21 = new Goods();
goods21.setGoodsId(21L);
goods21.setGoodsName("护手霜套装");
listGoods2.add(goods21);
Goods goods22 = new Goods();
goods22.setGoodsId(22L);
goods22.setGoodsName("美白牙贴");
listGoods2.add(goods22);
Goods goods23 = new Goods();
goods23.setGoodsId(23L);
goods23.setGoodsName("口腔护理泡沫");
listGoods2.add(goods23);
map2.put("goodslist",listGoods2);
//把map2添加到list
list.add(map2); //第三个分类
Map<String,Object> map3 = new HashMap<String,Object>();
Category category3 = new Category();
category3.setCategoryId(3L);
category3.setCategoryName("服装");
map3.put("category",category3);
ArrayList<Goods> listGoods3 = new ArrayList<Goods>(); Goods goods31 = new Goods();
goods31.setGoodsId(31L);
goods31.setGoodsName("纯色真丝睡袍");
listGoods3.add(goods31);
Goods goods32 = new Goods();
goods32.setGoodsId(32L);
goods32.setGoodsName("蚕丝条纹睡衣套装");
listGoods3.add(goods32);
Goods goods33 = new Goods();
goods33.setGoodsId(33L);
goods33.setGoodsName("牛津长袖衬衫");
listGoods3.add(goods33);
map3.put("goodslist",listGoods3);
////把map3添加到list
list.add(map3); //把list传递给模板
model.addAttribute("list",list);
return "home/category.html";
}
}
说明:我们没有使用数据库,因为只是用于演示,
直接用代码写入了11条数据,共三个分类
每个分类的数据各放入一个map中,最后用一个list传递给模板
4,category.html
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
<div style="width:100%;height:30px;background:#ffffff;font-size: 16px;" ></div>
<div id="content" style="width:1040px;">
<div style="width:790px;float:left;margin-left:30px;">
<!--main begin-->
<div th:each="categoryOne:${list}" style="width:790px;font-size:16px;overflow: hidden;">
<!--显示分类信息-->
<div style="background:#eeeeee;width:790px;height:20px;line-height:20px;overflow: hidden;margin-top: 10px;">
<div style="width:200px;float:left;">
分类ID:<span th:text="${categoryOne.category.categoryId}"></span> 分类名称:<span th:text="${categoryOne.category.categoryName}"></span>
</div> <div style="width:200px;float:right;text-align: right;">
<a th:href="@{/goods/goodslist/(categoryid=${categoryOne.category.categoryId})}">更多...</a>
</div>
</div>
<!--显示分类下的商品列表信息-->
<div style="width:790px;height:100px;">
<div th:each="goodsOne:${categoryOne.goodslist}" style="width:250px;height:100px;float: left;background:#eeeeee;margin-left:10px;margin-top:10px;">
<div>商品ID:[[${goodsOne.goodsId}]]</div>
<div>商品名称:[[${goodsOne.goodsName}]]</div>
</div>
</div>
</div>
<!--main end-->
</div>
</div>
</body>
</html>
注意代码中用了th:each嵌套循环了两层,变量名分别用了categoryOne和goodsOne
五,测试效果
访问:
http://127.0.0.1:8080/home/category
返回:

循环展示了多个分类下的多个商品
六,查看spring boot版本
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.2.RELEASE)
spring boot: 用thymeleaf嵌套循环展示多层数据(spring boot 2.3.2)的更多相关文章
- 77. Spring Boot Use Thymeleaf 3【从零开始学Spring Boot】
[原创文章,转载请注明出处] Spring Boot默认选择的Thymeleaf是2.0版本的,那么如果我们就想要使用3.0版本或者说指定版本呢,那么怎么操作呢?在这里要说明下 3.0的配置在spri ...
- spring boot整合Thymeleaf的那些坑(spring boot 学习笔记之四)
这里简单记录一下Thymeleaf配置和使用的步骤 1.修改pom文件,添加依赖 <dependency> <groupId>org.springframework.boot& ...
- Spring Boot☞ 使用Thymeleaf模板引擎渲染web视图
静态资源访问 在我们开发Web应用的时候,需要引用大量的js.css.图片等静态资源. 默认配置 Spring Boot默认提供静态资源目录位置需置于classpath下,目录名需符合如下规则: /s ...
- Spring Boot2(五):使用Spring Boot结合Thymeleaf模板引擎使用总结
一.Thymeleaf概述 一般来说,常用的模板引擎有JSP.Velocity.Freemarker.Thymeleaf . SpringBoot推荐的 Thymeleaf – 语法更简单,功能更强大 ...
- Spring Boot2 系列教程(九)Spring Boot 整合 Thymeleaf
虽然现在慢慢在流行前后端分离开发,但是据松哥所了解到的,还是有一些公司在做前后端不分的开发,而在前后端不分的开发中,我们就会需要后端页面模板(实际上,即使前后端分离,也会在一些场景下需要使用页面模板, ...
- Spring Boot 2.X(三):使用 Spring MVC + MyBatis + Thymeleaf 开发 web 应用
前言 Spring MVC 是构建在 Servlet API 上的原生框架,并从一开始就包含在 Spring 框架中.本文主要通过简述 Spring MVC 的架构及分析,并用 Spring Boot ...
- 极简 Spring Boot 整合 Thymeleaf 页面模板
虽然现在慢慢在流行前后端分离开发,但是据松哥所了解到的,还是有一些公司在做前后端不分的开发,而在前后端不分的开发中,我们就会需要后端页面模板(实际上,即使前后端分离,也会在一些场景下需要使用页面模板, ...
- Spring Boot整合Thymeleaf视图层
目录 Spring Boot整合Thymeleaf Spring Boot整合Thymeleaf 的项目步骤 Thymeleaf 语法详解 Spring Boot整合Thymeleaf Spring ...
- Spring Boot和Thymeleaf整合,结合JPA实现分页效果
在项目里,我需要做一个Spring Boot结合Thymeleaf前端模版,结合JPA实现分页的演示效果.做的时候发现有些问题,也查了现有网上的不少文档,发现能全栈实现的不多,所以这里我就把我的做法, ...
随机推荐
- 人人框架renren-security |小记(第一篇)
一丶首先介绍一下人人框架: 1.简介 renren-security | 轻量级权限管理系统 采用Spring.MyBatis.Shiro框架,开发的一套权限系统,极低门槛,拿来即用 支持分布式部 ...
- JDK15真的来了,一起来看看它的新特性
目录 简介 JDK15的新特性 JEP 385 Deprecate RMI Activation for Removal JEP 371 Hidden Classes JEP 339 Edwards- ...
- Kubernetes调度流程与安全(七)
一.Kubernetes中的调度流程 1,介绍 Scheduler 是 k8s 中的调度器,主要的任务是把定义的 Pod 分配到集群的节点上.Scheduler 是作为一个单独的程序运行的,启动之后会 ...
- k8s通过service访问pod(五)
service 每个 Pod 都有自己的 IP 地址.当 controller 用新 Pod 替代发生故障的 Pod 时,新 Pod 会分配到新的 IP 地址.这样就产生了一个问题: 如果一组 Pod ...
- @Embedded 和 @Embeddable
自定义类型在hibernate中实现自定义类型,需要去实现UserType接口即可或者以Component的形式提供. JPA的@Embedded注解有点类似,通过此注解可以在Entity模型中使用一 ...
- 堆的源码与应用:堆排序、优先队列、TopK问题
1.堆 堆(Heap))是一种重要的数据结构,是实现优先队列(Priority Queues)首选的数据结构.由于堆有很多种变体,包括二项式堆.斐波那契堆等,但是这里只考虑最常见的就是二叉堆(以下简称 ...
- 手把手教你ASP.NET Core:使用Entity Framework Core进行增删改查
新建表Todo,如图 添加模型类 在"解决方案资源管理器"中,右键单击项目. 选择"添加" > "新建文件夹". 将文件夹命名为 Mo ...
- JVM 第三篇:Java 类加载机制
本文内容过于硬核,建议有 Java 相关经验人士阅读. 1. 什么是类的加载? 类的加载指的是将类的 .class 文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个 ...
- Linux批量查找与替换
Linux批量查找并替换文件夹下所有文件的内容 经常要使用到 Linux的批量查找与替换,这里为大家介绍使用 sed 命令和 grep 命令的结合来实现查找文件中的内容并替换. 语法格式: sed - ...
- CentOS7 没有安装 ifconfig 命令
ifconfig 命令是设置或显示网络接口的程序,可以显示出我们机器的网卡信息. 除此之外, ip a 命令,也可以设置或显示网卡的信息 在 CentOS 7 下,默认 ifconfig 命令是没有安 ...