Trong ví dụ Spring MVC thêm sửa xóa dữ liệu, chúng ta sẽ xây dựng một ứng dụng Spring MVC đơn giản quản lý thông tin cầu thủ với thao tác Spring MVC CRUD.
Để thực hiện ví dụ Spring MVC thêm sửa xóa dữ liệu (Spring MVC CRUD) bao gồm:
- Spring MVC
- Hibernate & JPA
- MySQL hoặc MariaDB
- JSTL
- Tomcat
- NetBeans IDE
Sau đây là ví dụ đơn giản xây dựng ứng dụng Web quản lý thông tin cầu thủ sử dụng Spring MVC, bạn cần thực hiện các bước theo hướng dẫn sau đây của Team Việt Dev:
Bước 1: Khởi tạo ứng dụng Web
Khởi tạo ứng dụng Web Spring MVC bẳng cách từ danh mục của IDE chọn File > New Project…
Chọn thể loại Java Web > Web Application sau đó nhấn Next.
Bây giờ bạn đặt tên cho dự án, đường dẫn lưu trữ và nhấn Next.
Tiếp tục chọn các mục như Server, Java EE Version… sau đó nhấn Next.
Tích vào lựa chọn Spring Web MVC và Hibernate để chúng ta bắt đầu khởi tạo ứng dụng Spring MVC.
Cấu trúc ứng dụng Web Spring MVC như sau:
Bước 2: Bây giờ ta sẽ sử dụng các chú thích JPA để tạo thực thể, đầu tiên bạn tạo lớp Profile.java trong gói com.teamvietdev.model với một số thông tin gồm Name, Image, DateofBirth, Position…
package com.teamvietdev.model; import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; /** * * @author TVD */ @Entity(name = "profile") public class Profile implements Serializable { @Id @GeneratedValue private long profileId; private String profileName; private String profileImage; private String profileDateofBirth; private String profilePosition; private String profileCurrentClub; private boolean profileStatus; // get & set }
Trong gói com.teamvietdev.util cấu hình tập tin hibernate.cfg với các thông số cơ sở dữ liệu phù hợp.
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/db_example?createDatabaseIfNotExist=true</property> <property name="hibernate.connection.useUnicode">true</property> <property name="hibernate.connection.characterEncoding">UTF-8</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <property name="hibernate.current_session_context_class">thread</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.show_sql">false</property> <property name="hibernate.enable_lazy_load_no_trans">true</property> <property name="hibernate.c3p0.min_size">5</property> <property name="hibernate.c3p0.max_size">20</property> <property name="hibernate.c3p0.timeout">300</property> <property name="hibernate.c3p0.max_statements">50</property> <property name="hibernate.c3p0.idle_test_period">3000</property> <mapping class="com.teamvietdev.model.Profile"/> </session-factory> </hibernate-configuration>
Trong gói com.teamvietdev.util tạo lớp HibernateUtil.java
package com.teamvietdev.util; import org.hibernate.HibernateException; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /** * * @author TVD */ public class HibernateUtil { private static SessionFactory sessionFactory = null; private static Configuration cfg = null; static { try { cfg = new Configuration(); cfg.configure("/com/teamvietdev/util/hibernate.cfg.xml"); sessionFactory = cfg.buildSessionFactory(); } catch (HibernateException ex) { throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } }
Tiếp theo sẽ cần tạo các phương thức sẽ sử dụng trong dự án.
Lớp ProfileDAO.java
package com.teamvietdev.dao; import com.teamvietdev.model.Profile; import java.util.List; /** * * @author TVD */ public interface ProfileDAO { // create public boolean create(Profile object); // update public boolean update(Profile object); // delete public boolean delete(Profile object); // find by id public Profile findById(long profileId); // load list by nav public List<Profile> getListNav(int start, int limit); // total item public int totalItem(); }
Lớp ProfileDAOImpl.java
package com.teamvietdev.dao; import com.teamvietdev.model.Profile; import com.teamvietdev.util.HibernateUtil; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.Transaction; import org.springframework.stereotype.Repository; /** * * @author TVD */ @Repository public class ProfileDAOImpl implements ProfileDAO { @Override public boolean create(Profile object) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); session.save(object); transaction.commit(); return true; } catch (Exception ex) { if (transaction != null) { transaction.rollback(); } ex.printStackTrace(); } finally { session.flush(); session.close(); } return false; } @Override public boolean update(Profile object) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); session.update(object); transaction.commit(); return true; } catch (Exception ex) { if (transaction != null) { transaction.rollback(); } ex.printStackTrace(); } finally { session.flush(); session.close(); } return false; } @Override public boolean delete(Profile object) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); session.delete(object); transaction.commit(); return true; } catch (Exception ex) { if (transaction != null) { transaction.rollback(); } ex.printStackTrace(); } finally { session.flush(); session.close(); } return false; } @Override public Profile findById(long profileId) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); Query query = session.createQuery("FROM profile WHERE profileId = :profileId"); query.setLong("profileId", profileId); Profile obj = (Profile) query.uniqueResult(); transaction.commit(); return obj; } catch (Exception ex) { if (transaction != null) { transaction.rollback(); } ex.printStackTrace(); } finally { session.flush(); session.close(); } return null; } @Override public List<Profile> getListNav(int start, int limit) { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); Query query = session.createQuery("FROM profile"); query.setFirstResult(start); query.setMaxResults(limit); List<Profile> list = query.list(); transaction.commit(); return list; } catch (Exception ex) { if (transaction != null) { transaction.rollback(); } ex.printStackTrace(); } finally { session.flush(); session.close(); } return null; } @Override public int totalItem() { Session session = HibernateUtil.getSessionFactory().openSession(); Transaction transaction = null; try { transaction = session.beginTransaction(); Query query = session.createQuery("SELECT count(*) FROM profile"); Long obj = (Long) query.uniqueResult(); transaction.commit(); return obj.intValue(); } catch (Exception ex) { if (transaction != null) { transaction.rollback(); } ex.printStackTrace(); } finally { session.flush(); session.close(); } return 0; } }
Lớp ProfileService.java
package com.teamvietdev.service; import com.teamvietdev.model.Profile; import java.util.List; /** * * @author TVD */ public interface ProfileService { // create public boolean create(Profile object); // update public boolean update(Profile object); // delete public boolean delete(Profile object); // find by id public Profile findById(long profileId); // load list by nav public List<Profile> getListNav(int start, int limit); // total item public int totalItem(); }
Lớp ProfileServiceImpl.java
package com.teamvietdev.service; import com.teamvietdev.model.Profile; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.teamvietdev.dao.ProfileDAO; /** * * @author TVD */ @Service public class ProfileServiceImpl implements ProfileService { @Autowired private ProfileDAO profileDAO; @Override public boolean create(Profile object) { return profileDAO.create(object); } @Override public boolean update(Profile object) { return profileDAO.update(object); } @Override public boolean delete(Profile object) { return profileDAO.delete(object); } @Override public Profile findById(long profileId) { return profileDAO.findById(profileId); } @Override public List<Profile> getListNav(int start, int limit) { return profileDAO.getListNav(start, limit); } @Override public int totalItem() { return profileDAO.totalItem(); } }
Chỉnh sửa cấu hình tập tin web.xml như sau:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>redirect.jsp</welcome-file> </welcome-file-list> <filter> <filter-name>encoding-filter</filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding-filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
Chỉnh sửa cấu hình tập tin dispatcher-servlet.xml như sau:
<?xml version='1.0' encoding='UTF-8' ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/> <context:annotation-config /> <context:component-scan base-package="com.teamvietdev.controller" /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/plain;charset=UTF-8</value> <value>text/html;charset=UTF-8</value> <value>application/json;charset=UTF-8</value> </list> </property> </bean> <bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/> </mvc:message-converters> </mvc:annotation-driven> <bean id="profileDAO" class="com.teamvietdev.dao.ProfileDAOImpl" /> <bean id="profileService" class="com.teamvietdev.service.ProfileServiceImpl" /> </beans>
Bước 3: Sau khi hoàn thành tạo các lớp DAO và Service đã hoàn thành, chúng ta sẽ tạo lớp ProfileController.java nhằm xử lý dữ liệu từ máy khách nhằm tiếp nhận và phản hồi yêu cầu.
package com.teamvietdev.controller; import com.teamvietdev.model.Profile; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import com.teamvietdev.service.ProfileService; import java.util.ArrayList; import java.util.List; /** * * @author TVD */ @Controller @RequestMapping(value = "profile") public class ProfileController { @Autowired private ProfileService profileService; @RequestMapping(value = "list.html", method = RequestMethod.GET) public String listEmployee(ModelMap mm) { mm.put("listProfile", profileService.getListNav(0, 5)); mm.put("totalItem", profileService.totalItem() / 5); return "jsp/profile_list"; } @RequestMapping(value = "list/{page}.html", method = RequestMethod.GET) public String listEmployeeByNav(ModelMap mm, @PathVariable("page") int page) { mm.put("listProfile", profileService.getListNav((page - 1) * 5, 5)); mm.put("totalItem", profileService.totalItem() / 5); return "jsp/profile_list"; } @RequestMapping(value = "create.html", method = RequestMethod.GET) public String createEmployee(ModelMap mm) { mm.put("profile", new Profile()); // position List<String> listPostion = new ArrayList<>(); listPostion.add("Thủ môn"); listPostion.add("Hậu vệ"); listPostion.add("Tiền vệ"); listPostion.add("Tiền đạo"); mm.put("listPostion", listPostion); // club List<String> listClub = new ArrayList<>(); listClub.add("Hoàng Anh Gia Lai"); listClub.add("Becamex Bình Dương"); listClub.add("Hà Nội"); listClub.add("FLC Thanh Hóa"); listClub.add("Nam Định"); listClub.add("TP Hồ Chí Minh"); listClub.add("SHB Đà Nẵng"); listClub.add("Sông Lam Nghệ An"); listClub.add("Hải Phòng"); mm.put("listClub", listClub); return "jsp/profile_form"; } @RequestMapping(value = "edit/{profileId}.html", method = RequestMethod.GET) public String editEmployee(ModelMap mm, @PathVariable("profileId") int profileId) { Profile profile = profileService.findById(profileId); mm.put("profile", profile); // position List<String> listPostion = new ArrayList<>(); listPostion.add("Thủ môn"); listPostion.add("Hậu vệ"); listPostion.add("Tiền vệ"); listPostion.add("Tiền đạo"); mm.put("listPostion", listPostion); // club List<String> listClub = new ArrayList<>(); listClub.add("Hoàng Anh Gia Lai"); listClub.add("Becamex Bình Dương"); listClub.add("Hà Nội"); listClub.add("FLC Thanh Hóa"); listClub.add("Nam Định"); listClub.add("TP Hồ Chí Minh"); listClub.add("SHB Đà Nẵng"); listClub.add("Sông Lam Nghệ An"); listClub.add("Hải Phòng"); mm.put("listClub", listClub); return "jsp/profile_form"; } @RequestMapping(value = "delete/{profileId}.html", method = RequestMethod.GET) public String deleteEmployee(ModelMap mm, @PathVariable("profileId") int profileId) { Profile profile = profileService.findById(profileId); if (profile != null) { profileService.delete(profile); } mm.put("listProfile", profileService.getListNav(0, 5)); mm.put("totalItem", profileService.totalItem() / 5); return "jsp/profile_list"; } @RequestMapping(value = "save.html", method = RequestMethod.POST) public String saveEmployee(ModelMap mm, @ModelAttribute("profile") Profile profile) { if (profile.getProfileId() == 0) { profileService.create(profile); } else { profileService.update(profile); } mm.put("listProfile", profileService.getListNav(0, 5)); mm.put("totalItem", profileService.totalItem() / 5); return "jsp/profile_list"; } }
Trong đó:
- Phương thức listEmployee và listEmployeeByNav nhằm hiển thị dữ liệu theo dạng phân trang.
- Phương thức createEmployee để tạo mới thông tin cầu thủ.
- Phương thức editEmployee để hiển thị thông tin cầu thủ.
- Phương thức deleteEmployee để xóa thông tin cầu thủ khỏi danh sách.
- Phương thức saveEmployee để cập nhật thông tin cầu thủ vào dữ liệu.
Thiết kế trang profile_list.jsp hiển thị danh sách cầu thủ từ cơ sở dữ liệu.
<%-- Document : profile_list Created on : 9-Dec-2018, 7:34:54 PM Author : TVD --%> <%@page contentType="text/html" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Profile List</title> <!-- css --> <link href="<c:url value="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css"/>" rel='stylesheet' type='text/css'/> <!--js--> <script src="<c:url value="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js" />"></script> <script src="<c:url value="//code.jquery.com/jquery-1.11.1.min.js" />"></script> <script src="<c:url value="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" />"></script> <script src="<c:url value="http://getbootstrap.com/dist/js/bootstrap.min.js" />"></script> </head> <body> <div class="container"> <div class="row"> <div class="col col-xs-6"> <h4>Profile List</h4> <a href="${pageContext.request.contextPath}/profile/create.html">Create New</a> </div> <div class="col col-xs-6 text-right"> <ul class="pagination pull-right"> <li><a href="#"><span class="glyphicon glyphicon-chevron-left"></span></a></li> <c:forEach var="i" begin="0" end="${totalItem}"> <li> <a href="${pageContext.request.contextPath}/profile/list/${i+1}.html"><c:out value="${i+1}"/></a> </li> </c:forEach> <li><a href="#"><span class="glyphicon glyphicon-chevron-right"></span></a></li> </ul> </div> </div> <div class="clearfix"></div> <div class="row"> <div class="col-md-12"><br /> <div class="table-responsive"> <table id="mytable" class="table table-bordred table-striped"> <thead> <th>Image</th> <th>Name</th> <th>Date of Birth</th> <th>Position</th> <th>Current Club</th> <th style="width: 50px;">Edit</th> <th style="width: 50px;">Delete</th> </thead> <tbody> <c:forEach var="item" items="${listProfile}"> <tr> <td><image width="100px" src="${item.profileImage}"/></td> <td>${item.profileName}</td> <td>${item.profileDateofBirth}</td> <td>${item.profilePosition}</td> <td>${item.profileCurrentClub}</td> <td><a class="btn btn-default" href="${pageContext.request.contextPath}/profile/edit/${item.profileId}.html"><span class="glyphicon glyphicon-pencil"></span></a></td> <td><a class="btn btn-default" href="${pageContext.request.contextPath}/profile/delete/${item.profileId}.html"><span class="glyphicon glyphicon-trash"></span></i></a></td> </tr> </c:forEach> </tbody> </table> <div class="clearfix"></div> </div> </div> </div> </div> </body> </html>
Thiết kế trang profile_form.jsp hiển thị thông tin cầu thủ.
<%-- Document : profile_form Created on : 9-Dec-2018, 7:35:02 PM Author : TVD --%> <%@page contentType="text/html" pageEncoding="UTF-8"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Profile Form</title> <!-- css --> <link href="<c:url value="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css"/>" rel='stylesheet' type='text/css'/> <!--js--> <script src="<c:url value="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js" />"></script> <script src="<c:url value="//code.jquery.com/jquery-1.11.1.min.js" />"></script> </head> <body> <div class="container"> <br/> <div class="row"> <div class="col col-xs-6"> <a href="${pageContext.request.contextPath}/profile/list.html">Profile List</a> </div> <div class="col col-xs-6 text-right"> </div> </div> <div class="clearfix"></div> <fieldset> <form:form method="POST" modelAttribute="profile" action="${pageContext.request.contextPath}/profile/save.html" class="form-horizontal"> <legend>Profile</legend> <div class="form-group"> <label class="col-sm-3 control-label" for="card-holder-name">Name:</label> <div class="col-sm-9"> <form:input path="profileName" class="form-control" /> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label" for="card-number">Image URL:</label> <div class="col-sm-9"> <form:input path="profileImage" class="form-control" /> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label" for="cvv">Date of Birth:</label> <div class="col-sm-3"> <form:input path="profileDateofBirth" class="form-control" /> </div> </div> <div class="form-group"> <label class="col-sm-3 control-label" for="expiry-month">Position & Current Club:</label> <div class="col-sm-9"> <div class="row"> <div class="col-xs-3"> <form:select path="profilePosition" class="form-control col-sm-2"> <form:option value="NONE" label="--- Position ---"/> <form:options items="${listPostion}" /> </form:select> </div> <div class="col-xs-3"> <form:select path="profileCurrentClub" class="form-control col-sm-2"> <form:option value="NONE" label="--- Current Club ---"/> <form:options items="${listClub}" /> </form:select> </div> </div> </div> </div> <div class="form-group"> <div class="col-sm-offset-3 col-sm-9"> <input type="submit" value="Submit" class="btn btn-success"/> </div> </div> </form:form> </fieldset> </div> </body> </html>
Kết quả sau khi chạy ví dụ Spring MVC thêm sửa xóa dữ liệu danh sách cầu thủ:
Kết quả sau khi chạy ví dụ Spring MVC thêm sửa xóa dữ liệu thông tin cầu thủ:
Tải mã nguồn tại đây:
Lời kết: Trong thời gian tới Team Việt Dev sẽ tiếp tục chia sẻ thêm nhiều bài viết trong loạt bài hướng dẫn xây dựng web bán hàng bằng Spring MVC… miễn phí đến bạn đọc, các bạn nhớ theo dõi kênh để có được những chia sẻ mới nhất.
(Tác giả: Team Việt Dev)
Bạn có thể cung cấp file database cho chương trình này được không ạ?
Bạn có thể cho mình xin database của projects trên được không?
Cảm ơn bạn.
bạn có thể cho mình xin database của web bán hàng này đ ko ạ