PagingAndSortingRepository –如何与Thymeleaf一起使用

在本教程中,我将演示如何通过分页显示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也是视图对象的容器。 它允许控制器将两个值作为单个值返回。 这是我们正在做的事情所希望的。

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

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

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

相关文章

matlab里方差分析的盒子图怎么看,Matlab方差分析

Matlab 方差分析(T检验)在工农业生产和科学研究中,经常遇到这样的问题:影响产品产量、质量的因素很多,我们需要了解在这众多的因素中,哪些因素对影响产品产量、质量有显著影响.为此,要先做试验,然后对测试的结果进行分析.方差分析就是分析测试结果的一种方法.在方差分析中,把在…

使用Okta的单点登录保护您的Vert.x服务器

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕&#xff1f; 尝试使用Okta API进行托管身份验证&#xff0c;授权和多因素身份验证。 Vert.x是Spring生态系统中增长最快的元素之一&#xff0c;保护Vert.x服务器可能是一个…

Apache Kafka简介

什么是Apache Kafka&#xff1f; Apache Kafka是一个分布式流系统&#xff0c;具有发布和订阅记录流的功能。 在另一方面&#xff0c;它是企业消息传递系统。 它是一个快速&#xff0c;水平可扩展和容错的系统。 Kafka有四个核心API&#xff0c; 生产者API&#xff1a; 该API允…

oracle查看存储过程最近编译,Oracle恢复被误编译覆盖的存储过程

同事在写Oracle存储过程时候&#xff0c;是在以前已经写好的过程基础上修改的&#xff0c;想换个名字&#xff0c;由于疏忽没有改名字就编译了&#xff0c;编译完才意识到。这时原来的那个已经没有了。找我想办法恢复回原来的那个过程。通过查资料想到个方法&#xff0c;也不知…

oracle安装 redo log file,Oracle Dump Redo Log File 说明

关于Dump redo log 的示例&#xff0c;MOS 上的文档&#xff1a;[ID 1031381.6] 有详细说明。Dump 有两种方式&#xff1a;(1)使用一. dump redo 说明关于Dump redo log 的示例&#xff0c;MOS 上的文档&#xff1a;[ID 1031381.6] 有详细说明。Dump 有两种方式&#xff1a;(1)…

unity 飞机 残骸模型_训练残骸模式– Java 8中的改进实现

unity 飞机 残骸模型Venkat Subramaniam在今天的演讲中提到了有关“级联方法”模式或“火车残骸”模式的内容&#xff0c;如下所示&#xff1a; >someObject.method1().method2().method3().finalResult()很少有人会将此与构建器模式相关联&#xff0c;但事实并非如此。 无…

datastage配置oracle,IBM Datastage8.5配置问题

大家好&#xff0c;最近因学习需要&#xff0c;在虚拟机REHL5.5上安装了IBM Datastage8.5的服务器端&#xff0c;在windows端安装客户端&#xff0c;调试连接时&#xff0c;提示密码不正确&#xff0c;我修改了密码&#xff0c;重启了服务器&#xff0c;还是提示密码不正确&…

使用Spring @Transactional进行数据源路由

卡尔帕帕&#xff08;Carl Papa&#xff09;在Spring框架中使用方面来确定要使用的DataSource &#xff08;读写或只读&#xff09;启发了我。 所以&#xff0c;我正在写这篇文章。 我必须承认&#xff0c;我对Spring的AbstractRoutingDataSource早已熟悉。 但是我不知道在哪里…

linux设置新硬盘权限,Linux 下挂载新硬盘以及更改为普通权限

1、启动终端&#xff0c;以root用户登录2、查看硬盘信息&#xff1a;#fdisk -l3、进入磁盘&#xff0c;对磁盘进行分区&#xff1a;#fdisk /dev/sda(注意看你要挂载哪一个磁盘&#xff0c;我的是sda&#xff0c;有的是sdb)4、格式化分区&#xff1a;#mkfs.ext3 /dev/sda1 //注&…

使用Payara Micro的Easy Java EE Microservices

想知道如何开始使用Java EE Microservices&#xff1f; 使用Java EE API只需很少的步骤即可部署微服务。 许多人认为Java EE无法与微服务一起使用&#xff0c;但事实并非如此……特别是如果您仅使用服务所需的Java EE规范。 在这篇简短的文章中&#xff0c;我将演示如何使用Jav…

linux终端lex程序运行,lex的简单使用

Lex & Flex 简介Lex是lexical compiler的缩写&#xff0c;是Unix环境下非常著名的工具&#xff0c; Lex (最早是埃里克施密特和 Mike Lesk 制作)是许多 UNIX 系统的标准词法分析器(lexical analyzer)产生程式&#xff0c;而且这个工具所作的行为被详列为 POSIX 标准的一部分…

Linux内存page,Linux虚拟内存管理 - Page Table的作用

虚拟内存的作用&#xff1a;1.扩展实际有限的物理内存&#xff0c;当然这种扩展是虚拟的&#xff0c;比如物理内存512M&#xff0c;对于一个需要1G空间的进程来说&#xff0c;照样可以运行。这增加了操作系统是应用范围。2.使得进程中的数据空间增大&#xff0c;增大到多少与硬…

openoffice+linux+jodconverter+乱码,OpenOffice安装和转换乱码解决方案

前言&#xff1a;OpenOffice项目中用途&#xff1a;word转换pdfWindows安装、转换&#xff1a;安装包下载后一路OK就可以正常安装&#xff0c;转换没有问题Linux安装、转换&#xff1a;安装有分DEB包和RPM包&#xff0c;下面会说明各自安装方法在en_US.UTF-8 系统环境下会出现乱…

junit 参数化测试用例_JUnit:在参数化测试中命名单个测试用例

junit 参数化测试用例几年前&#xff0c;我写了有关JUnit参数化测试的文章 。 我不喜欢它们的一件事是JUnit使用数字命名了单个测试用例&#xff0c;因此&#xff0c;如果它们失败&#xff0c;您将不知道是哪个测试参数导致了失败。 以下Eclipse屏幕快照将向您展示我的意思&…

MX250和第三方Linux版区别,MX250和MX350哪个好一点,区别和差距在哪里?求推荐?_科技数码通...

MX350系列显卡使笔记本颜值变得更高&#xff0c;性能更强&#xff0c;更轻便&#xff0c;在轻便笔记本需求变得越来越大&#xff0c;但性能也要求越来越高&#xff0c;特别是在图像处理方面&#xff0c;这个时候MX系列的显卡便应运而生&#xff0c;其拥有者超低的功耗&#xff…

linux r包默认安装位置,R-Language(R语言或称r-project)的安装

1、R语言的简介R语言(r-project)是主要用于统计分析、绘图的语言和操作环境。2、配置yum源2.1、安装说明由于编译安装相对繁琐&#xff0c;故而安装使用repoforge的源解决&#xff0c;免去编译的麻烦。注意&#xff1a;请根据实际的系统OS版本选取合适的YUM源。2.3、rpmforge源…

aws s3 命令行_通过命令行界面使用AWS ElasticMapReduce

aws s3 命令行在本文中&#xff0c;我将通过使用EMR的CLI使用AWS MapReduce服务&#xff08;称为ElasticMapReduce &#xff09;。 使用EMR的过程可以大致分为三个步骤&#xff1a; 设置并填充S3存储桶 创建并运行EMR作业 从S3存储桶中获取结果 在开始这三个高级步骤之前&…

在5分钟内将Spring Boot作为Windows服务启动

最近&#xff0c;我不得不将Spring Boot应用程序部署为Windows服务&#xff0c;并且对使用winsw如此容易感到惊讶。 我之前曾写过关于使用procrun – Java程序作为Windows服务的文章 &#xff0c;但是winsw更加容易 入门 Spring Boot文档的第59节是有关安装Spring Boot应用程序…

Android 画布画线,android实现一个简单的画布,可以用手指画线条。

满意答案wpdhc2016.07.05采纳率&#xff1a;49% 等级&#xff1a;7已帮助&#xff1a;359人public class DrawView extends View {Context mycontext;int toasttime 1000*60;boolean enabletoast true;//之前的坐标float preX;float preY;//路径private Path path;//画笔p…

设置html文字居中自动换行,CSS怎么设置文字自动换行?

CSS怎么设置文字自动换行&#xff1f;下面本篇文章就给大家介绍css设置文字(特别是连续的数字和英文)自动换行的方法。有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对你们有所帮助。关于换行问题&#xff0c;正常字符的换行是比较合理的&#xff0c;…