Im Allgemeinen implementiert das Spring Data JPA-Modul die Spring Data Commons-Repository-Abstraktion, um Repository-Implementierungen zu vereinfachen. Darüber hinaus ermöglicht Ihnen der Spring Data-Repository-Ansatz, durch die Verwendung einer einfachen Schnittstellendefinition den größten Teil des Implementierungscodes loszuwerden. Sie haben die Repository-Implementierung in Ihren Anwendungen genutzt, indem Sie Schnittstellen erstellt haben, die das erweitern Repository die von der Spring Data-Infrastruktur bereitgestellte.
Der Spring-Daten-Repository erfasst den Typ der Domänenklasse sowie die Typidentität. Aber das ist noch nicht die ganze Geschichte: Spring Data bietet auch verschiedene Arten von Repositories.
Daher stellt Ihnen Spring Data die folgenden Repositorys zur Verfügung.
Repository: Eine einfache Markierungsschnittstelle, mit der die Spring Data-Infrastruktur benutzerdefinierte Repositorys abrufen kann (in Bezug auf die Konfiguration).
CrudRepository: Erweitert Repository und fügt grundlegende Persistenzmethoden wie das Speichern, Suchen und Löschen von Entitäten hinzu.
PagingAndSortingRepositories: Erweitert CrudRepository und fügt Methoden für den seitenweisen Zugriff auf Entitäten und deren Sortierung nach bestimmten Kriterien hinzu.
Dieses Tutorial führt Sie durch eine Beispielanwendung zur Implementierung von PrimeFaces, Spring Data und MySQL-Datenbanken mithilfe von PagingAndSortingRepositories um die Anzeige von Daten zu paginieren. Wenn Sie Fragen haben, schreiben Sie diese bitte in den Kommentarbereich.
Lesen Sie auch:
Spring Data JPA
Spring Data JPA + Querydsl
Spring Data + MongoDB
Verbinde dich mit uns : Google+ | Twitter | Facebook
Schauen wir uns an, wie EmployeeRepository das von Spring Data bereitgestellte CrudRespository erbt.
EmployeeRepository.java
package net.javabeat.springdata.repo;
import net.javabeat.springdata.jpa.data.Employee;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EmployeeRepository extends CrudRepository<Employee,Integer>{
}
Die EmployeeRepository-Schnittstelle erbt nun alle im CurdRepository definierten Methoden, was uns zu einem Repository führt, das diese definierten Methoden im CurdRepository selbst enthält.
CrudRepository.java (Dies ist die Spring Data API-Implementierung)
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {
<S extends T> save(S entity);
<S extends T> Iterable<S> save(Iterable<S> entities);
T findOne(ID id);
Iterable<T> findAll();
void delete(ID id);
void delete(T entity);
void deleteAll();
}
Es enthält also Methoden zum Speichern einer einzelnen Entität sowie einer Wiederholbar von Entitäten, Finder-Methoden für einzelne Entitäten oder alle Entitäten und löschen Methoden verschiedener Geschmacksrichtungen. PagingAndSortingRepository erweitert nun wiederum CrudRepository und fügt Methoden hinzu, um die Übergabe von Instanzen von Pagable und Sort an die generischen findAll-Methoden zu ermöglichen, um tatsächlich Seite für Seite auf Entitäten zuzugreifen.
Dieses Tutorial würde das geben PagingAndSortingRepository Beispielanwendung mit Benutzeroberfläche, entwickelt mit PrimeFaces.
1. Datenbanktabellen
Es handelt sich lediglich um eine Darstellung der Datenbankmodelle, die zur Implementierung des Unternehmensbeispiels verwendet wurden und die wirklich auf einem echten Datensatz basieren.
Abfragen zur Tabellenerstellung
CREATE TABLE `address` (
`addressId` bigint(20) NOT NULL AUTO_INCREMENT,
`addressCountry` varchar(45) DEFAULT NULL,
`addressCity` varchar(45) DEFAULT NULL,
PRIMARY KEY (`addressId`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
SELECT * FROM javabeat.employee;
CREATE TABLE `employee` (
`employeeId` bigint(20) NOT NULL AUTO_INCREMENT,
`employeeName` varchar(20) DEFAULT NULL,
`address` bigint(20) DEFAULT NULL,
PRIMARY KEY (`employeeId`),
KEY `FK_EMP_ADD` (`address`),
CONSTRAINT `FK_EMP_ADD` FOREIGN KEY (`address`) REFERENCES `address` (`addressId`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
Adresstabelle
Mitarbeitertisch
[Nur-Lese-/Nur-Schreib-Vorgänge mit Spring Data Repository Services](https://javatipps.de/nur-lese-nur-schreib-vorgaenge-mit-spring-data-repository-services/)
Fremdschlüssel des Mitarbeiters
2. Geschäftsdomäne
Wie Sie bereits wussten, enthält die JPA zwei Hauptteile: das Mapping und den Entity Manager. Hier listen wir die Zuordnungsklassen auf, die später zum Ausführen der im vorherigen Abschnitt erwähnten CRUD-Operationen für definierte Datenbankmodelle verwendet werden.
Adresse.java
package net.javabeat.springdata.jpa.data;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity(name = "address")
public class Address {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer addressId;
private String addressCountry = "";
private String addressCity = "";
@OneToOne(cascade = CascadeType.ALL, mappedBy = "address")
private Employee employee;
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public Integer getAddressId() {
return addressId;
}
public void setAddressId(Integer addressId) {
this.addressId = addressId;
}
public String getAddressCountry() {
return addressCountry;
}
public void setAddressCountry(String addressCountry) {
this.addressCountry = addressCountry;
}
public String getAddressCity() {
return addressCity;
}
public void setAddressCity(String addressCity) {
this.addressCity = addressCity;
}
}
Employee.java
package net.javabeat.springdata.jpa.data;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
@Entity
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer employeeId;
@Basic(optional = false)
private String employeeName;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "Address")
private Address address = new Address();
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public Integer getEmployeeId() {
return employeeId;
}
public void setEmployeeId(Integer employeeId) {
this.employeeId = employeeId;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
}
3. Spring-Datenrepositorys
PagingAndSortingRepository würde für die Implementierung der Spring Data-Operationen verwendet werden. Es handelt sich um die spezialisierte Version der CrudRepository-Schnittstelle. PagingAndSortingRepository definiert zusätzliche Methoden zum Suchen der Zeilen durch Übergabe der Seitenzahlen. Schauen wir uns die Beispielimplementierung für die Klassen AddressRepository und EmployeeRepository an.
AddressRepositiry.java
package net.javabeat.springdata.repo;
import net.javabeat.springdata.jpa.data.Address;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface AddressRepository extends PagingAndSortingRepository<Address,Integer>{
}
EmployeeRepository.java
package net.javabeat.springdata.repo;
import net.javabeat.springdata.jpa.data.Employee;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface EmployeeRepository extends PagingAndSortingRepository<Employee,Integer>{
}
4. Spring-Kontextkonfiguration
Hier ist die XML-Spring-Konfiguration, die zum Konfigurieren von Spring-Beans, Repositorys und dem MySQL-Entity-Manager verwendet wird.
SpringContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<!-- For consider the using of annotations foe defining Spring Bean -->
<context:annotation-config />
<!-- For defining Spring Bean -->
<context:component-scan base-package="net.javabeat.springdata.beans" />
<!-- For bootstrapping the Spring Repository -->
<jpa:repositories base-package="net.javabeat.springdata.repo" />
<!-- Necessary to get the entity manager injected into the factory bean -->
<bean
/>
<!-- Define EclipseLink JPA Vendor Adapter -->
<bean id="jpaVendorAdapter"
>
<property name="databasePlatform"
value="org.eclipse.persistence.platform.database.MySQLPlatform" />
<property name="generateDdl" value="false" />
<property name="showSql" value="true" />
</bean>
<!-- Entity Manager Factory -->
<bean id="entityManagerFactory"
>
<property name="persistenceUnitName" value="SpringData"></property>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
</bean>
<!-- Transaction Manager -->
<bean id="transactionManager" >
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- Enable Transactional Manner -->
<tx:annotation-driven transaction-manager="transactionManager" />
</beans>
5. Spring Bean Service
Hier ist die Spring-Komponente, die zum Beibehalten eines Repository-Proxys verwendet wurde.
RegistrationService.java
package net.javabeat.springdata.beans;
import net.javabeat.springdata.repo.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class RegistrationService {
@Autowired
private EmployeeRepository employeeRepository;
public EmployeeRepository getEmployeeRepository() {
return employeeRepository;
}
public void setEmployeeRepository(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
}
6. Primefaces verwaltete Bohnen
Es handelt sich um die verwaltete Bean, die die Geschäftslogik für die Primefaces-Ansicht speichert.
RegistrationManagedBean.java
package net.javabeat.primefaces.managedbeans;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import net.javabeat.springdata.beans.RegistrationService;
import net.javabeat.springdata.jpa.data.Employee;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
@ManagedBean
@SessionScoped
public class RegistrationManagedBean {
private Employee employee = new Employee();
private List<Employee> employees = new ArrayList<Employee>();
private Page<Employee> page;
public RegistrationManagedBean(){
}
@PostConstruct
public void postInitialization(){
// Create & Initialize a Sort Object
Sort sort = new Sort(Direction.ASC,"employeeName");
// Create & Initialize a Page Object
page = this.service.getEmployeeRepository().findAll(new PageRequest(0, 3,sort));
// Fetch the employees from the page object
this.employees = page.getContent();
}
@ManagedProperty(value="#{registrationService}")
private RegistrationService service;
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public List<Employee> getEmployees() {
return employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public String nextEmployees(){
if(page.hasNextPage()){
this.page = this.service.getEmployeeRepository().findAll(page.nextPageable());
this.employees = page.getContent();
}
return "";
}
public String previousEmployees(){
if(page.hasPreviousPage()){
this.page = this.service.getEmployeeRepository().findAll(page.previousPageable());
this.employees = page.getContent();
}
return "";
}
public String sortByEmployeeName(){
if(page != null){
if(page.getSort() != null){
Sort sort= new Sort(Direction.ASC,"employeeName");
this.page = this.service.getEmployeeRepository().findAll(new PageRequest(this.page.getNumber(), this.page.getSize(), sort));
this.employees = this.page.getContent();
}
}
return "";
}
public String sortByEmployeeId(){
if(page != null){
if(page.getSort() != null){
Sort sort= new Sort(Direction.ASC,"employeeId");
this.page = this.service.getEmployeeRepository().findAll(new PageRequest(this.page.getNumber(), this.page.getSize(), sort));
this.employees = this.page.getContent();
}
}
return "";
}
public RegistrationService getService() {
return service;
}
public void setService(RegistrationService service) {
this.service = service;
}
public Page<Employee> getPage() {
return page;
}
public void setPage(Page<Employee> page) {
this.page = page;
}
public String register(){
this.service.getEmployeeRepository().save(this.employee);
this.employee = new Employee();
return "";
}
}
7. Faces-Konfigurationsdatei
Für die Herstellung der Frühlingsbohnen, auf die sich die von den Gesichtern verwalteten Bohnen beziehen, Ihr face-config.xml Sollte aussehen, wie
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
version="2.2">
<application>
<resource-bundle>
<base-name>net.javabeat.jsf.application</base-name>
<var>msg</var>
</resource-bundle>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
</faces-config>
8. Primefaces-Ansicht
Es ist die Primefaces-Ansichtsseite.
index.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<script name="jquery/jquery.js" library="primefaces"></script>
</h:head>
<f:view>
<h:form prependId="false">
<h2>JavaBeat Tutorials</h2>
<h2>Primefaces + Spring Data + PagingAndSortingRepository + MySQL</h2>
<div style="width: 700px;border: 1px;border-style: dotted;">
<h:panelGrid columns="2">
<h:outputText value="Enter Employee Name:"/>
<p:inputText value="#{registrationManagedBean.employee.employeeName}"></p:inputText>
<h:outputText value="Enter Employee Address Country:"/>
<p:inputText value="#{registrationManagedBean.employee.address.addressCountry}"></p:inputText>
<h:outputText value="Enter Employee Address City:"/>
<p:inputText value="#{registrationManagedBean.employee.address.addressCity}"></p:inputText>
</h:panelGrid>
<p:commandButton value="Register" action="#{registrationManagedBean.register}" ajax="false"/>
<p:separator/>
<h:panelGrid columns="1" width="100%">
<p:dataTable value="#{registrationManagedBean.employees}" var="employee" style="width:100%">
<p:column headerText="Employee's Name">
<h:outputText value="#{employee.employeeName}"/>
</p:column>
<p:column headerText="Employee's Country">
<h:outputText value="#{employee.address.addressCountry}"/>
</p:column>
<p:column headerText="Employee's City">
<h:outputText value="#{employee.address.addressCity}"/>
</p:column>
</p:dataTable>
<h:panelGrid columns="4" width="100%">
<p:commandButton value="Next Employees" action="#{registrationManagedBean.nextEmployees}" ajax="false"/>
<p:commandButton value="Previous Employees" action="#{registrationManagedBean.previousEmployees}" ajax="false"/>
<p:commandButton value="Sort By Employee Name" action="#{registrationManagedBean.sortByEmployeeName}" ajax="false"/>
<p:commandButton value="Sort By Employee Id" action="#{registrationManagedBean.sortByEmployeeId}" ajax="false"/>
</h:panelGrid>
</h:panelGrid>
</div>
</h:form>
</f:view>
</html>
9. Web-Bereitstellungsdeskriptor
Es handelt sich um den Bereitstellungsdeskriptor für diese Beispielanwendung.
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" metadata-complete="true" version="2.5">
<context-param>
<description>State saving method: 'client' or 'server'
(=default). See JSF Specification 2.5.2
</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<context-param>
<param-name>javax.faces.application.CONFIG_FILES</param-name>
<param-value>/WEB-INF/faces-config.xml</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-config/*.xml</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
</web-app>
10. Maven-Build-Datei
Dies ist die Maven-Build-Datei, die zum Erstellen dieser Anwendung verwendet wird.
pom.xml
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>next.javabeat.jsf</groupId>
<artifactId>JavaBeat-Primefaces-SpringData-PagingAndSortingRepository-MySQL</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.7</java.version>
<junit.version>4.9</junit.version>
<slf4j.version>1.6.4</slf4j.version>
<logback.version>1.0.1</logback.version>
<log4j.version>1.2.14</log4j.version>
<servlet.version>2.5</servlet.version>
<jsp.version>2.1</jsp.version>
<jstl.version>1.2</jstl.version>
<taglibs-standard.version>1.1.2</taglibs-standard.version>
<maven.compiler.plugin>2.3.2</maven.compiler.plugin>
<maven.failsafe.plugin>2.4.3-alpha-1</maven.failsafe.plugin>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>prime-repo</id>
<name>PrimeFaces Maven Repository</name>
<url>http://repository.primefaces.org</url>
<layout>default</layout>
</repository>
</repositories>
<dependencies>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<!-- Faces Implementation -->
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.2.4</version>
</dependency>
<!-- Faces Library -->
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.2.4</version>
</dependency>
<!-- Primefaces Version 5 -->
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>5.0.RC2</version>
</dependency>
<!-- JSP Library -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<!-- JSTL Library -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<!-- Spring Core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.3.RELEASE</version>
</dependency>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.0.3.RELEASE</version>
</dependency>
<!-- Google List Library -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>r09</version>
</dependency>
<!-- Dependencies for Eclipse JPA Persistence API -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.0-RC1</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.persistence</groupId>
<artifactId>commonj.sdo</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring Data Dependency -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.5.2.RELEASE</version>
</dependency> <!-- Dependency for MySql Java connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>
</dependencies>
</project>
11. PagingAndSortingRepository-Demo
Das hier implementierte Szenario enthält eine Reihe von Mitarbeitern, die paginiert werden könnten. Für jede einzelne Seite beträgt die Gesamtzahl der darin angezeigten Mitarbeiter drei. Der Benutzer hat die Möglichkeit, Mitarbeiter hinzuzufügen, siehe nächste Seite, siehe vorherige Seite und nach Mitarbeitername und Mitarbeiter-ID zu sortieren.
PagingAndSortingRepository – Die erste Ansicht
PagingAndSortingRepository – Die nächsten Mitarbeiter
PagingAndSortingRepository – Sortieren nach Mitarbeiter-ID
12. Zusammenfassung
Sie haben gerade eine Spring Data-Anwendung mit PagingAndSortingRepository entwickelt. Dieses Repository bietet Ihnen eine Paginierungsfunktion für Ihre Daten. Wenn Sie irgendwelche Fragen haben. Bitte schreiben Sie es in den Kommentarbereich.
Laden Sie den Quellcode herunter [JavaTipps](https://javatipps.de/)