wake-up-neo.com

So implementieren Sie die Paginierung im Frühlingsboot mit Winterschlaf

Ich verwende Springboot mit Winterschlaf und möchte die Paginierung in meinem Projekt verwenden. Ich habe bei google gesucht und viele Beispiele gesehen, kann sie jedoch nicht in mein Projekt implementieren.

Ich möchte, wenn ich 1 in meiner URL übergebe, dann sollten 10 Ergebnisse kommen, und wenn ich 2 übergebe, sollten die nächsten 10 Ergebnisse kommen.

Hier ist mein Dao

@Transactional
public interface PostDao extends CrudRepository<Post, Long>{

@Query(getAllPostsByRank)
List<Post> getAllPostsByRank();

final String getAllPostsByRank= "from Post order by value DESC";
}

Hier ist mein Controller

@RequestMapping("/top")
    @ResponseBody 
     public List<Post> getAllPosts(HttpServletRequest req, HttpServletResponse res) throws ServletException {

List<Post> postobj = postDao.getAllPostsByRank();
return postobj;
}

Und hier ist meine url:

http://localhost:8888/v1.0/post/top/1

Bitte vorschlagen.

12
Nadeem Ahmed

Prüfen Sie. Ihr Controller

@RequestMapping("/top/pages/{pageno}")
    @ResponseBody 
     public List<Post> getAllPosts(@PathVariable("pageno") int pageno, HttpServletRequest req, HttpServletResponse res) throws ServletException {

List<Post> postobj = postDao.getAllPostsByRank(new PageRequest(pageno,10));
return postobj;
}

Dein Dao

@Transactional
public interface PostDao extends CrudRepository<Post, Long>{

@Query(getAllPostsByRank)
List<Post> getAllPostsByRank(Pageable pageable);

final String getAllPostsByRank= "from Post order by value DESC";
}
8
artle

Ich würde in Erwägung ziehen, org.springframework.data.domain.Pageable direkt in Ihrem Controller zu verwenden. Dieses Objekt kann dann an Ihre JPA-Ebene übergeben werden, wo es die Anzahl der zurückgegebenen Ergebnisse und die Größe verarbeitet. 

Das Tolle an der Verwendung von Pageable ist, dass ein Page-Objekt zurückgegeben wird, das im Frontend verwendet werden kann, um die Logik der vorherigen/nächsten Seite zu bilden. 

Standardmäßig verwendet diese Klasse die URL-Parameter ' page ' und ' size '; Daher gibt page = 0 & size = 10 die ersten 10 Elemente zurück.

In Ihrem Fall könnte der Code also ungefähr so ​​aussehen:

@ResponseBody
@RequestMapping("/top/pages/")
public List<Post> getAllPosts(@PageableDefault(value=10, page=0) Pageable pageable) throws ServletException {
    Page page = postDao.findAll(pageable);
    return page.getContent();
}

Beachten Sie, dass die Anmerkung @PageableDefault nur zum Einrichten der Standardwerte dient und nicht erforderlich ist.

Im Frontend kann der nächste Seitenaufruf <a href="/top/pages?page=1">Next</a> sein. Daraufhin wird eine Liste mit Beiträgen von 11 bis 20 angezeigt. 

15
Ithar

Das Implementieren der Paginierung in Spring Boot ist ziemlich einfach. Sie müssen lediglich die grundlegenden Schritte ausführen.

1 - Erweitert PagingAndSortingRepository in der Repository-Schnittstelle

public interface UserRepository extends PagingAndSortingRepository <User, Long> 

2 - Methodendeklaration sollte wie folgt aussehen

Page<User> userList(Pageable pageable);

3 - Die Implementierung der Methode in der Service-Klasse sollte wie folgt aussehen

@Override
public Page<User> userList(Pageable pageable) {
        return userRepository.findAll(pageable);
}

4 - Controller-Klassencode sollte wie folgt aussehen

@GetMapping("/list")
public String userList(Model model, Pageable pageable) {
        Page<User> pages = userService.userList(pageable);
        model.addAttribute("number", pages.getNumber());
        model.addAttribute("totalPages", pages.getTotalPages());
        model.addAttribute("totalElements",       
                                      pages.getTotalElements());
        model.addAttribute("size", pages.getSize());
        model.addAttribute("users", pages.getContent());
        return "/user/list";
}

Vom Frontend-Anruf sollte wie folgt sein

http://localhost:8080/application/user/list?page=0&size=5
http://localhost:8080/application/user/list?page=1&size=5
http://localhost:8080/application/user/list?page=2&size=5

Für weitere Details schauen Sie sich das Video unten an

Spring Boot: Pagination Basic

Spring Boot: Pagination Advanced

Danke fürs Lesen

7

So implementieren Sie dynamische Paginierung mithilfe einer systemeigenen Abfrage

Hier finden Sie die Repository- und Service-Layer sowie Ihr Data Transfer Object (DTO), mit denen unser Ergebnis abgebildet und an die Controller-Schicht gesendet wird.

public interface CustomSomethingRepository {
    List<Something> findPagedResultBySomethingElseId(long somethingElseId, int offset, int limit);
}

public class SomethingRepositoryImpl implements CustomSomethingRepository {
    @Autowired
    private EntityManager em;

    @SuppressWarnings("unchecked")
    @Override
    public List<Something> findPagedResultBySomethingElseId(long somethingElseId, int offset, int limit) {
        String query = "select s.* from Something s "
                + "join somethingelse selse on selse.id = s.fk_somethingelse "
                + "where selse.id = :somethingElseId "
                + "order by selse.date";
        Query nativeQuery = em.createNativeQuery(query);
        nativeQuery.setParameter("somethingElseId", somethingElseId);
        //Paginering
        nativeQuery.setFirstResult(offset);
        nativeQuery.setMaxResults(limit);
        final List<Object[]> resultList = nativeQuery.getResultList();
        List<Something> somethingList = Lists.newArrayList();
        resultList.forEach(object -> somethingList.add(//map obj to something));
        return somethingList;
    }
}

Hibernate übersetzt Ihre Anfrage wie folgt:

SELECT inner_query.*, ROW_NUMBER() OVER (ORDER BY CURRENT_TIMESTAMP) as __hibernate_row_nr__ FROM ( select TOP(?) t as page0_ from Something s join s.somethingelse as selse order by selse.date ) inner_query ) SELECT page0_ FROM query WHERE __hibernate_row_nr__ >= ? AND __hibernate_row_nr__ < ?


@Service
public class SomethingService {
    private SomethingRepository somethingRepository;
    @Autowired
    public SomethingService(SomethingRepository somethingRepository){
        this.somethingRepository = somethingRepository;
    }
    @Transactional(readOnly=true)
    public PageDto getSomething(long somethingElseId, int page, int size){
         List<Something> somethings = somethingRepository.findBySomethingElseId(somethingElseId, offset, limit);
        return new PagedResult<>(somethings
                .stream()
                .map(SomethingDto::createDto)
                .sorted(comparing(SomethingDto::getDatum))
                .collect(toList()), somethings.getTotalElements(), somethings.getTotalPages();
    }
}
@Controller
//....
public class PagedResult<T> {
    public static final long DEFAULT_OFFSET = 0;
    public static final int DEFAULT_MAX_NO_OF_ROWS = 100;
    private int offset;
    private int limit;
    private long totalElements;
    private List<T> elements;
    public PagedResult(List<T> elements, long totalElements, int offset, int limit) {
        this.elements = elements;
        this.totalElements = totalElements;
        this.offset = offset;
        this.limit = limit;
    }
    public boolean hasMore() {
        return totalElements > offset + limit;
    }
    public boolean hasPrevious() {
        return offset > 0 && totalElements > 0;
    }
    public long getTotalElements() {
        return totalElements;
    }
    public int  getOffset() {
        return offset;
    }
    public int getLimit() {
        return limit;
    }
    public List<T> getElements() {
        return elements;
    }
}

Vor- und Nachteile Vorteile : Im Vergleich zu Spring Data werden weniger SQL-Abfragen generiert. Diese komplexen Abfragen können nicht in Spring Data geschrieben werden, und wir müssen unsere Abfrage als native Abfrage angeben, die mit dieser Methode dennoch aufgerufen werden kann.

Cons : Das Array "object" muss einem Java-Objekt zugeordnet werden. Es ist schmerzhaft und schwer aufrechtzuerhalten.

So implementieren Sie OffsetLimit Pagination With Spring Data Soweit ich weiß, gibt es keine "Out-of-the-Box" -Unterstützung für das, was Sie in standardmäßigen Spring Data-Repositorys benötigen. Sie können jedoch eine benutzerdefinierte Implementierung von Pageable-Objekten erstellen, für die Grenzwert-/Versatzparameter verwendet werden.

Machen Sie ein auslagerbares Objekt und übergeben Sie es an PaginationAndSortingRepository:

public class OffsetLimitRequest implements Pageable {
    private int limit;
    private int offset;
    public OffsetLimitRequest(int offset, int limit){
        this.limit = limit;
        this.offset = offset;
    }
        @Override
    public int getPageNumber() {
        return 0;
    }
    @Override
    public int getPageSize() {
        return limit;
    }
    @Override
    public int getOffset() {
        return offset;
    }
    ....
}

Dies bedeutet, dass die Repository-Schicht nicht geändert werden muss. Die einzige Änderung, die Sie vornehmen müssen, ist die Serviceebene wie folgt:

@Service
public class SomethingService {
    private SomethingRepository somethingRepository;
    @Autowired
    public SomethingService(SomethingRepository somethingRepository){
        this.somethingRepository = somethingRepository;
    }
    @Transactional(readOnly=true)
    public PageDto getSomething(long somethingElseId, int page, int size){
        Page<Something> somethings = somethingRepository.findBySomethingElseId(somethingElseId, new OffsetLimitRequest(offset, limit));
        return new PageDto(somethings.getContent()
                .stream()
                .map(SomethingDto::createDto)
                .sorted(comparing(SomethingDto::getDatum))
                .collect(toList()), somethings.getTotalElements(), somethings.getTotalPages();
    }
}

Beachten Sie, dass Sie das Ergebnis nicht manuell abbilden müssen, und die Entwicklung nimmt viel Zeit in Anspruch.