By GokiSoft.com|
10:45 26/12/2020|
Spring MVC
[Share Code] Bài tập - Quản lý sản phẩm - Lập trình Spring MVC
B1. Thiết kế database
create table product (
id int primary key auto_increment,
title varchar(200) not null,
content longtext,
thumbnail varchar(500),
price float,
discount float,
created_at datetime,
updated_at datetime
)
B2. Tao project
- Sua config
- Ket noi vs CSDL
- Tai thu vien jdbc mysql driver => copy vao project
- Add thu vien trong project
- Generate database (ORM)
- Sua lai file cau hinh Persistence
- Product
- Hien thi danh sach san pham => /product/index
#persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="BT1994PU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.entity.Product</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/product_mgr?serverTimezone=UTC"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.password" value=""/>
</properties>
</persistence-unit>
</persistence>
#ProductController.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.controller;
import com.entity.Product;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**
*
* @author teacher
*/
@Controller
@RequestMapping(value = "/product")
public class ProductController {
@RequestMapping(value = "/index", method = RequestMethod.GET)
public String index(@RequestParam Map<String, String> form, ModelMap modelMap) {
//Lay du lieu database
//B1. Ket noi toi CSDL
EntityManagerFactory factory = Persistence.createEntityManagerFactory("BT1994PU");
EntityManager em = factory.createEntityManager();
//B2. Tao query toi database
Query q = null;
if(form.containsKey("s")) {
String s = form.get("s");
q = em.createNamedQuery("Product.findByTitleLike", Product.class);
q.setParameter("title", "%"+s+"%");
} else {
q = em.createNamedQuery("Product.findAll", Product.class);
}
//B3. Lay du lieu
List<Product> list = q.getResultList();
modelMap.put("productList", list);
return "/product/index";
}
@RequestMapping(value = "/view", method = RequestMethod.GET)
public String view(@RequestParam Map<String, String> form, ModelMap modelMap) {
Product product = new Product();
if(form.containsKey("id")) {
int id = Integer.parseInt(form.get("id"));
//B1. Ket noi toi CSDL
EntityManagerFactory factory = Persistence.createEntityManagerFactory("BT1994PU");
EntityManager em = factory.createEntityManager();
product = em.find(Product.class, id);
if(product == null) {
product = new Product();
}
}
modelMap.put("product", product);
return "/product/view";
}
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(@RequestParam Map<String, String> form) {
String title = form.get("title");
String thumbnail = form.get("thumbnail");
String content = form.get("content");
float price = Float.parseFloat(form.get("price"));
float discount = Float.parseFloat(form.get("discount"));
int id = 0;
if(form.containsKey("id") && !form.get("id").isEmpty()) {
id = Integer.parseInt(form.get("id"));
}
//B1. Ket noi toi CSDL
EntityManagerFactory factory = Persistence.createEntityManagerFactory("BT1994PU");
EntityManager em = factory.createEntityManager();
if(id > 0) {
//update
Product productFind = em.find(Product.class, id);
em.getTransaction().begin();
productFind.setTitle(title);
productFind.setThumbnail(thumbnail);
productFind.setContent(content);
productFind.setPrice(price);
productFind.setDiscount(discount);
productFind.setUpdatedAt(new Date());
em.getTransaction().commit();
} else {
//insert
em.getTransaction().begin();
Product product = new Product();
product.setTitle(title);
product.setThumbnail(thumbnail);
product.setContent(content);
product.setPrice(price);
product.setDiscount(discount);
product.setCreatedAt(new Date());
product.setUpdatedAt(new Date());
em.persist(product);
em.getTransaction().commit();
}
return "redirect:index.html";
}
@RequestMapping(value = "/delete", method = RequestMethod.POST)
public String delete(@RequestParam Map<String, String> form) {
int id = 0;
if(form.containsKey("id") && !form.get("id").isEmpty()) {
id = Integer.parseInt(form.get("id"));
}
//B1. Ket noi toi CSDL
EntityManagerFactory factory = Persistence.createEntityManagerFactory("BT1994PU");
EntityManager em = factory.createEntityManager();
if(id > 0) {
//delete
Product productFind = em.find(Product.class, id);
if(productFind != null) {
em.getTransaction().begin();
em.remove(productFind);
em.getTransaction().commit();
}
}
return "redirect:index.html";
}
//delete/1.html
@RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
public String delete2(@PathVariable int id) {
//B1. Ket noi toi CSDL
EntityManagerFactory factory = Persistence.createEntityManagerFactory("BT1994PU");
EntityManager em = factory.createEntityManager();
if(id > 0) {
//delete
Product productFind = em.find(Product.class, id);
if(productFind != null) {
em.getTransaction().begin();
em.remove(productFind);
em.getTransaction().commit();
}
}
return "redirect:index.html";
}
}
#Product.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.entity;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author teacher
*/
@Entity
@Table(name = "product")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "Product.findAll", query = "SELECT p FROM Product p")
, @NamedQuery(name = "Product.findById", query = "SELECT p FROM Product p WHERE p.id = :id")
, @NamedQuery(name = "Product.findByTitle", query = "SELECT p FROM Product p WHERE p.title = :title")
, @NamedQuery(name = "Product.findByTitleLike", query = "SELECT p FROM Product p WHERE p.title like :title")
, @NamedQuery(name = "Product.findByThumbnail", query = "SELECT p FROM Product p WHERE p.thumbnail = :thumbnail")
, @NamedQuery(name = "Product.findByPrice", query = "SELECT p FROM Product p WHERE p.price = :price")
, @NamedQuery(name = "Product.findByDiscount", query = "SELECT p FROM Product p WHERE p.discount = :discount")
, @NamedQuery(name = "Product.findByCreatedAt", query = "SELECT p FROM Product p WHERE p.createdAt = :createdAt")
, @NamedQuery(name = "Product.findByUpdatedAt", query = "SELECT p FROM Product p WHERE p.updatedAt = :updatedAt")})
public class Product implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 200)
@Column(name = "title")
private String title;
@Lob
@Size(max = 2147483647)
@Column(name = "content")
private String content;
@Size(max = 500)
@Column(name = "thumbnail")
private String thumbnail;
// @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
@Column(name = "price")
private Float price;
@Column(name = "discount")
private Float discount;
@Column(name = "created_at")
@Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
@Column(name = "updated_at")
@Temporal(TemporalType.TIMESTAMP)
private Date updatedAt;
public Product() {
}
public Product(Integer id) {
this.id = id;
}
public Product(Integer id, String title) {
this.id = id;
this.title = title;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getThumbnail() {
return thumbnail;
}
public void setThumbnail(String thumbnail) {
this.thumbnail = thumbnail;
}
public Float getPrice() {
return price;
}
public void setPrice(Float price) {
this.price = price;
}
public Float getDiscount() {
return discount;
}
public void setDiscount(Float discount) {
this.discount = discount;
}
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
public Date getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Product)) {
return false;
}
Product other = (Product) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "com.entity.Product[ id=" + id + " ]";
}
}
#dispatcher-servlet.xml
<?xml version='1.0' encoding='UTF-8' ?>
<!-- was: <?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"
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/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-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc">
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<mvc:annotation-driven></mvc:annotation-driven>
<context:component-scan base-package="com.controller"/>
<!--
Most controllers will use the ControllerClassNameHandlerMapping above, but
for the index controller we are using ParameterizableViewController, so we must
define an explicit mapping for it.
-->
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="index.html">indexController</prop>
</props>
</property>
</bean>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/view/"
p:suffix=".jsp" />
<!--
The index controller.
-->
<bean name="indexController"
class="org.springframework.web.servlet.mvc.ParameterizableViewController"
p:viewName="index" />
</beans>
#index.jsp
<%--
Document : index
Created on : Dec 26, 2020, 8:51:24 AM
Author : teacher
--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Product List - Page</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"/>
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="panel panel-primary">
<div class="panel-heading">
<h1 style="text-transform: uppercase">Product List - Page</h1>
</div>
<div class="panel-body">
<a href="view.html"><button class="btn btn-success" style="margin-bottom: 15px;">Add Product</button></a>
<form method="get" action="index.html" style="float: right">
<input type="text" class="form-control" name="s" style="width: 200px; float: right" placeholder="Tim kiem ..."/>
</form>
<table class="table table-bordered table-hovered">
<thead>
<tr>
<th>STT</th>
<th>Thumbnail</th>
<th>Title</th>
<th>Price</th>
<th>Discount</th>
<th>Updated At</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<c:forEach items="${productList}" var="item" varStatus="loop">
<tr>
<td>${loop.index + 1}</td>
<td>
<img src="${item.thumbnail}" width="80px">
</td>
<td>${item.title}</td>
<td>${item.price}</td>
<td>${item.discount}</td>
<td>${item.updatedAt}</td>
<td>
<a href="view.html?id=${item.id}"><button class="btn btn-warning">Edit</button></a>
</td>
<td>
<button class="btn btn-danger" onclick="deleteProduct(${item.id})">Delete</button>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
<script>
function deleteProduct(id) {
var option = confirm('Ban co chac chan muon xoa du lieu nay khong???')
if(!option) return
$.post('delete.html', {
'id': id
}, function(data) {
location.reload()
})
// $.post("delete/"+id+".html", {}, function(data) {
// location.reload()
// })
}
</script>
</body>
</html>
#view.jsp
<%--
Document : view
Created on : Dec 26, 2020, 9:41:14 AM
Author : teacher
--%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Product Editor - Page</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"/>
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="text-center">Product Editor - Page</h2>
</div>
<div class="panel-body">
<form method="post" action="save.html">
<div class="form-group">
<label for="usr">Title:</label>
<input type="text" name="id" value="${product.id}" hidden="true"/>
<input required="true" type="text" class="form-control" id="title" name="title" value="${product.title}"/>
</div>
<div class="form-group">
<label for="email">Thumbnail:</label>
<input required="true" type="text" class="form-control" id="thumbnail" name="thumbnail" value="${product.thumbnail}"/>
</div>
<div class="form-group">
<label for="birthday">Price:</label>
<input type="number" class="form-control" id="price" name="price" value="${product.price}"/>
</div>
<div class="form-group">
<label for="pwd">Discount:</label>
<input required="true" type="number" class="form-control" id="discount" name="discount" value="${product.discount}"/>
</div>
<div class="form-group">
<label for="address">Description:</label>
<textarea class="form-control" rows="5" name="content">${product.content}</textarea>
</div>
<button class="btn btn-success">Save</button>
</form>
</div>
</div>
</div>
</body>
</html>
Tags:
Phản hồi từ học viên
5
(Dựa trên đánh giá ngày hôm nay)