thymeleaf与jsp_PagingAndSortingRepository –如何与Thymeleaf一起使用

thymeleaf与jsp

在本教程中,我将演示如何通过分页显示Thymeleaf中的企业客户列表。

1 –项目结构

我们有一个正常的Maven项目结构。

2 –项目依赖性

除了正常的Spring依赖关系之外,我们还添加Thymeleaf和hsqldb,因为我们使用的是嵌入式数据库。

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.michaelcgood</groupId><artifactId>michaelcgood-pagingandsorting</artifactId><version>0.0.1</version><packaging>jar</packaging><name>PagingAndSortingRepositoryExample</name><description>Michael C  Good - PagingAndSortingRepository</description><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.6.RELEASE</version><relativePath /> <!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.hsqldb</groupId><artifactId>hsqldb</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

3 –型号

我们为客户定义以下字段:

  • 唯一标识符
  • 客户名称
  • 客户地址
  • 当前发票上的欠款

getter和setter在Spring Tool Suite中快速生成。
要将此模型注册到@SpringBootApplication,需要@Entity批注。

ClientModel.java

package com.michaelcgood.model;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;@Entity
public class ClientModel {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Long id;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public Integer getCurrentInvoice() {return currentInvoice;}public void setCurrentInvoice(Integer currentInvoice) {this.currentInvoice = currentInvoice;}private String name;private String address;private Integer currentInvoice;}

与ClientModel不同,PagerModel只是一个POJO(普通的旧Java对象)。 没有导入,因此没有注释。 该PagerModel纯粹用于帮助我们网页上的分页。 阅读Thymeleaf模板并查看演示图片后,请重新访问该模型。 当您在上下文中考虑它时,PagerModel更有意义。

PagerModel.java

package com.michaelcgood.model;public class PagerModel {private int buttonsToShow = 5;private int startPage;private int endPage;public PagerModel(int totalPages, int currentPage, int buttonsToShow) {setButtonsToShow(buttonsToShow);int halfPagesToShow = getButtonsToShow() / 2;if (totalPages <= getButtonsToShow()) {setStartPage(1);setEndPage(totalPages);} else if (currentPage - halfPagesToShow <= 0) {setStartPage(1);setEndPage(getButtonsToShow());} else if (currentPage + halfPagesToShow == totalPages) {setStartPage(currentPage - halfPagesToShow);setEndPage(totalPages);} else if (currentPage + halfPagesToShow > totalPages) {setStartPage(totalPages - getButtonsToShow() + 1);setEndPage(totalPages);} else {setStartPage(currentPage - halfPagesToShow);setEndPage(currentPage + halfPagesToShow);}}public int getButtonsToShow() {return buttonsToShow;}public void setButtonsToShow(int buttonsToShow) {if (buttonsToShow % 2 != 0) {this.buttonsToShow = buttonsToShow;} else {throw new IllegalArgumentException("Must be an odd value!");}}public int getStartPage() {return startPage;}public void setStartPage(int startPage) {this.startPage = startPage;}public int getEndPage() {return endPage;}public void setEndPage(int endPage) {this.endPage = endPage;}@Overridepublic String toString() {return "Pager [startPage=" + startPage + ", endPage=" + endPage + "]";}}

4 –储存库

PagingAndSortingRepository是CrudRepository的扩展。 唯一的区别是,它允许您对实体进行分页。 注意,我们用@Repository注释了接口,以使其对@SpringBootApplication可见。

ClientRepository.java

package com.michaelcgood.dao;import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;import com.michaelcgood.model.ClientModel;@Repository
public interface ClientRepository extends PagingAndSortingRepository<ClientModel,Long> {}

5 –控制器

我们在课程开始时定义一些变量。 我们只想一次显示3个页面按钮。 初始页面是结果的第一页,页面上的初始项目数是5,用户可以每页获得5或10个结果。

我们使用addtorepository()方法将一些示例值添加到我们的存储库中,该方法在该类的下面进一步定义。 使用addtorepository method(),我们将几个“客户端”添加到我们的存储库中,其中许多都是帽子公司,因为我没有足够的想法。

这里使用ModelAndView而不是Model。 而是使用ModelAndView,因为它既是ModelMap的容器又是View对象的容器。 它允许控制器将两个值作为单个值返回。 这是我们正在做的事情所希望的。

ClientController.java

package com.michaelcgood.controller;import java.util.Optional;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.michaelcgood.model.PagerModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;import com.michaelcgood.dao.ClientRepository;
import com.michaelcgood.model.ClientModel;@Controller
public class ClientController {private static final int BUTTONS_TO_SHOW = 3;private static final int INITIAL_PAGE = 0;private static final int INITIAL_PAGE_SIZE = 5;private static final int[] PAGE_SIZES = { 5, 10};@AutowiredClientRepository clientrepository;@GetMapping("/")public ModelAndView homepage(@RequestParam("pageSize") Optional<Integer> pageSize,@RequestParam("page") Optional<Integer> page){if(clientrepository.count()!=0){;//pass}else{addtorepository();}ModelAndView modelAndView = new ModelAndView("index");//// Evaluate page size. If requested parameter is null, return initial// page sizeint evalPageSize = pageSize.orElse(INITIAL_PAGE_SIZE);// Evaluate page. If requested parameter is null or less than 0 (to// prevent exception), return initial size. Otherwise, return value of// param. decreased by 1.int evalPage = (page.orElse(0) < 1) ? INITIAL_PAGE : page.get() - 1;// print repoSystem.out.println("here is client repo " + clientrepository.findAll());Page<ClientModel> clientlist = clientrepository.findAll(new PageRequest(evalPage, evalPageSize));System.out.println("client list get total pages" + clientlist.getTotalPages() + "client list get number " + clientlist.getNumber());PagerModel pager = new PagerModel(clientlist.getTotalPages(),clientlist.getNumber(),BUTTONS_TO_SHOW);// add clientmodelmodelAndView.addObject("clientlist",clientlist);// evaluate page sizemodelAndView.addObject("selectedPageSize", evalPageSize);// add page sizesmodelAndView.addObject("pageSizes", PAGE_SIZES);// add pagermodelAndView.addObject("pager", pager);return modelAndView;}public void addtorepository(){//below we are adding clients to our repository for the sake of this exampleClientModel widget = new ClientModel();widget.setAddress("123 Fake Street");widget.setCurrentInvoice(10000);widget.setName("Widget Inc");clientrepository.save(widget);//next clientClientModel foo = new ClientModel();foo.setAddress("456 Attorney Drive");foo.setCurrentInvoice(20000);foo.setName("Foo LLP");clientrepository.save(foo);//next clientClientModel bar = new ClientModel();bar.setAddress("111 Bar Street");bar.setCurrentInvoice(30000);bar.setName("Bar and Food");clientrepository.save(bar);//next clientClientModel dog = new ClientModel();dog.setAddress("222 Dog Drive");dog.setCurrentInvoice(40000);dog.setName("Dog Food and Accessories");clientrepository.save(dog);//next clientClientModel cat = new ClientModel();cat.setAddress("333 Cat Court");cat.setCurrentInvoice(50000);cat.setName("Cat Food");clientrepository.save(cat);//next clientClientModel hat = new ClientModel();hat.setAddress("444 Hat Drive");hat.setCurrentInvoice(60000);hat.setName("The Hat Shop");clientrepository.save(hat);//next clientClientModel hatB = new ClientModel();hatB.setAddress("445 Hat Drive");hatB.setCurrentInvoice(60000);hatB.setName("The Hat Shop B");clientrepository.save(hatB);//next clientClientModel hatC = new ClientModel();hatC.setAddress("446 Hat Drive");hatC.setCurrentInvoice(60000);hatC.setName("The Hat Shop C");clientrepository.save(hatC);//next clientClientModel hatD = new ClientModel();hatD.setAddress("446 Hat Drive");hatD.setCurrentInvoice(60000);hatD.setName("The Hat Shop D");clientrepository.save(hatD);//next clientClientModel hatE = new ClientModel();hatE.setAddress("447 Hat Drive");hatE.setCurrentInvoice(60000);hatE.setName("The Hat Shop E");clientrepository.save(hatE);//next clientClientModel hatF = new ClientModel();hatF.setAddress("448 Hat Drive");hatF.setCurrentInvoice(60000);hatF.setName("The Hat Shop F");clientrepository.save(hatF);}}

6 – Thymeleaf模板

在Thymeleaf模板中,要注意的两个最重要的事情是:

  • 胸腺标准方言
  • Java脚本

像在CrudRepository中一样,我们使用th:each =” clientlist:$ {clientlist}”遍历PagingAndSortingRepository。 除了存储库中的每个项目不是Iterable之外,该项目都是页面。

使用select class =“ form-control pagination” id =“ pageSizeSelect”,我们允许用户选择5或10的页面大小。我们在Controller中定义了这些值。

接下来是允许用户浏览各个页面的代码。 这是我们的PagerModel进入使用的地方。

changePageAndSize()函数是JavaScript函数,当用户更改页面大小时,它将更新页面大小。

<html xmlns="http://www.w3.org/1999/xhtml"xmlns:th="http://www.thymeleaf.org"><head>
<!-- CSS INCLUDE -->
<link rel="stylesheet"href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"crossorigin="anonymous"></link><!-- EOF CSS INCLUDE -->
<style>
.pagination-centered {text-align: center;
}.disabled {pointer-events: none;opacity: 0.5;
}.pointer-disabled {pointer-events: none;
}
</style></head>
<body><!-- START PAGE CONTAINER --><div class="container-fluid"><!-- START PAGE SIDEBAR --><!-- commented out     <div th:replace="fragments/header :: header"> </div> --><!-- END PAGE SIDEBAR --><!-- PAGE TITLE --><div class="page-title"><h2><span class="fa fa-arrow-circle-o-left"></span> Client Viewer</h2></div><!-- END PAGE TITLE --><div class="row"><table class="table datatable"><thead><tr><th>Name</th><th>Address</th><th>Load</th></tr></thead><tbody><tr th:each="clientlist : ${clientlist}"><td th:text="${clientlist.name}">Text ...</td><td th:text="${clientlist.address}">Text ...</td><td><button type="button"class="btn btn-primary btn-condensed"><i class="glyphicon glyphicon-folder-open"></i></button></td></tr></tbody></table><div class="row"><div class="form-group col-md-1"><select class="form-control pagination" id="pageSizeSelect"><option th:each="pageSize : ${pageSizes}" th:text="${pageSize}"th:value="${pageSize}"th:selected="${pageSize} == ${selectedPageSize}"></option></select></div><div th:if="${clientlist.totalPages != 1}"class="form-group col-md-11 pagination-centered"><ul class="pagination"><li th:class="${clientlist.number == 0} ? disabled"><aclass="pageLink"th:href="@{/(pageSize=${selectedPageSize}, page=1)}">«</a></li><li th:class="${clientlist.number == 0} ? disabled"><aclass="pageLink"th:href="@{/(pageSize=${selectedPageSize}, page=${clientlist.number})}">←</a></li><lith:class="${clientlist.number == (page - 1)} ? 'active pointer-disabled'"th:each="page : ${#numbers.sequence(pager.startPage, pager.endPage)}"><a class="pageLink"th:href="@{/(pageSize=${selectedPageSize}, page=${page})}"th:text="${page}"></a></li><lith:class="${clientlist.number + 1 == clientlist.totalPages} ? disabled"><a class="pageLink"th:href="@{/(pageSize=${selectedPageSize}, page=${clientlist.number + 2})}">→</a></li><lith:class="${clientlist.number + 1 == clientlist.totalPages} ? disabled"><a class="pageLink"th:href="@{/(pageSize=${selectedPageSize}, page=${clientlist.totalPages})}">»</a></li></ul></div></div></div><!-- END PAGE CONTENT --><!-- END PAGE CONTAINER --></div><scriptsrc="https://code.jquery.com/jquery-1.11.1.min.js"integrity="sha256-VAvG3sHdS5LqTT+5A/aeq/bZGa/Uj04xKxY8KM/w9EE="crossorigin="anonymous"></script><scriptsrc="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"crossorigin="anonymous"></script><script th:inline="javascript">/*<![CDATA[*/$(document).ready(function() {changePageAndSize();
});function changePageAndSize() {$('#pageSizeSelect').change(function(evt) {window.location.replace("/?pageSize=" + this.value + "&page=1");});
}/*]]>*/</script></body>
</html>

7 –配置

可以根据您的喜好更改以下属性,但这正是我所希望的环境。

application.properties

#==================================
# = Thymeleaf configurations 
#==================================
spring.thymeleaf.check-template-location=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
server.contextPath=/

8 –演示

这是主页。

这是第二页。

我可以将页面上的项目数量更改为10。

源代码在 Github上

翻译自: https://www.javacodegeeks.com/2017/10/pagingandsortingrepository-use-thymeleaf.html

thymeleaf与jsp

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334405.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 批量生成 SQL 脚本语句解决实际的业务需求/如何拼接字符串/拼接字符串的 SQL 语句

文章目录实际需求分析思路写拼接 SQL 脚本的脚本语句执行得到脚本语句保存成 SQL 脚本文件实际需求 有些行政区域的字段 area_fullname 是空的&#xff0c;如何补全呢&#xff1f;如下所示&#xff1a; 分析思路 &#xff08;一&#xff09;如何取到每个区域的上级名称和上…

php的变量都放在哪里,php变量一般放在哪个位置

php变量一般放在哪个位置php定义变量的要求格式&#xff0c;是非常宽松的&#xff0c;至于在哪里定义变量就需要看你的需求&#xff0c;可以在构造函数&#xff0c;也可以在你定义的方法中定义局部变量&#xff0c;也可以在构造函数外面定义全局变量。// 局部变量 函数内部func…

oauth2令牌刷新_了解OAuth2令牌认证

oauth2令牌刷新1.简介 在本教程中&#xff0c;我们将了解OAuth2令牌身份验证 &#xff0c;以便只有经过身份验证的用户和应用程序才能获得有效的访问令牌&#xff0c;该令牌随后可用于访问服务器上的授权API&#xff08;在OAuth术语中仅是受保护的资源&#xff09;。 使用基于…

jsap支付_Java命令行界面(第20部分):JSAP

jsap支付JSAP &#xff08; Java Simple Argument Parser &#xff09;2.1是本系列文章的第二十篇&#xff0c;重点是处理Java的命令行参数。 JSAP页面描述了该库存在的原因&#xff1a;“我在Internet上找到了多个解析器&#xff0c;所有解析器都处理了开关&#xff0c;但是没…

python语句大全input_input提示文字 Python基础输入函数,if-else语句,if-elif

input&#xff08;&#xff09;函数 此功能用于获取用户输入。 &#xff08;调用1&#xff09;input后&#xff0c;程序将立即暂停并等待用户输入。在用户完成内容输入后&#xff0c;单击Enter&#xff0c;程序将继续向下执行。 例如&#xff1a; input() &#xff08;2&#x…

ftp限流java,FTP流量限制的方法

一般来说&#xff0c;下载都是通过FTP来实现的&#xff0c;这样简单的采用ACLs就可以实现的。不过这样存在一个问题&#xff0c;就是原来正常的网络访问也给禁止了&#xff0c;无法继续工作&#xff0c;另外&#xff0c;还有大量的DOWNLOAD不通过FTP&#xff0c;而是借助HTTP协…

argparser_Java命令行界面(第22部分):argparser

argparserJohn Lloyd的argparser是本系列的第二十二篇有关基于Java的命令行参数解析的文章中介绍的库。 该库的主页除了提供单个源代码示例外&#xff0c;还提供了指向基于Javadoc的API文档 &#xff0c;JAR文件&#xff0c;ZIP文件和TAR文件的链接。 本帖子中使用的示例与本系…

判断 小程序 是否 滚动到页面底部 scrolltolower_微信小程序长列表性能优化——recycle-view

背景&#xff1a;第七次人口普查项目使用是微信小程序原生框架&#xff0c;组件是根据用户需求由项目组前端组组长封装完成的。采集小程序正式登记首页列表页面&#xff0c;根据腾讯老哥在sentry上的监控可以看出&#xff0c;列表页面前端性能比较差&#xff0c;主要表现在一些…

java rop_Java命令行界面(第23部分):Rop

java ropRop库在其主页上被描述为“用Java编写的轻量级命令行选项解析器”。 Rop的“简介”还指出&#xff1a;“ Rop的设计目的是最小化同时方便&#xff0c;并涵盖了大多数常见的命令行解析用例。” 这篇文章是本系列中有关解析Java命令行参数的系列文章中的第23部分&#xf…

java 接口 私有_Java 9:好的,坏的和私有的接口方法

java 接口 私有Java 9 是在几周前发布的。 查看发行说明 &#xff0c;其中包含许多有趣的功能。 不过&#xff0c;我觉得并非一切都是不如Oracle和Java行家似乎图片吧 。 我看到了Java世界中的三个趋势&#xff0c;分别是好&#xff0c;坏和丑陋。 让我们从好的开始。 Birdman…

python卸载module_Python学习笔记

拖了一整年终于开始学习Python编程。为了逼自己快速上路&#xff0c;强行要求自己本学期的两门课程全部的coding作业用Python完成。 一门机器学习&#xff08;computational Stats&#xff09;&#xff0c;一门Jeff WU 大佬的实验设计与分析&#xff08;DOE&#xff09;。即使R…

mlp神经网络_白天鹅黑天鹅灰天鹅?卷积神经网络帮你搞定识别

全文共3014字&#xff0c;预计学习时长6分钟本文将通过一系列的天鹅图片来解释卷积神经网络&#xff08;CNN&#xff09;的概念&#xff0c;并使用CNN在常规多层感知器神经网络上处理图像。图像分析假设我们要创建一个能够识别图像中的天鹅的神经网络模型。天鹅具有某些特征&am…

java登录界面命令_Java命令行界面(第26部分):CmdOption

java登录界面命令由于Tweet&#xff0c;我了解了本系列中第26个基于Java的功能强大的库&#xff0c;该库用于解析命令行参数 。 CmdOption在其GitHub主页上被描述为“一个通过注释配置的&#xff0c;用于Java 5应用程序的简单注释驱动命令行解析器工具包。” 该项目的副标题是“…

getopt java_Java命令行界面(第28部分):getopt4j

getopt javagetopt4j的页面将其描述为“一个根据GNU样式解析命令行参数的库。” 然后&#xff0c; 页面介绍getopt4j &#xff1a;“getopt4j库旨在以与glibc &#xff08;GNU C运行时库&#xff09;中的C getopt&#xff08;&#xff09;函数相同的方式解析命令行选项。 与原始…

springboot redis token_Spring Boot + Redis + 注解 + 拦截器来实现接口幂等性校验

优质文章&#xff0c;及时送达作者 | wangzaiplus链接 | www.jianshu.com/p/6189275403ed一、概念幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次比如:订单接口, 不能多次创建订单支付接口, 重复支付同一笔订单只能扣一次钱支付宝回调接口, 可能…

java 示例_功能Java示例 第2部分–讲故事

java 示例这是称为“ Functional Java by Example”的系列文章的第2部分。 我在本系列的每个部分中开发的示例是某种“提要处理程序”&#xff0c;用于处理文档。 在上一部分中&#xff0c;我从一些原始代码开始&#xff0c;并应用了一些重构来描述“什么”而不是“如何”。 …

python range函数范围_Python range函数

Python range函数教程 range函数详解 语法 range(start, stop[, step]) 参数 参数 描述 start 计数从 start 开始。默认是从 0 开始。 stop 计数到 stop 结束&#xff0c;但不包括 stop。 step 步长&#xff0c;默认为1&#xff0c;可以支持负数。 返回值 返回生成的序列。 案例…

openpyxl删除添加excel列_Python | 如何使用Python操作Excel(二)

0 前言在阅读本文之前&#xff0c;请确保您已满足或可能满足一下条件&#xff1a;请确保您具备基本的Python编程能力。请确保您会使用Excel。请确保您的电脑已经安装好Python且pip可用。请确保您已经读过前文&#xff1a;如何使用Python操作Excel(一)LogicPanda&#xff0c;公众…

payara 创建 集群_使用Payara Micro的Easy Java EE Microservices

payara 创建 集群想知道如何开始使用Java EE Microservices&#xff1f; 使用Java EE API部署微服务只需要几个快速步骤。 许多人认为Java EE对于与微服务一起使用而言过于繁重&#xff0c;但事实并非如此……尤其是如果您仅利用服务所需的Java EE规范。 在这篇简短的文章中&am…

php导出页面居中设置,PHPExcel导出插入图片和居中问题

首先到网上先下载PHPExcel下载后解压得到这两个文件下载后引用该文件最后编写相关代码&#xff1a;首先是图片插入导出$objDrawing new PHPExcel_Worksheet_Drawing();$objDrawing->setName(‘Photo‘);$objDrawing->setDescription(‘Photo‘);$objDrawing->setPath…