In this post, I am going to explain
about pagination using struts2 and hibernate. If the result set is large, then
it is not efficient way to store it in memory; It is always to do lazy loading
in these scenarios. For example, you had 10000 records of employees, instead of
loading all 10000 records at a time, first load 100 records in first page, if
user asks for 2nd page then send him records between 101 and 200, 3rd page send
him from 201 to 300 etc.,
Class
|
Description
|
Employee.java
|
Employee model class, mapped to
employee table.
|
EmployeeService.java
|
Interface declares the methods to work
with Employee table.
|
EmployeeServiceImpl.java
|
Implements EmployeeService interface.
|
EmployeeAction.java
|
Struts action class that receives
requests.
|
org.hibernate.Criteria class provides
methods setFirstResult, setMaxResults methods to support pagination.
public Criteria setFirstResult(int
firstResult)
Set the first result to be retrieved.
public Criteria setMaxResults(int
maxResults)
Set a limit upon the number of objects
to be retrieved.
Following step-by-step procedure set up
complete working application in eclipse.
Step
1: Create new dynamic
web project ‘struts_pagination’ in eclipse.
File -> New Dynamic Web project.
Step
2: Mavenize the
project, Right click on the project -> Configure -> Convert To Maven
Project.
Step
3: Update pom.xml for
gson, struts, hibernate, MySQL dependencies.
pom.xml
<dependencies> <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.3.20</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.3.11.Final</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.36</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.6</version> <scope>provided</scope> </dependency> </dependencies>
Step 4: Create package com.sample.model, Define Employee
class.
Employee.java
package com.sample.model; import javax.persistence.Entity; import javax.persistence.Id; import lombok.Getter; import lombok.Setter; import lombok.ToString; @Entity(name="employee") @ToString public class Employee { @Id @Getter @Setter private long id; @Getter @Setter private String firstName; @Getter @Setter private String lastName; @Getter @Setter private String designation; @Getter @Setter private int age; @Getter @Setter private double salary; }
Step 5: Define hibernate.cfg.xml file, and configure all
the hibernate settings here. Make sure hibernate.cfg.xml file is located in
project classpath.
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database Connection settings --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.url">jdbc:mysql://127.0.0.1/sample</property> <property name="connection.username">root</property> <property name="connection.password">tiger</property> <!-- Enable the logging of all the generated SQL statements to the console --> <property name="show_sql">true</property> <!-- Format the generated SQL statement to make it more readable, --> <property name="format_sql">false</property> <!-- Hibernate will put comments inside all generated SQL statements to hint what’s the generated SQL trying to do --> <property name="use_sql_comments">true</property> <!-- This property makes Hibernate generate the appropriate SQL for the chosen database. --> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">update</property> <!-- mappings for annotated classes --> <mapping class="com.sample.model.Employee" /> </session-factory> </hibernate-configuration>
Since I mapped Employee to table
employee, create table employee in the database sample. Following is the schema
for employee table.
create table Employee (id integer not
null, age integer not null, designation varchar(255), firstName varchar(255),
lastName varchar(255), salary double precision not null, primary key (id));
Step
6: create package
com.sample.service. Define the interface EmployeeService.java.
EmployeeService.java
package com.sample.service; import java.util.List; import com.sample.model.Employee; public interface EmployeeService { public long insertEmployee(Employee emp); public long insertEmployees(List<Employee> emps); public List<Employee> getEmployees(int pageNum); }
Step 7: Create package com.sample.service.impl, define the
class EmployeeServiceImpl.java.
EmployeeServiceImpl.java
package com.sample.service.impl; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import com.sample.model.Employee; import com.sample.service.EmployeeService; public class EmployeeServiceImpl implements EmployeeService { private static SessionFactory sessionFactory = getSessionFactory(); private static SessionFactory getSessionFactory() { if (sessionFactory == null) { Configuration configuration = new Configuration().configure(); StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder() .applySettings(configuration.getProperties()); sessionFactory = configuration.buildSessionFactory(builder.build()); } return sessionFactory; } @Override public long insertEmployee(Employee emp) { Session session = null; try { session = sessionFactory.openSession(); session.beginTransaction(); session.save(emp); Transaction trans = session.getTransaction(); trans.commit(); return getLastInsertId(session); } catch (Exception e) { System.out.println(e.getMessage()); } finally { if (session != null) session.close(); } return -1; } @Override public long insertEmployees(List<Employee> emps) { Session session = null; try { session = sessionFactory.openSession(); session.beginTransaction(); for (Employee emp : emps) session.save(emp); Transaction trans = session.getTransaction(); trans.commit(); return getLastInsertId(session); } catch (Exception e) { System.out.println(e.getMessage()); } finally { if (session != null) session.close(); } return -1; } private long getLastInsertId(Session session) { BigInteger id = (BigInteger) session.createSQLQuery( "SELECT LAST_INSERT_ID()").uniqueResult(); return id.longValue(); } @SuppressWarnings("unchecked") @Override public List<Employee> getEmployees(int pageNum) { Session session = null; List<Employee> list = new ArrayList<>(); try { session = sessionFactory.openSession(); Criteria crit = session.createCriteria(Employee.class .getCanonicalName()); crit.setFirstResult(pageNum * 100 + 1); crit.setMaxResults(100); list = (List<Employee>) crit.list(); return list; } catch (Exception e) { System.out.println(e.getMessage()); } finally { if (session != null) session.close(); } return list; } }
Step 8: Create packge com.sample.util. Define class
JSONUtil.java.
JSONUtil.java
package com.sample.util; import com.google.gson.Gson; public class JSONUtil { private static Gson gson = new Gson(); public static String getJson(Object obj) { return gson.toJson(obj); } }
Step 9: Create package com.sample.actions, define the class
EmployeeAction.java.
EmployeeAction.java
package com.sample.actions; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import lombok.Getter; import lombok.Setter; import com.sample.model.Employee; import com.sample.service.EmployeeService; import com.sample.service.impl.EmployeeServiceImpl; import com.sample.util.JSONUtil; public class EmployeeAction { @Getter @Setter private int pageNum; private InputStream inputStream; EmployeeService service = new EmployeeServiceImpl(); public InputStream getInputStream() { return inputStream; } public String insert1000Employess() throws UnsupportedEncodingException { List<Employee> emps = new ArrayList<>(); for (int i = 0; i < 1000; i++) { Employee emp = new Employee(); emp.setAge(28); emp.setDesignation("Engineer"); emp.setFirstName("PTR" + i); emp.setId(i); emp.setLastName("nayan" + i); emp.setSalary(12345 + i); emps.add(emp); } service.insertEmployees(emps); String data = "Employees saved successfully"; inputStream = new ByteArrayInputStream(data.getBytes("UTF-8")); return "success"; } public String getEmployees() throws UnsupportedEncodingException { List<Employee> emps = service.getEmployees(pageNum); String json = JSONUtil.getJson(emps); inputStream = new ByteArrayInputStream(json.getBytes("UTF-8")); return "success"; } }
Step 10: Update web.xml to transfer all requests to struts.
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>struts_pagination</display-name> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <session-config> <session-timeout>1</session-timeout> </session-config> </web-app>
Step
11: It is time to
create struts.xml. Since Struts 2 requires struts.xml to be present in classes
folder. Create struts.xml file under the WebContent/WEB-INF/classes folder.
Eclipse does not create the "classes" folder by default, so you need
to do this yourself. To do this, right click on the WEB-INF folder in the
project explorer and select New > Folder. Create struts.xml file inside
classes.
struts.xml
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="default" extends="struts-default"> <action name="getEmployees" class="com.sample.actions.EmployeeAction" method="getEmployees"> <result type="stream"> <param name="contentType">text/html</param> <param name="inputName">inputStream</param> </result> </action> <action name="insert1000Employess" class="com.sample.actions.EmployeeAction" method="insert1000Employess"> <result type="stream"> <param name="contentType">text/html</param> <param name="inputName">inputStream</param> </result> </action> </package> </struts>
Step 12: Total project structure looks like below.
Run the
project in server.
Hit following
url, all the 1000 employees are saved to table employee.
Now, hit
following url, to get first 100 employee details.
Hit following
url, to get employees from 101 to 200.
No comments:
Post a Comment