Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement general pagination

Tags:

People also ask

How we can implement pagination?

Offset pagination is one of the simplest to implement. It's achieved using the limit and offset commands. Offset pagination is popular with apps powered by SQL databases, as limit and offset are already included with the SQL SELECT library. Offset pagination requires almost no programming.

What is pagination how it is implemented?

There are a lot of different ways to implement the pagination algorithm. Depending on the method used, both performance and the user experience will be affected. Pagination algorithms can be categorized generally into two types: database driven and application server or middleware driven.


I am not looking for a Hibernate/JPA/JDBC implementation, but for a general design pattern.

Googling "pagination" gives me loads of information, lot of interesting articles that explain how to implement pagination on the UI and various implementations which more or less do the same.

Since I am using Spring 3.0.5, and I stumbled this good reference article How to implement pagination in Spring MVC 3.

Simple bean:

public class Person{
     private String personName;
     private int age;
     // ...
}

A simple DAO interface:

public interface PersonDAO{
   Set<Person> getAllPersons(int start, int limit,String orderBy);
   Set<Person> findPersonsByName(String name, int start, int limit,String orderBy);
}

And the hibernate implementation

   @Repository
   public class PersonDAOImpl implements PersonDAO {

        @Autowired(required = true)
    private SessionFactory sessionFactory;

        public Set<Person> getAllPersons(int start, int limit, String orderBy){
                Criteria crit = sessionFactory.getCurrentSession().createCriteria(Person.class);
                crit.setFirstResult(start);
                crit.setMaxResults(limit);
                crit.addOrder(Order.asc("personName"));
                return new LinkedHashSet<Person>(crit.list());
        }


        public Set<Person> findPersonsByName(String name, int start, int limit, String orderBy){
                Criteria crit = sessionFactory.getCurrentSession().createCriteria(Person.class);
                crit.add(Restrictions.eq("name", name));
                crit.setFirstResult(start);
                crit.setMaxResults(limit);
                crit.addOrder(Order.asc(orderBy));
                return new LinkedHashSet<Person>(crit.list());
         }

Now, I am thinking if I have to include similar parameters across all the interface then there is something really wrong here. Either I can wrap the request in a request bean object and pass this bean to the methods, something like this

public class PersonRequest{
   private int start;
   private int limit;
   private String orderBy;
   private String name;
   // ...
}

And subsequently

public interface PersonDAO{
   Set<Person> getAllPersons(PersonRequest request);
   Set<Person> findPersonsByName(PersonRequest request);
}

But this too seems unnatural, for some reason. Then I am thinking of varargs in Java

public interface PersonDAO{
   Set<Person> getAllPersons(Object... params);
   Set<Person> findPersonsByName(String name,Object... params);
}


   @Repository
   public class PersonDAOImpl implements PersonDAO {

        @Autowired(required = true)
    private SessionFactory sessionFactory;



        public Set<Person> getAllPersons(Object... params){
                Criteria crit = sessionFactory.getCurrentSession().createCriteria(Person.class);
                crit.setFirstResult((Integer)params[0]);
                crit.setMaxResults((Integer)params[1]);
                crit.addOrder(Order.asc("personName"));
                return new LinkedHashSet<Person>(crit.list());
        }


        public Set<Person> findPersonsByName(String name, Object... params){
                Criteria crit = sessionFactory.getCurrentSession().createCriteria(Person.class);
                crit.add(Restrictions.eq("name", name));
                crit.setFirstResult((Integer)params[0]);
                crit.setMaxResults((Integer)params[1]);
                crit.addOrder(Order.asc((String)params[2]));
                return new LinkedHashSet<Person>(crit.list());
         }

This too seems bit flimsy, for some reason I keep thinking bridge pattern could be helpful but still is distant unfit.

Any idea how you would deal with this?