Hướng dẫn CRUD Spring WebMVC vs Hibernate phần 2 (Quản lý sản phẩm)

2023-06-22 11:15:11

Hướng dẫn CRUD  Spring WebMVC vs Hibernate phần 2 (Quản lý sản phẩm), CRUD có upload image và có quan hệ khóa ngoại

Ở bài trước chúng ta đã crud trên bảng categories với springWebMVC và Hibernate 

Phần 1 : CRUD category

Hôm nay chúng ta sẽ quản lý sản phẩm 

Bước 1: Chuẩn Bị Bảng products

create table prouducts(
    productId int GENERATED AS IDENTITY PRIMARY KEY,
    productName nvarchar2(100) NOT NULL,
    price float,
    image NVARCHAR2(255) NULL,
    description CLOB , 
    categoryId int,
    foreign key(categoryId) references categories(categoryId)
);

Bước 2: Thay đổi Entity Category ở phần 1 như sau: 

package com.mosoftvn.crud_spring_mvc.entities;

import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.GenerationType;
@Entity
@Table(name = "categories")
public class Category {
	@Id
	@Column(name = "categoryId")
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer categoryId;
	@Column(name =  "categoryName")
	private String categoryName;
	@Column(name = "categoryStatus")
	private Boolean categoryStatus;
// thêm phần này
	@OneToMany(mappedBy = "category")
	private Set<Product> products;

	public Category() {
		// TODO Auto-generated constructor stub
	}
	
	public Integer getCategoryId() {
		return categoryId;
	}

	public void setCategoryId(Integer categoryId) {
		this.categoryId = categoryId;
	}

	public String getCategoryName() {
		return categoryName;
	}

	public void setCategoryName(String categoryName) {
		this.categoryName = categoryName;
	}

	public Boolean getCategoryStatus() {
		return categoryStatus;
	}

	public void setCategoryStatus(Boolean categoryStatus) {
		this.categoryStatus = categoryStatus;
	}
	
	public Set<Product> getProducts() {
		return products;
	}
	
	public void setProducts(Set<Product> products) {
		this.products = products;
	}
}

Bước 3: Tạo Entity Product trong package entities:
 

package com.mosoftvn.crud_spring_mvc.entities;

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

@Entity
@Table(name = "products")
public class Product {
	@Id
	@Column(name = "productId")
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Integer productId;
	@Column(name = "productName")
	private String productName;
	@Column(name = "price")
	private Double price;
	@Column(name = "image")
	private String image;
	@Column(name = "description")
	private String description;
	
	@ManyToOne
	@JoinColumn(name = "categoryId",referencedColumnName = "categoryId")
	private Category category;
	
	public Product() {
		// TODO Auto-generated constructor stub
	}

	public Product(Integer productId, String productName, Double price, String image, String description,
			Category category) {
		super();
		this.productId = productId;
		this.productName = productName;
		this.price = price;
		this.image = image;
		this.description = description;
		this.category = category;
	}

	public Integer getProductId() {
		return productId;
	}

	public void setProductId(Integer productId) {
		this.productId = productId;
	}

	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	public Double getPrice() {
		return price;
	}

	public void setPrice(Double price) {
		this.price = price;
	}

	public String getImage() {
		return image;
	}

	public void setImage(String image) {
		this.image = image;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}
      
	public Category getCategory() {
		return category;
	}

	public void setCategory(Category category) {
		this.category = category;
	}
	
	
}

Bước 4: Tạo ProductDAO,ProductDAOImpl trong package dao như sau :

ProductDAO: 

package com.mosoftvn.crud_spring_mvc.dao;

import java.util.List;


import com.mosoftvn.crud_spring_mvc.entities.Product;

public interface ProductDAO {
	public List<Product> getAll();
	public Boolean create(Product product);
	public Product find(Integer productID);
	public Boolean update(Product product);
	public Boolean delete(Integer productID);
}

ProductDAOImpl:

package com.mosoftvn.crud_spring_mvc.dao;

import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.mosoftvn.crud_spring_mvc.entities.Product;

@Repository
public class ProductDAOImpl implements ProductDAO {
	@Autowired
	private SessionFactory sessionFactory;
	@Override
	public List<Product> getAll() {
		Session session = sessionFactory.openSession();
		try {
			List list = session.createQuery("from Product p ORDER BY p.productId DESC").list();
			return list;
		} catch (Exception e) {
			// TODO: handle exception\
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public Boolean create(Product product) {
		Session session = sessionFactory.openSession();
		try {
		
			session.save(product);
			return true;
		} catch (Exception e) {
			// TODO: handle exception
		} finally {
			session.close();
		}
		return false;
	}

	@Override
	public Product find(Integer productID) {
		Session session = sessionFactory.openSession();
		try {
			Product product = session.get(Product.class, productID);
			return product;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			session.close();
		}
		return null;
	}

	@Override
	public Boolean update(Product product) {
		Session session = sessionFactory.openSession();
		try {
			session.beginTransaction();
			session.update(product);
			session.getTransaction().commit();
			return true;
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			session.getTransaction().rollback();
		} finally {
			session.close();
		}
		return false;
	}

	@Override
	public Boolean delete(Integer productID) {
		Session session = sessionFactory.openSession();
		
		try {
			session.beginTransaction();
			session.delete(find(productID));
			session.getTransaction().commit();
			return true;
		} catch (Exception e) {
			// TODO: handle exception
			session.getTransaction().rollback();
		} finally {
			session.close();
		}
		return false;
	}

}

Bước 5: Thêm các thư viện để xử lý upload file : commons-fileupload,commons-io

Add thêm thư viện vào file porm.xml:

<?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: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.xsd 

    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
    "> 

  <context:component-scan base-package="com.mosoftvn.crud_spring_mvc" /> 
  <context:annotation-config></context:annotation-config>
  <mvc:annotation-driven></mvc:annotation-driven>
	<mvc:resources location="/uploads/" mapping="/uploads/**"></mvc:resources>
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 

    <property name="prefix"> 

      <value>/views/</value> 

    </property> 

    <property name="suffix"> 

      <value>.jsp</value> 

    </property> 

  </bean> 
  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  		<property name="driverClassName" value="oracle.jdbc.OracleDriver"></property>
  		<property name="url" value="jdbc:oracle:thin:@localhost:1521:CrmDB"></property>
  		<property name="username" value="system"></property>
  		<property name="password" value="123456"></property>
  </bean>
  <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
  	<property name="dataSource" ref="dataSource"></property>
  		<property name="packagesToScan" value="com.mosoftvn.crud_spring_mvc.entities"></property>
  		<property name="hibernateProperties">
  			<props>
  				<prop key="hibernate.show_sql">true</prop>
  				<prop key="hibernate.dialect">org.hibernate.dialect.Oracle12cDialect</prop>
  			</props>
  		</property>
  </bean>
   <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
</beans>

Bước 6: Thay đổi cấu hình upload trong spring-config.xml:

spring-config.xml:

<?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: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.xsd 

    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
    http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
    "> 

  <context:component-scan base-package="com.mosoftvn.crud_spring_mvc" /> 
  <context:annotation-config></context:annotation-config>
  <mvc:annotation-driven></mvc:annotation-driven>
	<mvc:resources location="/uploads/" mapping="/uploads/**"></mvc:resources>
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 

    <property name="prefix"> 

      <value>/views/</value> 

    </property> 

    <property name="suffix"> 

      <value>.jsp</value> 

    </property> 

  </bean> 
  <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  		<property name="driverClassName" value="oracle.jdbc.OracleDriver"></property>
  		<property name="url" value="jdbc:oracle:thin:@localhost:1521:CrmDB"></property>
  		<property name="username" value="system"></property>
  		<property name="password" value="123456"></property>
  </bean>
  <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
  	<property name="dataSource" ref="dataSource"></property>
  		<property name="packagesToScan" value="com.mosoftvn.crud_spring_mvc.entities"></property>
  		<property name="hibernateProperties">
  			<props>
  				<prop key="hibernate.show_sql">true</prop>
  				<prop key="hibernate.dialect">org.hibernate.dialect.Oracle12cDialect</prop>
  			</props>
  		</property>
  </bean>
   <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
</beans>

Tạo Thư mục uploads/images trong webapp

Bước 7: Tạo Controller ProductController trong package controllers:

package com.mosoftvn.crud_spring_mvc.controllers;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
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.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.mosoftvn.crud_spring_mvc.dao.ProductDAO;
import com.mosoftvn.crud_spring_mvc.dao.CategoryDAO;
import com.mosoftvn.crud_spring_mvc.entities.Category;
import com.mosoftvn.crud_spring_mvc.entities.Product;

@Controller
public class ProductController {
	@Autowired
	private ProductDAO productDAO;
	@Autowired
	private CategoryDAO categoryDAO;
	
	@RequestMapping(value = "/product")
	public String index(Model model) {
		List<Product> list = productDAO.getAll();
		model.addAttribute("list", list);
		return "product/index";
	}
	@RequestMapping(value = "/addProduct")
	public String add(Model model) {
		Product product = new Product();
		List<Category> listCategory = categoryDAO.getAll();
		model.addAttribute("product", product);
		model.addAttribute("listCategory",listCategory);
		return "product/add";
	}
	
	@RequestMapping(value = "/insertProduct")
	public String save(@ModelAttribute("product")Product product,BindingResult result,@RequestParam("image")MultipartFile fileImage,HttpServletRequest request) {
		
		// xu ly upload file 
		String path = request.getServletContext().getRealPath("uploads/images");
		File f = new File(path);
		String fileName = fileImage.getOriginalFilename();
		File distination = new File(f.getAbsolutePath()+"/"+fileName);
		if(!distination.exists()) {
			try {
				Files.write(distination.toPath(), fileImage.getBytes(), StandardOpenOption.CREATE);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		product.setImage(fileName);
		
		if(productDAO.create(product)) {
			return "redirect:/product";
		} else {
			return "redirect:/addProduct";
		}
		
	}
	
	@RequestMapping(value = "/editProduct/{id}")
	public String edit(Model model,@PathVariable Integer id) {
		Product product = productDAO.find(id);
		List<Category> listCategory = categoryDAO.getAll();
		model.addAttribute("product", product);
		
		model.addAttribute("listCategory",listCategory);
		return "product/edit";
	}
	
	@RequestMapping(value = "/updateProduct")
	public String update(@ModelAttribute("product")Product product,BindingResult result,@RequestParam("fileImage")MultipartFile fileImage,HttpServletRequest request) {
		// xu ly upload file 
				String fileName = fileImage.getOriginalFilename();
				boolean isEmpty = fileName == null || fileName.trim().length() == 0;
				if(!isEmpty) {
					String path = request.getServletContext().getRealPath("uploads/images");
					File f = new File(path);
					
					File distination = new File(f.getAbsolutePath()+"/"+fileName);
					if(!distination.exists()) {
						try {
							Files.write(distination.toPath(), fileImage.getBytes(), StandardOpenOption.CREATE);
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					product.setImage(fileName);
				}
				
				if(productDAO.update(product)) {
					return "redirect:/product";
				} else {
					return "redirect:/updateProduct";
				}
	}
	
	@GetMapping("/deleteProduct/{id}")
	public String delete(@PathVariable  String id,RedirectAttributes redirectAttrs) {
		
		if(productDAO.delete(Integer.parseInt(id))) {
			redirectAttrs.addFlashAttribute("success", "Xóa thành công");
			return "redirect:/product";
		}
		
		return "redirect:/";
		
	}
}

Bước 8: Tạo View

productt/index.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 <%@ taglib prefix = "fmt" uri = "http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
  <head>
    <title>Title</title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" >
  </head>
  <body>
    
    <div class="container">
        <div class="row justify-content-center">
        	
        
            <div class="col-lg-8">
            <c:if test="${!empty success}">
		        <div class="alert alert-primary" role="alert">
					<strong>${success}</strong>
				</div>
        	</c:if>
                <table class="table">
                    <thead>
                        <tr>
                            <th>STT</th>
                            <th>Name</th>
                            <th>Price</th>
                            <th>Image</th>
                            <th>Category Name</th>
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>
                    <c:forEach items="${list}" var="p" varStatus="loop">
                    	 <tr>
                            <td scope="row">${loop.count}</td>
                            <td>${p.productName}</td>
                            <td><fmt:formatNumber type = "number" maxFractionDigits = "3" value = "${p.price}" /></td>
                            <td>${p.category.categoryName}</td>
                            <td>
                            	<img alt="" src="<c:url value="uploads"/>/images/${p.image}" width="100px" />
                            </td>
                            <td>
                            	<a href="editProduct/${p.productId}" class="btn btn-primary">Edit</a>
                             	<a href="deleteProduct/${p.productId}" class="btn btn-danger">Delete</a>
                             
                             </td>
                        </tr>
                       
                    </c:forEach>
                       
                    </tbody>
                </table>
                <a href="addProduct" class="btn btn-success">Thêm mới</a>
            </div>
        </div>
    </div>

</body>
</html>

product/add.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
  <head>
    <title>Title</title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" >
  </head>
  <body>
    
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-lg-6">
                <form:form action="insertProduct" method="POST" modelAttribute="product" enctype="multipart/form-data">
					  <div class="form-group">
					    <label for="exampleInputEmail1">Product Name</label>
					    <form:input type="text" path="ProductName" class="form-control"/>
					    
					  </div>
					  <div class="form-group">
					    <label for="exampleInputEmail1">price</label>
					    <form:input type="text" path="price" class="form-control"/>
					    
					  </div>
					  <div class="form-group">
					    <label for="exampleInputEmail1">Image</label>
					    <input type="file" name="image" class="form-control"/>
					    
					  </div>
					 <div class="form-group">
					    <label for="exampleInputEmail1">Category</label>
					    <form:select path="category.categoryId" class="form-control">
					    	<form:options items="${listCategory}" itemLabel="categoryName" itemValue="categoryId"/>
					    </form:select>
					    
					  </div>
					  <div class="form-group">
					    <label for="exampleInputEmail1">Description</label>
					    
					    <form:textarea path="description" class="form-control"/>
					  </div>
					  <button type="submit" class="btn-block btn-primary">Add</button>
				</form:form>
            </div>
        </div>
    </div>

</body>
</html>

product/edit.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
  <head>
    <title>Title</title>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" >
  </head>
  <body>
    
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-lg-6">
                <form:form action="${pageContext.request.contextPath}/updateProduct" method="POST" modelAttribute="product" enctype="multipart/form-data">
					  <form:input path="image" type="text"/>
					  <form:input path="productId" type="text"/>
					  <div class="form-group">
					    <label for="exampleInputEmail1">Product Name</label>
					    <form:input type="text" path="ProductName" class="form-control"/>
					    
					  </div>
					  <div class="form-group">
					    <label for="exampleInputEmail1">price</label>
					    <form:input type="text" path="price" class="form-control"/>
					    
					  </div>
					  <div class="form-group">
					    <label for="exampleInputEmail1">Image</label>
					    <input type="file" name="fileImage" class="form-control"/>
					    <img alt="" src="${pageContext.request.contextPath}/<c:url value="uploads"/>/images/${product.image}">
					  </div>
					 <div class="form-group">
					    <label for="exampleInputEmail1">Category</label>
					    <form:select path="category.categoryId" class="form-control">
					    	<form:options items="${listCategory}" itemLabel="categoryName" itemValue="categoryId"/>
					    </form:select>
					    
					  </div>
					  <div class="form-group">
					    <label for="exampleInputEmail1">Description</label>
					    
					    <form:textarea path="description" class="form-control"/>
					  </div>
					  <button type="submit" class="btn-block btn-primary">Update</button>
				</form:form>
            </div>
        </div>
    </div>

</body>
</html>

 

Bài viết liên quan

Ngày đăng : 2023-08-31 08:48:49
Spring MVC Custom Validation(Hướng dẫn validate file)

Spring MVC Custom Validation- Hướng dẫn validate file multipart file, custome anotation validate, validate file không rỗng , validate định dạng file.....

Read More
Ngày đăng : 2023-07-26 17:12:59
Hướng dẫn sử dụng i18n Internationalization(Quốc tế hóa) làm đa ngôn ngữ trong Spring MVC

Sử dụng i18n Internationalization(Quốc tế hóa) làm đa ngôn ngữ trong ứng dụng web với Spring MVC

Read More
Ngày đăng : 2023-07-20 17:17:45
Tải giao diện Admin LTE

Tải giao diện Admin LTE 2 bản rút gọn nhẹ làm trang quản trị cho ứng dụng web ...............

Read More
Ngày đăng : 2023-06-20 10:30:47
Hướng dẫn CRUD (Thêm sửa xóa) Spring WebMVC vs Hibernate

Hướng dẫn Thêm sửa xóa dữ liệu với spring webmvc sử dụng hibernate , trong bài viết này mình sử dụng database oracle

Read More
Ngày đăng : 2023-06-13 18:25:02
Hướng dẫn upload file trong spring webmvc

Hướng dẫn upload file trong spring webmvc sử dụng common-io, common-fileupload ...

Read More
Ngày đăng : 2023-06-13 18:15:39
Hướng dẫn validate form trong Spring WebMVC

Hướng dẫn validate form trong springMVC sử dụng javax-validate

Read More
Ngày đăng : 2023-06-08 14:57:17
Tổng quan về Spring Framework và Spring MVC

Là một framework phát triển ứng dụng phổ biến nhất cho ứng dụng doanh nghiệp trong Java Là một nền tảng Java mã nguồn mở. Được viết đầu tiên bởi Rod Johnson và được phát hành lần đầu dưới phiên bản Apache 2.0 vào tháng 6 năm 2003

Read More