[JAVA] Implementieren Sie die Paging-Funktion mit Spring Boot + Thymeleaf

Mit Spring Boot + Thymeleaf können Sie problemlos Paging-Funktionen für Bildschirme implementieren. Bildschirmbild nach Abschluss スクリーンショット 2017-01-21 23.25.18.png

Überprüfungsumgebung

Implementierung

Erstens ist die Domänenschicht.

@Entity
@Table(name="word_info")
public class Word implements Serializable {

	private static final long serialVersionUID = -870708489937857961L;
	
	@Id
	@GeneratedValue(strategy=GenerationType.TABLE, generator="seqTable")
	@TableGenerator(name="seqTable", table="seq_table", pkColumnName="seq_name", pkColumnValue="word_seq", valueColumnName="seq_value")
	@Column(name="id")
	private Long id;
	
	@Column(name="word")
	private String word;
	
	@Column(name="meaning")
	private String meaning;
	
	@Column(name="example")
	private String example;

	//get / set weggelassen
	...
}

Definieren Sie eine JPA-Repository-Klasse, um die Liste abzurufen. Verwenden Sie die Page-Klasse anstelle von List.

@Repository
public interface WordRepository extends CrudRepository<Word, Long>{
	
	public Page<Word> findAll(Pageable pageable);

}

Als nächstes folgt die Service-Schicht.

@Service
public class WordService {
	
	@Autowired
	private WordRepository wordRepo;
	
	public Page<Word> getAllWord(Pageable pageable) {

		return wordRepo.findAll(pageable);
	}

}

Präsentationsfolie.

@Controller
public class MainController {
	
	@Autowired
	private WordService wordService;
	
	@RequestMapping(value="/word/wordList", method=RequestMethod.GET)
	public String getWordList(Model model, Pageable pageable) {
		Page<Word> wordsPage = wordService.getAllWord(pageable);
		model.addAttribute("page", wordsPage);
		model.addAttribute("words", wordsPage.getContent());
		model.addAttribute("url", "/word/wordList");
		
		return "/word/wordList";
	}
}

Festlegen der Anzahl der anzuzeigenden Elemente

Legen Sie die maximale Anzahl von Elementen fest, die für jede Seite angezeigt werden sollen.

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

  @Override
  public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
      PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
      //Anzahl der Elemente, die pro Seite angezeigt werden sollen
      resolver.setFallbackPageable(new PageRequest(0, 5));
      argumentResolvers.add(resolver);
      super.addArgumentResolvers(argumentResolvers);
  }

}

Schließlich die Umsetzung auf der Thymeleaf-Seite.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
	  xmlns:th="http://www.thymeleaf.org">
	<head>
		<meta charset="UTF-8" />
		<link th:substituteby="common/header :: common_header"/>
		<title>Word List</title>
	</head>
	<body>
		<table border="1">
			<tr>
				<th>ID</th>
				<th>WORD</th>
				<th>MEANING</th>
				<th>EXAMPLE</th>
			</tr>
			<tr th:each="word:${words}">
				<td th:text="${word.id}"></td>
				<td th:text="${word.word}"></td>
				<td th:text="${word.meaning}"></td>
				<td th:text="${word.example}"></td>
			</tr>
		</table>
		
		<div th:fragment='paginationbar'>
			<ul>
				<li th:class="${page.first} ? 'disabled':''" style="display:inline">
					<span th:if="${page.first}">← Zuerst</span>
					<a th:if="${not page.first}" th:href="@{${url}(page=0)}">← Zuerst</a>
				</li>
				<li th:each='i : ${#numbers.sequence(0, page.totalPages-1)}' th:class="(${i}==${page.number})? 'active' : ''" style="display:inline">
                	<span th:if='${i}==${page.number}' th:text='${i+1}'>1</span>
               	 	<a th:if='${i}!=${page.number}' th:href="@{${url}(page=${i})}">
               	 		<span th:text='${i+1}'>1</span>
               	 	</a>
                </li>
				<li th:class="${page.last} ? 'disabled':''" style="display:inline">
					<span th:if="${page.last}">Ende ➝</span>
					<a th:if="${not page.last}" th:href="@{${url}(page=(${page.totalPages}-1))}">Ende ➝</a>
				</li>
			</ul>
		</div>
	</body>
</html>

Anpassen

Wenn Sie in dem Fall mit einer großen Anzahl von Seiten, wie unten gezeigt, nur einige Seitenzahlen anzeigen möchten, können Sie eine Wrapper-Klasse für Page erstellen und anpassen. 2017-12-08_092643.jpg

Implementierung der Wrapper-Klasse

public class PageWrapper<T> {
    public static final int MAX_PAGE_ITEM_DISPLAY = 5;
    private Page<T> page;
    private List<PageItem> items;
    private int currentNumber;
    private String url;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public PageWrapper(Page<T> page, String url){
        this.page = page;
        this.url = url;
        items = new ArrayList<PageItem>();

        currentNumber = page.getNumber() + 1;

        int start, size;
        if (page.getTotalPages() <= MAX_PAGE_ITEM_DISPLAY){
            start = 1;
            size = page.getTotalPages();
        } else {
            if (currentNumber <= MAX_PAGE_ITEM_DISPLAY - MAX_PAGE_ITEM_DISPLAY/2){
                start = 1;
                size = MAX_PAGE_ITEM_DISPLAY;
            } else if (currentNumber >= page.getTotalPages() - MAX_PAGE_ITEM_DISPLAY/2){
                start = page.getTotalPages() - MAX_PAGE_ITEM_DISPLAY + 1;
                size = MAX_PAGE_ITEM_DISPLAY;
            } else {
                start = currentNumber - MAX_PAGE_ITEM_DISPLAY/2;
                size = MAX_PAGE_ITEM_DISPLAY;
            }
        }

        for (int i = 0; i<size; i++){
            items.add(new PageItem(start+i, (start+i)==currentNumber));
        }
    }

    public List<PageItem> getItems(){
        return items;
    }

    public int getNumber(){
        return currentNumber;
    }

    public List<T> getContent(){
        return page.getContent();
    }

    public int getSize(){
        return page.getSize();
    }

    public int getTotalPages(){
        return page.getTotalPages();
    }

    public boolean isFirstPage(){
        return page.isFirst();
    }

    public boolean isLastPage(){
        return page.isLast();
    }

    public boolean isHasPreviousPage(){
        return page.hasPrevious();
    }

    public boolean isHasNextPage(){
        return page.hasNext();
    }

    public class PageItem {
        private int number;
        private boolean current;
        public PageItem(int number, boolean current){
            this.number = number;
            this.current = current;
        }

        public int getNumber(){
            return this.number;
        }

        public boolean isCurrent(){
            return this.current;
        }
    }
}

Kontrollklassenwechsel

Verwenden Sie eine Wrapper-Klasse anstelle von Page.

@Controller
public class MainController {
	
	@Autowired
	private WordService wordService;

	@RequestMapping("/word/register")
	public String wordRegister(WordForm wordForm) {
		wordService.addWord(wordForm);
		return "/word/wordRegister";
	}
	
	@RequestMapping(value="/word/wordList", method=RequestMethod.GET)
	public String getWordList(Model model, Pageable pageable) {
		Page<Word> wordPage = wordService.getAllWord(pageable);
		PageWrapper<Word> page = new PageWrapper<Word>(wordPage, "/word/wordList");
		model.addAttribute("page", page);
		model.addAttribute("words", page.getContent());
		
		return "/word/wordList";
	}
}

Thymeleaf

Ändern Sie den Paging-Teil wie folgt.

	...

		<div th:fragment='paginationbar'>
			<ul class='pagination pagination-centered'>
				<li th:class="${page.firstPage}?'disabled':''" style="display:inline">
					<span th:if='${page.firstPage}'>← Zuerst</span>
					<a th:if='${not page.firstPage}' th:href='@{${page.url}(page=0,size=${page.size})}'>← Zuerst</a>
				</li>
				<li th:class="${page.hasPreviousPage}? '' : 'disabled'" style="display:inline">
					<span th:if='${not page.hasPreviousPage}'>«</span>
					<a th:if='${page.hasPreviousPage}' th:href='@{${page.url}(page=${page.number-2},size=${page.size})}'>«</a>
				</li>
	                
	                
				<li th:each='item : ${page.items}' th:class="${item.current}? 'active' : ''" style="display:inline">
					<span th:if='${item.current}' th:text='${item.number}'>1</span>
					<a th:if='${not item.current}' th:href='@{${page.url}(page=${item.number-1},size=${page.size})}'>
					<span th:text='${item.number}'>1</span>
					</a>
				</li>
				<li th:class="${page.hasNextPage}? '' : 'disabled'" style="display:inline">
					<span th:if='${not page.hasNextPage}'>»</span>
					<a th:if='${page.hasNextPage}' th:href='@{${page.url}(page=${page.number},size=${page.size})}'>»</a>
				</li>
				<li th:class="${page.lastPage}? 'disabled' : ''" style="display:inline">
					<span th:if='${page.lastPage}'>Ende ➝</span>
					<a th:if='${not page.lastPage}' th:href='@{${page.url}(page=${page.totalPages - 1},size=${page.size})}'>Ende ➝</a>
				</li>
			</ul>
		</div>
	...

Referenz: https://github.com/mtiger2k/pageableSpringBootDataJPA

Recommended Posts

Implementieren Sie die Paging-Funktion mit Spring Boot + Thymeleaf
Implementieren Sie CRUD mit Spring Boot + Thymeleaf + MySQL
Implementieren Sie GraphQL mit Spring Boot
Versuchen Sie, die Anmeldefunktion mit Spring Boot zu implementieren
Führen Sie die WEB-Anwendung mit Spring Boot + Thymeleaf aus
Mit Spring Boot herunterladen
Erstellen Sie eine CRUD-App mit Spring Boot 2 + Thymeleaf + MyBatis
Erstellen Sie Ihr eigenes Dienstprogramm mit Thymeleaf mit Spring Boot
[Einführung in Spring Boot] Authentifizierungsfunktion mit Spring Security
Generieren Sie mit Spring Boot einen Barcode
Hallo Welt mit Spring Boot
Beginnen Sie mit Spring Boot
Hallo Welt mit Spring Boot!
Führen Sie LIFF mit Spring Boot aus
SNS-Login mit Spring Boot
Implementieren Sie eine einfache Rest-API mit Spring Security mit Spring Boot 2.0
[Java] Thymeleaf Basic (Spring Boot)
Datei-Upload mit Spring Boot
Spring Boot beginnt mit dem Kopieren
Anmeldefunktion mit Spring Security
Spring Boot beginnend mit Docker
Hallo Welt mit Spring Boot
Setzen Sie Cookies mit Spring Boot
[Spring Boot] Einfaches Rezept für den Paging-Prozess
Verwenden Sie Spring JDBC mit Spring Boot
Modul mit Spring Boot hinzufügen
Erste Schritte mit Spring Boot
Erstellen Sie mit Spring Boot einen Mikrodienst
Mail mit Spring Boot verschicken
Behandeln Sie die Java 8-Datums- und Uhrzeit-API mit Thymeleaf mit Spring Boot
Implementieren Sie die REST-API mit Spring Boot und JPA (Application Layer).
Implementieren Sie die REST-API mit Spring Boot und JPA (Infrastructure Layer).
Bis INSERT und SELECT für Postgres mit Spring Boot und Thymianblatt
Verwenden Sie thymeleaf3 mit parent, ohne Spring-Boot-Starter-Parent in Spring Boot anzugeben
Implementieren Sie die REST-API mit Spring Boot und JPA (Domain Layer Edition).
Implementieren Sie eine einfache Rest-API mit Spring Security & JWT mit Spring Boot 2.0
Verwenden Sie die Standardauthentifizierung mit Spring Boot
Implementierte Authentifizierungsfunktion mit Spring Security ②
Implementieren Sie einen Textlink mit Springboot + Thymeleaf
gRPC auf Spring Boot mit grpc-spring-boot-Starter
Implementierte Authentifizierungsfunktion mit Spring Security ③
Erstellen Sie eine App mit Spring Boot 2
Hot Deploy mit Spring Boot-Entwicklung
Datenbankverknüpfung mit doma2 (Spring Boot)
Spring Boot Programmierung mit VS Code
Bis "Hallo Welt" mit Spring Boot
Erstellen Sie eine Anfrage-App mit Spring Boot
Implementierte Authentifizierungsfunktion mit Spring Security ①
Erhalten Sie Validierungsergebnisse mit Spring Boot
Implementieren Sie den Dateidownload mit Spring MVC
(Intellij) Hallo Welt mit Spring Boot
Erstellen Sie eine App mit Spring Boot
Implementieren Sie die REST-API mit Spring Boot
Spring-Profilfunktion und Spring Boot application.properties
Google Cloud Platform mit Spring Boot 2.0.0
Ich habe GraphQL mit Spring Boot ausprobiert
[Java] LINE-Integration mit Spring Boot
Beginnend mit Spring Boot 0. Verwenden Sie Spring CLI
Ich habe Flyway mit Spring Boot ausprobiert