Add pagination for owners and vets lists in HTML

Fixes #91
This commit is contained in:
simrin051 2021-09-13 20:11:55 +05:30 committed by Dave Syer
parent 25ba1621a9
commit 8ad9c05f74
27 changed files with 323 additions and 192 deletions

View file

@ -15,12 +15,11 @@
*/
package org.springframework.samples.petclinic.model;
import java.io.Serializable;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import java.io.Serializable;
/**
* Simple JavaBean domain object with an id property. Used as a base class for objects

View file

@ -24,6 +24,7 @@ import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.Digits;
@ -59,7 +60,7 @@ public class Owner extends Person {
@Digits(fraction = 0, integer = 10)
private String telephone;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch = FetchType.EAGER)
private Set<Pet> pets;
public String getAddress() {

View file

@ -15,6 +15,14 @@
*/
package org.springframework.samples.petclinic.owner;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.samples.petclinic.visit.VisitRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@ -24,12 +32,9 @@ import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import javax.validation.Valid;
import java.util.Collection;
import java.util.Map;
/**
* @author Juergen Hoeller
* @author Ken Krebs
@ -43,7 +48,7 @@ class OwnerController {
private final OwnerRepository owners;
private VisitRepository visits;
private final VisitRepository visits;
public OwnerController(OwnerRepository clinicService, VisitRepository visits) {
this.owners = clinicService;
@ -80,7 +85,8 @@ class OwnerController {
}
@GetMapping("/owners")
public String processFindForm(Owner owner, BindingResult result, Map<String, Object> model) {
public String processFindForm(@RequestParam(defaultValue = "1") int page, Owner owner, BindingResult result,
Model model) {
// allow parameterless GET request for /owners to return all records
if (owner.getLastName() == null) {
@ -88,24 +94,43 @@ class OwnerController {
}
// find owners by last name
Collection<Owner> results = this.owners.findByLastName(owner.getLastName());
if (results.isEmpty()) {
String lastName = owner.getLastName();
Page<Owner> ownersResults = findPaginatedForOwnersLastName(page, lastName);
if (ownersResults.isEmpty()) {
// no owners found
result.rejectValue("lastName", "notFound", "not found");
return "owners/findOwners";
}
else if (results.size() == 1) {
else if (ownersResults.getTotalElements() == 1) {
// 1 owner found
owner = results.iterator().next();
owner = ownersResults.iterator().next();
return "redirect:/owners/" + owner.getId();
}
else {
// multiple owners found
model.put("selections", results);
return "owners/ownersList";
lastName = owner.getLastName();
return addPaginationModel(page, model, lastName, ownersResults);
}
}
private String addPaginationModel(int page, Model model, String lastName, Page<Owner> paginated) {
model.addAttribute("listOwners", paginated);
List<Owner> listOwners = paginated.getContent();
model.addAttribute("currentPage", page);
model.addAttribute("totalPages", paginated.getTotalPages());
model.addAttribute("totalItems", paginated.getTotalElements());
model.addAttribute("listOwners", listOwners);
return "owners/ownersList";
}
private Page<Owner> findPaginatedForOwnersLastName(int page, String lastname) {
int pageSize = 5;
Pageable pageable = PageRequest.of(page - 1, pageSize);
return owners.findByLastName(lastname, pageable);
}
@GetMapping("/owners/{ownerId}/edit")
public String initUpdateOwnerForm(@PathVariable("ownerId") int ownerId, Model model) {
Owner owner = this.owners.findById(ownerId);

View file

@ -15,8 +15,8 @@
*/
package org.springframework.samples.petclinic.owner;
import java.util.Collection;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.query.Param;
@ -42,9 +42,10 @@ public interface OwnerRepository extends Repository<Owner, Integer> {
* @return a Collection of matching {@link Owner}s (or an empty Collection if none
* found)
*/
@Query("SELECT DISTINCT owner FROM Owner owner left join fetch owner.pets WHERE owner.lastName LIKE :lastName%")
@Query("SELECT DISTINCT owner FROM Owner owner left join owner.pets WHERE owner.lastName LIKE :lastName% ")
@Transactional(readOnly = true)
Collection<Owner> findByLastName(@Param("lastName") String lastName);
Page<Owner> findByLastName(@Param("lastName") String lastName, Pageable pageable);
/**
* Retrieve an {@link Owner} from the data store by id.
@ -61,4 +62,11 @@ public interface OwnerRepository extends Repository<Owner, Integer> {
*/
void save(Owner owner);
/**
* Returnes all the owners from data store
**/
@Query("SELECT owner FROM Owner owner")
@Transactional(readOnly = true)
Page<Owner> findAll(Pageable pageable);
}

View file

@ -15,12 +15,12 @@
*/
package org.springframework.samples.petclinic.owner;
import java.util.List;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* Repository class for <code>Pet</code> domain objects All method names are compliant
* with Spring Data naming conventions so this interface can easily be extended for Spring

View file

@ -15,11 +15,11 @@
*/
package org.springframework.samples.petclinic.owner;
import org.springframework.samples.petclinic.model.NamedEntity;
import javax.persistence.Entity;
import javax.persistence.Table;
import org.springframework.samples.petclinic.model.NamedEntity;
/**
* @author Juergen Hoeller Can be Cat, Dog, Hamster...
*/

View file

@ -15,14 +15,14 @@
*/
package org.springframework.samples.petclinic.owner;
import java.text.ParseException;
import java.util.Collection;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.Formatter;
import org.springframework.stereotype.Component;
import java.text.ParseException;
import java.util.Collection;
import java.util.Locale;
/**
* Instructs Spring MVC on how to parse and print elements of type 'PetType'. Starting
* from Spring 3.0, Formatters have come as an improvement in comparison to legacy

View file

@ -15,20 +15,15 @@
*/
package org.springframework.samples.petclinic.owner;
import java.util.Map;
import javax.validation.Valid;
import org.springframework.samples.petclinic.visit.Visit;
import org.springframework.samples.petclinic.visit.VisitRepository;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Map;
/**
* @author Juergen Hoeller

View file

@ -16,13 +16,13 @@
package org.springframework.samples.petclinic.system;
import javax.cache.configuration.MutableConfiguration;
import org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.cache.configuration.MutableConfiguration;
/**
* Cache configuration intended for caches providing the JCache API. This configuration
* creates the used cache for the application and enables statistics that become

View file

@ -15,12 +15,11 @@
*/
package org.springframework.samples.petclinic.vet;
import java.io.Serializable;
import org.springframework.samples.petclinic.model.NamedEntity;
import javax.persistence.Entity;
import javax.persistence.Table;
import org.springframework.samples.petclinic.model.NamedEntity;
import java.io.Serializable;
/**
* Models a {@link Vet Vet's} specialty (for example, dentistry).

View file

@ -15,24 +15,14 @@
*/
package org.springframework.samples.petclinic.vet;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlElement;
import org.springframework.beans.support.MutableSortDefinition;
import org.springframework.beans.support.PropertyComparator;
import org.springframework.samples.petclinic.model.Person;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlElement;
import java.util.*;
/**
* Simple JavaBean domain object representing a veterinarian.
*

View file

@ -15,11 +15,17 @@
*/
package org.springframework.samples.petclinic.vet;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;
import java.util.List;
/**
* @author Juergen Hoeller
@ -37,15 +43,31 @@ class VetController {
}
@GetMapping("/vets.html")
public String showVetList(Map<String, Object> model) {
public String showVetList(@RequestParam(defaultValue = "1") int page, Model model) {
// Here we are returning an object of type 'Vets' rather than a collection of Vet
// objects so it is simpler for Object-Xml mapping
Vets vets = new Vets();
vets.getVetList().addAll(this.vets.findAll());
model.put("vets", vets);
Page<Vet> paginated = findPaginated(page);
vets.getVetList().addAll(paginated.toList());
return addPaginationModel(page, paginated, model);
}
private String addPaginationModel(int page, Page<Vet> paginated, Model model) {
List<Vet> listVets = paginated.getContent();
model.addAttribute("currentPage", page);
model.addAttribute("totalPages", paginated.getTotalPages());
model.addAttribute("totalItems", paginated.getTotalElements());
model.addAttribute("listVets", listVets);
return "vets/vetList";
}
private Page<Vet> findPaginated(int page) {
int pageSize = 5;
Pageable pageable = PageRequest.of(page - 1, pageSize);
return vets.findAll(pageable);
}
@GetMapping({ "/vets" })
public @ResponseBody Vets showResourcesVetList() {
// Here we are returning an object of type 'Vets' rather than a collection of Vet

View file

@ -15,13 +15,15 @@
*/
package org.springframework.samples.petclinic.vet;
import java.util.Collection;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.dao.DataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
/**
* Repository class for <code>Vet</code> domain objects All method names are compliant
* with Spring Data naming conventions so this interface can easily be extended for Spring
@ -43,4 +45,16 @@ public interface VetRepository extends Repository<Vet, Integer> {
@Cacheable("vets")
Collection<Vet> findAll() throws DataAccessException;
/**
* Retrieve all <code>Vet</code>s from data store in Pages
* @param pageable
* @return
* @throws DataAccessException
*/
@Transactional(readOnly = true)
@Cacheable("vets")
Page<Vet> findAll(Pageable pageable) throws DataAccessException;
;
}

View file

@ -15,11 +15,10 @@
*/
package org.springframework.samples.petclinic.vet;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.ArrayList;
import java.util.List;
/**
* Simple domain object representing a list of veterinarians. Mostly here to be used for

View file

@ -15,15 +15,14 @@
*/
package org.springframework.samples.petclinic.visit;
import java.time.LocalDate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.samples.petclinic.model.BaseEntity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.samples.petclinic.model.BaseEntity;
import java.time.LocalDate;
/**
* Simple JavaBean domain object representing a visit.

View file

@ -15,12 +15,12 @@
*/
package org.springframework.samples.petclinic.visit;
import java.util.List;
import org.springframework.dao.DataAccessException;
import org.springframework.data.repository.Repository;
import org.springframework.samples.petclinic.model.BaseEntity;
import java.util.List;
/**
* Repository class for <code>Visit</code> domain objects All method names are compliant
* with Spring Data naming conventions so this interface can easily be extended for Spring