Showing posts with label Pagination. Show all posts
Showing posts with label Pagination. Show all posts

Points To Remember



Pagination in Spring Hibernate Application using Bootstrap


  • Create a Domain Person.
  • Create a Service PersonService
  • Create a Dao PersonDao.
  • Create a Controller PersonController.
  • Create a Taglib PaginationTaglib.

Person.java
package com.ekiras.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="person")
public class Person {

public Person(){};
public Person(String name,Integer age){
this.name = name;
this.age = age;
}


@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="id")
private Long id;

@Column(name="name")
private String name;

@Column(name="age")
private Integer age;

// GETTERS and SETTERS

PersonService.java
package com.ekiras.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ekiras.dao.PersonDAO;
import com.ekiras.domain.Person;

@Service
public class PersonService {

@Autowired
private PersonDAO personDAO;


public List<Person> list(Integer offset, Integer maxResults){
return personDAO.list(offset, maxResults);
}

public Long count(){
return personDAO.count();
}

public void save(){
personDAO.save();
}

}

PersonDAO.java
package com.ekiras.dao;

import java.util.List;

import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.ekiras.domain.Person;

@Repository
@Transactional
public class PersonDAO {

@Autowired
private SessionFactory sessionFactory;

@SuppressWarnings("unchecked")
@Transactional
public List<Person> list(Integer offset, Integer maxResults){
return sessionFactory.openSession()
.createCriteria(Person.class)
.setFirstResult(offset!=null?offset:0)
.setMaxResults(maxResults!=null?maxResults:10)
.list();
}


public Long count(){
return (Long)sessionFactory.openSession()
.createCriteria(Person.class)
.setProjection(Projections.rowCount())
.uniqueResult();
}


public void save(){
for(int itr=1;itr <= 100 ; itr++){
Person person = new Person("Person_"+itr,Math.max(25, (itr%2)*35));
sessionFactory.openSession()
.save(person);
}



}

}

PersonController.java
package com.ekiras.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.ekiras.service.PersonService;

@Controller
@RequestMapping(value="/person")
public class PersonController {

@Autowired
private PersonService personService;

@RequestMapping(value="/list")
public String list(Model model, Integer offset, Integer maxResults){
model.addAttribute("persons", personService.list(offset, maxResults));
model.addAttribute("count", personService.count());
model.addAttribute("offset", offset);
return "/person/list";
}

@RequestMapping(value="/save")
public String save(){
personService.save();
return "/person/list";
}

}

PaginationTaglib.java
package com.ekiras.taglib;

import java.io.Writer;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class PaginationTaglib extends SimpleTagSupport {
private String uri;
private int offset;
private int count;
private int max = 10;
private int steps = 10;
private String previous = "Previous";
private String next = "Next";

private Writer getWriter() {
JspWriter out = getJspContext().getOut();
return out;
}

@Override
public void doTag() throws JspException {
Writer out = getWriter();

try {
out.write("<nav>");
out.write("<ul class=\"pagination\">");

if(offset<steps)
out.write(constructLink(1, previous, "disabled", true));
else
out.write(constructLink(offset-steps, previous, null, false));

for(int itr=0;itr<count;itr+=steps) {
if(offset==itr)
out.write(constructLink((itr/10+1)-1 *steps, String.valueOf(itr/10+1), "active", true));
else
out.write(constructLink(itr/10*steps, String.valueOf(itr/10+1), null , false));
}

if(offset+steps>=count)
out.write(constructLink(offset+steps, next, "disabled", true));
else
out.write(constructLink(offset+steps, next, null , false));


out.write("</ul>");
out.write("</nav>");
} catch (java.io.IOException ex) {
throw new JspException("Error in Paginator tag", ex);
}
}


private String constructLink(int page, String text, String className, boolean disabled) {
StringBuilder link = new StringBuilder("<li");
if (className != null) {
link.append(" class=\"");
link.append(className);
link.append("\"");
}
if(disabled)
link.append(">").append("<a href=\"#\">"+text+"</a></li>");
else
link.append(">").append("<a href=\""+uri+"?offset="+page + "\">"+text+"</a></li>");
return link.toString();
}

public String getUri() {
return uri;
}

public void setUri(String uri) {
this.uri = uri;
}

public int getOffset() {
return offset;
}

public void setOffset(int offset) {
this.offset = offset;
}

public int getCount() {
return count;
}

public void setCount(int count) {
this.count = count;
}

public int getMax() {
return max;
}

public void setMax(int max) {
this.max = max;
}

public String getPrevious() {
return previous;
}

public void setPrevious(String previous) {
this.previous = previous;
}

public String getNext() {
return next;
}

public void setNext(String next) {
this.next = next;
}

public int getSteps() {
return steps;
}

public void setSteps(int steps) {
this.steps = steps;
}

}

list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="tag" uri="/WEB-INF/taglibs/customTaglib.tld"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="/css/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="/css/font-awesome.min.css" />
<title>| Ekiras</title>
</head>
<body>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span> <span
class="icon-bar"></span> <span class="icon-bar"></span> <span
class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>

<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse"
id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li class="dropdown"><a href="#" class="dropdown-toggle"
data-toggle="dropdown" role="button" aria-expanded="false">Dropdown
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
<li class="divider"></li>
<li><a href="#">One more separated link</a></li>
</ul></li>
</ul>
<form class="navbar-form navbar-left" role="search">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Link</a></li>
<li class="dropdown"><a href="#" class="dropdown-toggle"
data-toggle="dropdown" role="button" aria-expanded="false">Dropdown
<span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul></li>
</ul>
</div>
<!-- /.navbar-collapse -->
</div>
<!-- /.container-fluid --> </nav>

<div class="container">
<div class="well">
<strong>List of Persons</strong>
</div>
<table class="table table-stripped">
<tr>
<th>S.No</th>
<th>Name</th>
<th>Age</th>
</tr>
<c:forEach items="${persons}" var="person" varStatus="itr">
<tr>
<td>${offset + itr.index +1 }</td>
<td>${person.name }</td>
<td>${person.age }</td>
</tr>
</c:forEach>
</table>
<tag:paginate max="15" offset="${offset}" count="${count}"
uri="/person/list" next="&raquo;" previous="&laquo;" />
</div>


<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/bootstrap.min.js"></script>
</body>
</html>

This is how you can do pagination using bootstrap style in spring hibernate mvc application.


Points To Remember


  • Offset may be required to do pagination or get the results after a particular result from the database.
  • Using offset you can define the first result to be included in the result set from the database. 
  • You can use setFirstResult on the CriteriaQuery to set the first result that you want.

Using offset to get the results

SampleDAO.java
@SuppressWarnings("unchecked")
public List<Person> getCategories(Integer offset){
return getSession()
.createCriteria(Person.class)
.setFirstResult(offset!=null?offset:0)
.setMaxResults(10)
.list();
}
This is how you can set the first result you want to fetch from the database. In this example we have set the first result and the maximum number of records that we need to fetch.

Points To Remember

Bootstrap is one of the major UI componnet used worldwide, So you may want to implemnt pagination using bootstrap in java , j2ee or spring application. So all you need to do is

  1. Create a Class that will behave like a taglib.
  2. Create a Tld file that will map the tablib class with the jsp's.
  3. Use the taglib on jsp using the tld file.

Create Pagination Taglib for Jsp with Bootstrap.

Following is an example of the a custom taglib built for Bootstrap. This taglib takes in

  • uri -> action to be hit when clicked.
  • offset -> the offset of pagination.
  • count -> total number of elements to be shown.
  • max -> maximum number of pages to be shown in the pagination bar.
  • steps -> maximum number of elements to be shown per page.
  • previous -> text to be shown for previous page link.
  • next -> text to be shown for next page link.

PaginationTaglib.java
This is a java class that will behave like a taglib on jsp's.
package com.ekiras.taglib;

import java.io.Writer;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class PaginationTaglib extends SimpleTagSupport {
private String uri;
private int offset;
private int count;
private int max = 10;
private int steps = 10;
private String previous = "Previous";
private String next = "Next";

private Writer getWriter() {
JspWriter out = getJspContext().getOut();
return out;
}

@Override
public void doTag() throws JspException {
Writer out = getWriter();

try {
out.write("<nav>");
out.write("<ul class=\"pagination\">");

if(offset<steps)
out.write(constructLink(1, previous, "disabled", true));
else
out.write(constructLink(offset-steps, previous, null, false));

for(int itr=0;itr<count;itr+=steps) {
if(offset==itr)
out.write(constructLink((itr/10+1)-1 *steps, String.valueOf(itr/10+1), "active", true));
else
out.write(constructLink(itr/10*steps, String.valueOf(itr/10+1), null , false));
}

if(offset+steps>count)
out.write(constructLink(offset+steps, next, "disabled", true));
else
out.write(constructLink(offset+steps, next, null , false));


out.write("</ul>");
out.write("</nav>");
} catch (java.io.IOException ex) {
throw new JspException("Error in Paginator tag", ex);
}
}


private String constructLink(int page, String text, String className, boolean disabled) {
StringBuilder link = new StringBuilder("<li");
if (className != null) {
link.append(" class=\"");
link.append(className);
link.append("\"");
}
if(disabled)
link.append(">").append("<a href=\"#\">"+text+"</a></li>");
else
link.append(">").append("<a href=\""+uri+"?offset="+page + "\">"+text+"</a></li>");
return link.toString();
}

public String getUri() {
return uri;
}

public void setUri(String uri) {
this.uri = uri;
}

public int getOffset() {
return offset;
}

public void setOffset(int offset) {
this.offset = offset;
}

public int getCount() {
return count;
}

public void setCount(int count) {
this.count = count;
}

public int getMax() {
return max;
}

public void setMax(int max) {
this.max = max;
}

public String getPrevious() {
return previous;
}

public void setPrevious(String previous) {
this.previous = previous;
}

public String getNext() {
return next;
}

public void setNext(String next) {
this.next = next;
}

public int getSteps() {
return steps;
}

public void setSteps(int steps) {
this.steps = steps;
}

}

customTaglib.tld
This is the .tld file that defines how to use the java class as a taglib in jsp's
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
<tlib-version>1.0</tlib-version>
<short-name>paginator</short-name>
<uri>/WEB-INF/taglibs/customTaglib.tld</uri>

<tag>
<name>paginate</name>
<tag-class>com.ekiras.taglib.PaginationTaglib</tag-class>
<body-content>empty</body-content>

<attribute>
<name>next</name>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
</attribute>
<attribute>
<name>previous</name>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
</attribute>
<attribute>
<name>uri</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
</attribute>
<attribute>
<name>offset</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>int</type>
</attribute>
<attribute>
<name>count</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>int</type>
</attribute>
<attribute>
<name>max</name>
<rtexprvalue>true</rtexprvalue>
<type>int</type>
</attribute>
</tag>
</taglib>
Well that's all that you need to do do create a custom taglib and use it in your jsp's.
<%@ taglib prefix="tag" uri="/WEB-INF/taglibs/customTaglib.tld"%>
You can use this taglib in jsp by including it as mentioned above and use it like shown below.
<tag:paginate max="15" offset="${offset}" count="${count}" uri="${uri}"
next="&raquo;" previous="&laquo;" />
So this when used in the application may give u an output as shown in image below.