1. Create a basic portlet
At first we need a basic portlet project. We are not going to explain how to create a portlet. Consider that our portlet project name is crud-example-portlet
2. Create a service.xml file under WEB-INF as shown in the above. The content of the file is
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.2.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_2_0.dtd"> <service-builder package-path="com.proliferay.sbuilder.example.crud"> <author>Hamidul Islam</author> <namespace>Crud</namespace> <entity name="Book" table="CRUD_BOOK_PORTLET" local-service="true" remote-service="true"> <column name="bookId" type="long" primary="true" id-type="increment"/> <column name="bookName" type="String" /> <column name="description" type="String" /> <column name="authorName" type="String" /> <column name="isbn" type="int" /> <column name="price" type="int" /> </entity> </service-builder>
Note 1: Book is the entity name. It represents the database table. Once service is generated, lots of code will be generated based entity name. For example Book.java, BookLocalServiceImpl.java, BookServiceImpl.java etc. Book.java will be a model class. All the setter and getter methods will be generated like setBookName,getBookName, setDescription, getDescription etc.
Note 2: table=”CRUD_BOOK_PORTLET” means that book information will be saved in CRUD_BOOK_PORTLET table.
Note 3: id-type=”increment” means that each time we create a new row of book, one incremented primary key will be generated.
Note 4: local-service and remote-service are set true. This means that BookLocalServiceImpl.java and BookServiceImpl.java files will be generated after building our service. By default Both the files will be empty. However we can write our own custom methods in those files. The methods of BookLocalServiceImpl.java can be called only from local machine and on the other hand methods of BookServiceImpl.java can be called remotely.
Note 5: Column represents simply columns of the table. The type of the column is defined by type attribute.
3. Building service
If you properly configured your liferay with Liferay IDE then build the service as shown in below. We can also run build service by running ant build-service.
4.Identify 4 methods for all the operations
If the build service is successful then all the service methods will be created for all the operations like Create, Read, Update and Delete. We just need to call the correct methods. Have a look in service.xml file. The entity name is Book. After building the service along with other files BookLocalServiceUtil.java will be generated. This class contains all the methods to perform CRUD operations in liferay portlet.
i) To create, BookLocalServiceUtil.addBook(book)
ii) For reading, BookLocalServiceUtil.getBook(bookId)
iii) For updating, BookLocalServiceUtil.updateBook(book)
iv) To delete, BookLocalServiceUtil.deleteBook(bookId)
All these methods will be created by default.
5. Portlet class
All the 4 operations are written in portlet class. The whole portlet class code is given below
package com.proliferay.portlet; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; import javax.portlet.PortletSession; import javax.portlet.ProcessAction; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.servlet.SessionMessages; import com.liferay.portal.kernel.util.ParamUtil; import com.liferay.util.bridges.mvc.MVCPortlet; import com.proliferay.sbuilder.example.crud.model.Book; import com.proliferay.sbuilder.example.crud.service.BookLocalServiceUtil; import com.proliferay.util.ActionUtil; import com.proliferay.util.WebKeys; /** * * @author Hamidul Islam * */ public class BookPortlet extends MVCPortlet{ /** * * This method will persist the data in database */ @ProcessAction(name = "addBook") public void addBook(ActionRequest actionRequest,ActionResponse actionResponse) throws SystemException { Book book = ActionUtil.bookFromRequest(actionRequest); //Calling service method to persist book. BookLocalServiceUtil.addBook(book); SessionMessages.add(actionRequest, "added-book"); _log.info("#################Added Book Successfully#########################"); } @ProcessAction(name = "deleteBook") public void deleteBook(ActionRequest actionRequest,ActionResponse actionResponse) throws SystemException, PortalException { long bookId = ParamUtil.getLong(actionRequest, "bookId"); BookLocalServiceUtil.deleteBook(bookId); SessionMessages.add(actionRequest, "deleted-book"); _log.info("#################Book Deleted Successfully#########################"); } @ProcessAction(name = "viewBook") public void viewBook(ActionRequest actionRequest,ActionResponse actionResponse) throws SystemException, PortalException { long bookId = ParamUtil.getLong(actionRequest, "bookId"); Book book = BookLocalServiceUtil.getBook(bookId); actionRequest.setAttribute(WebKeys.BOOK_ENTRY, book); //Show view_book.jsp actionResponse.setRenderParameter("jspPage", "/html/view_book.jsp"); } @ProcessAction(name = "updateBook") public void updateBook(ActionRequest actionRequest,ActionResponse actionResponse) throws SystemException, PortalException { long bookId = (Long) actionRequest.getPortletSession().getAttribute(WebKeys.BOOK_ID,PortletSession.PORTLET_SCOPE); Book book = ActionUtil.bookFromRequest(actionRequest); book.setBookId(bookId); /** * Calling service method to update book. * While calling update method we must have primary key in the passing object. */ BookLocalServiceUtil.updateBook(book); SessionMessages.add(actionRequest, "updated-book"); _log.info("#################Updated Book Successfully#########################"); } @ProcessAction(name = "viewEdit") public void viewEdit(ActionRequest actionRequest,ActionResponse actionResponse) throws SystemException, PortalException { long bookId = ParamUtil.getLong(actionRequest, "bookId",0); Book book = BookLocalServiceUtil.getBook(bookId); actionRequest.setAttribute(WebKeys.BOOK, book); //Show edit_book.jsp actionResponse.setRenderParameter("jspPage", "/html/edit_book.jsp"); actionRequest.getPortletSession().setAttribute(WebKeys.BOOK_ID, book.getBookId(),PortletSession.PORTLET_SCOPE); } private Log _log = LogFactoryUtil.getLog(BookPortlet.class.getName()); }
Note 1: For updating a record in database we must need primary key. While updating book the primary key of the book is kept in portlet session and retrieved from the portlet session just before updating book. Many developers keep the primary key in hidden filed which is not good practice with respect to security concern.
Note 2: Download whole source code for better understanding.