Hướng dẫn các thao tác cơ bản với MongoDB trong Spring MVC-Maven-Eclipse
Đăng lúc: 11:47 AM - 04/03/2024 bởi Charles Chung - 1083Trong bài này tôi sẽ hướng dẫn các thao tác cơ bản CRUD, tìm kiếm, phân trang với MongoDB trong Spring MVC-Maven-Eclipse
1. Kiến thức cần có
- Thiết kế web với HTML5, CSS3, JS, JQuery, Bootstrap
- Cơ bản về MongoDB
- Nắm vững JavaCore
- Nắm cơ bản về JSP Servlet, Spring MVC
2. Chuẩn bị dữ liệu
- Tải tệp script tạo cơ sở dữ liệu trong MongoDB tại đây
- Tải thư mục images chứa các ảnh sản phẩm tại đây
- Tải thư mục ckeditor 3.x tại đây
3. Các chức năng trong bài viết
- Hiển thị sản phẩm kèm tên danh mục và chi tiết
- Thêm mới, sửa sản phẩm có upload ảnh và tích hợp ckeditor cho soạn thảo nội dung
- Xóa sản phẩm
- Hiển thị sản phẩm hoa theo loại
- Tìm kiếm sản phẩm hoa theo loại và tên
- Tìm kiếm sản phẩm hoa theo khoảng giá
- Phân trang sản phẩm
4. Các bước thực hiện
Bước 1: Tạo dự án
Mở Eclipse tạo loại project Dynamic Web Project và đặt tên "SpringMVCMongoDB", lưu ý sinh file web.xml trong quá trình tạo
Bước 2: Convert project sang Maven Project
Kích chuột phải vào project vừa tạo -> chọn Configure->Convert to Maven Project -> Finish
Bước 3: Mở file pom.xml và cấu hình các dependency như sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
<dependencies> <!-- spring dependency --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.0.5.RELEASE</version> </dependency> <!-- jstl dependency --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- javax servlet api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>3.0-alpha-1</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-mongodb --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <version>3.4.9</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>3.12.14</version> </dependency> <!--https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.5</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.13.0</version> </dependency> </dependencies> |
Bước 4: Copy thư mục ckeditor và images đã tải về vào thư mục src/main/webapp/resources của project (chưa có resources thì tạo ra nhé)
Bước 5: Tạo tệp tin spring-servlet.xml trong thư mục src/main/webapp/WEB-INF và cấu hình như sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?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: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/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"> <!-- chỉ ra các package chứa các lớp java được đăng ký như là các bean --> <context:component-scan base-package="com.hanam88" /> <!-- chỉ tìm kiếm các bean trong cùng context application mà nó được định nghĩa --> <context:annotation-config /> <!-- mặc định các basic components được ủy quyền gửi request tới các controller --> <mvc:annotation-driven /> <!-- Cấu hình đường dẫn tài nguyên được phép truy cập --> <mvc:resources mapping="/**" location="/resources" /> <!-- Tạo bean xác định view sẽ được sinh ra (thư mục chứa các view, đuôi tệp tin view) --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/views/" p:suffix=".jsp" /> <!-- Tạo bean xác định dữ liệu multipart khi upload file --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" /> </beans> |
Bước 6: Mở tệp tin web.xml ở thư mục src/main/webapp/WEB-INF và cấu hình vào trong thẻ web-app như sau
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<!-- Cấu hình filter hỗ trợ UTF-8 --> <filter> <filter-name>encodingFilter</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> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Cấu hình Dispatcher Servlet nhận các cấu hình của Spring trong file spring-servlet.xml --> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> |
Bước 7: Tạo các trang jsp để hiển thị dữ liệu và các lớp entities, dao, controller để xử lý logic
Tạo thư mục views trong thư mục src/main/webapp/WEB-INF để chứa các trang jsp, sau đây là cấu trúc project đầy đủ
- Tạo lớp com.hanam88.entities/Category.java (Biểu diễn dữ liệu của collection categories)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package com.hanam88.entities; import java.io.Serializable; public class Category implements Serializable { private int categoryId; private String categoryName; private boolean status; public Category() { // TODO Auto-generated constructor stub } public Category(int categoryId, String categoryName, boolean status) { super(); this.categoryId = categoryId; this.categoryName = categoryName; this.status = status; } public int getCategoryId() { return categoryId; } public void setCategoryId(int categoryId) { this.categoryId = categoryId; } public String getCategoryName() { return categoryName; } public void setCategoryName(String categoryName) { this.categoryName = categoryName; } public boolean isStatus() { return status; } public void setStatus(boolean status) { this.status = status; } } |
- Tạo lớp com.hanam88.entities/Brand.java (Biểu diễn dữ liệu collection brands)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
package com.hanam88.entities; import java.io.Serializable; public class Brand implements Serializable { private int brandId; private String brandName; private boolean status; public Brand() { // TODO Auto-generated constructor stub } public Brand(int brandId, String brandName, boolean status) { super(); this.brandId = brandId; this.brandName = brandName; this.status = status; } public int getBrandId() { return brandId; } public void setBrandId(int brandId) { this.brandId = brandId; } public String getBrandName() { return brandName; } public void setBrandName(String brandName) { this.brandName = brandName; } public boolean isStatus() { return status; } public void setStatus(boolean status) { this.status = status; } } |
- Tạo lớp com.hanam88.entities/Product.java (Biểu diễn dữ liệu collection products)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
package com.hanam88.entities; import java.io.Serializable; public class Product implements Serializable{ private String productId; private String productName; private int categoryId; private int brandId; private int price; private String picture; private String description; private boolean status; public Product() { // TODO Auto-generated constructor stub } public Product(String productId, String productName, int categoryId, int brandId, int price, String picture, String description, boolean status) { super(); this.productId = productId; this.productName = productName; this.categoryId = categoryId; this.brandId = brandId; this.price = price; this.picture = picture; this.description = description; this.status=status; } public String getProductId() { return productId; } public void setProductId(String productId) { this.productId = productId; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public int getCategoryId() { return categoryId; } public void setCategoryId(int categoryId) { this.categoryId = categoryId; } public int getBrandId() { return brandId; } public void setBrandId(int brandId) { this.brandId = brandId; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } public String getPicture() { return picture; } public void setPicture(String picture) { this.picture = picture; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public boolean isStatus() { return status; } public void setStatus(boolean status) { this.status = status; } } |
- Tạo lớp com.hanam88.entities/ProductPage.java (Biểu diễn trang dữ liệu lấy ra từ collection products)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
package com.hanam88.entities; import java.util.List; public class ProductPage { private List<Product> products; private long totalPages; private int pageSize; private int currentPage; public ProductPage() { // TODO Auto-generated constructor stub } public ProductPage(List<Product> products, long totalPages, int pageSize, int currentPage) { super(); this.products = products; this.totalPages = totalPages; this.pageSize = pageSize; this.currentPage = currentPage; } public List<Product> getProducts() { return products; } public void setProducts(List<Product> products) { this.products = products; } public long getTotalPages() { return totalPages; } public void setTotalPages(long totalPages) { this.totalPages = totalPages; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } } |
- Tạo lớp com.hanam88.factory/ProductModel.java (Biểu diễn dữ liệu từ Product và Category)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
package com.hanam88.entities; import java.io.Serializable; public class ProductModel implements Serializable { private String productId; private String productName; private String categoryName; private int price; private String picture; private boolean status; public ProductModel() { // TODO Auto-generated constructor stub } public ProductModel(String productId, String productName, String categoryName, int price, String picture,boolean status) { super(); this.productId = productId; this.productName = productName; this.categoryName = categoryName; this.price = price; this.picture = picture; this.status=status; } public boolean isStatus() { return status; } public void setStatus(boolean status) { this.status = status; } public String getProductId() { return productId; } public void setProductId(String productId) { this.productId = productId; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public String getCategoryName() { return categoryName; } public void setCategoryName(String categoryName) { this.categoryName = categoryName; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } public String getPicture() { return picture; } public void setPicture(String picture) { this.picture = picture; } } |
- Tạo lớp com.hanam88.factory/MongoFactory.java (Kết nối với cơ sở dữ liệu mongodb)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package com.hanam88.factory; import com.mongodb.MongoClient; import com.mongodb.client.MongoDatabase; public class MongoFactory { private static MongoClient mongo; private MongoFactory() { } public static MongoClient getInstance() { int port = 27017; String hostname = "localhost"; if (mongo == null) { try { mongo = new MongoClient(hostname, port); } catch (Exception e) { e.printStackTrace(); } } return mongo; } public static MongoDatabase getDatabase() { return getInstance().getDatabase("bkapdb"); } } |
- Tạo lớp com.hanam88.services/ProductService.java (Chứa các nghiệp vụ CRUD... làm việc với mongodb)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
package com.hanam88.services; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.bson.BsonDocument; import org.bson.BsonInt32; import org.bson.BsonString; import org.bson.Document; import org.bson.conversions.Bson; import org.springframework.stereotype.Service; import com.hanam88.entities.Brand; import com.hanam88.entities.Category; import com.hanam88.entities.Product; import com.hanam88.entities.ProductModel; import com.hanam88.entities.ProductPage; import com.hanam88.factory.MongoFactory; import com.mongodb.client.AggregateIterable; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; import com.mongodb.client.model.Filters; @Service("productService") public class ProductService { // phương thức lấy danh sách các brands public List<Brand> getBrands() { List<Brand> brands = new ArrayList<>(); MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("brands"); MongoCursor<Document> cursor = collection.find().cursor(); while (cursor.hasNext()) { Document doc = cursor.next(); brands.add(new Brand(doc.getInteger("_id"), doc.getString("BrandName"),doc.getBoolean("Status"))); } return brands; } // phương thức lấy danh sách categories public List<Category> getCategories() { List<Category> categories = new ArrayList<>(); MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("categories"); MongoCursor<Document> cursor = collection.find().cursor(); while (cursor.hasNext()) { Document doc = cursor.next(); categories .add(new Category(doc.getInteger("_id"), doc.getString("CategoryName"),doc.getBoolean("Status"))); } return categories; } // phương thức lấy danh sách product public List<Product> getProducts() { List<Product> products = new ArrayList<>(); MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("products"); MongoCursor<Document> cursor = collection.find().cursor(); while (cursor.hasNext()) { Document doc = cursor.next(); products.add(new Product(doc.getString("_id"), doc.getString("ProductName"), doc.getInteger("CategoryId"), doc.getInteger("BrandId"), doc.getInteger("Price"), doc.getString("Picture"), doc.getString("Description"),doc.getBoolean("Status"))); } return products; } // phương thức product theo id public Product getProduct(String id) { MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("products"); Bson filter = new BsonDocument("_id", new BsonString(id)); Document doc = collection.find(filter).first(); if (doc != null) return new Product(doc.getString("_id"), doc.getString("ProductName"), doc.getInteger("CategoryId"), doc.getInteger("BrandId"), doc.getInteger("Price"), doc.getString("Picture"), doc.getString("Description"),doc.getBoolean("Status")); else return null; } // Tìm sản phẩm theo category public List<Product> getProductCategory(int categoryId) { List<Product> products = new ArrayList<>(); MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("products"); Bson filter = new BsonDocument("CategoryId", new BsonInt32(categoryId)); MongoCursor<Document> cursor = collection.find(filter).cursor(); while (cursor.hasNext()) { Document doc = cursor.next(); products.add(new Product(doc.getString("_id"), doc.getString("ProductName"), doc.getInteger("CategoryId"), doc.getInteger("BrandId"), doc.getInteger("Price"), doc.getString("Picture"), doc.getString("Description"),doc.getBoolean("Status"))); } return products; } // Tìm sản phẩm theo Brand public List<Product> getProductBrand(int brandId) { List<Product> products = new ArrayList<>(); MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("products"); Bson filter = new BsonDocument("BrandId", new BsonInt32(brandId)); MongoCursor<Document> cursor = collection.find(filter).cursor(); while (cursor.hasNext()) { Document doc = cursor.next(); products.add(new Product(doc.getString("_id"), doc.getString("ProductName"), doc.getInteger("CategoryId"), doc.getInteger("BrandId"), doc.getInteger("Price"), doc.getString("Picture"), doc.getString("Description"),doc.getBoolean("Status"))); } return products; } // Tìm sản phẩm theo tên và category public List<Product> search(int categoryId, String name) { List<Product> products = new ArrayList<>(); MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("products"); Bson c1 = Filters.eq("CategoryId", categoryId); Bson c2 = Filters.regex("ProductName", "^.*" + name + ".*$"); MongoCursor<Document> cursor = null; if (categoryId == 0) cursor = collection.find(c2).cursor(); else cursor = collection.find(Filters.and(c1, c2)).cursor();// sử dụng Filters.or nếu muốn while (cursor.hasNext()) { Document doc = cursor.next(); products.add(new Product(doc.getString("_id"), doc.getString("ProductName"), doc.getInteger("CategoryId"), doc.getInteger("BrandId"), doc.getInteger("Price"), doc.getString("Picture"), doc.getString("Description"),doc.getBoolean("Status"))); } return products; } // Tìm sản phẩm theo tên và category public List<Product> search(Integer fromPrice, Integer toPrice) { List<Product> products = new ArrayList<>(); MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("products"); Bson c1 = Filters.gte("Price", fromPrice); Bson c2 = Filters.lte("Price", toPrice); MongoCursor<Document> cursor = null; if (fromPrice == 0 && toPrice>0) cursor = collection.find(c2).cursor(); else if (fromPrice > 0 && toPrice==0) cursor = collection.find(c1).cursor(); else cursor = collection.find(Filters.and(c1, c2)).cursor();// sử dụng Filters.or nếu muốn while (cursor.hasNext()) { Document doc = cursor.next(); products.add(new Product(doc.getString("_id"), doc.getString("ProductName"), doc.getInteger("CategoryId"), doc.getInteger("BrandId"), doc.getInteger("Price"), doc.getString("Picture"), doc.getString("Description"),doc.getBoolean("Status"))); } return products; } // thêm mới public void insert(Product p) { Document bson = new Document(); bson.append("_id", p.getProductId()); bson.append("ProductName", p.getProductName()); bson.append("CategoryId", p.getCategoryId()); bson.append("BrandId", p.getBrandId()); bson.append("Price", p.getPrice()); bson.append("Picture", p.getPicture()); bson.append("Description", p.getDescription()); bson.append("Status", p.isStatus()); MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("products"); collection.insertOne(bson); } // sửa public void update(Product p) { Document bson = new Document(); bson.append("_id", p.getProductId()); bson.append("ProductName", p.getProductName()); bson.append("CategoryId", p.getCategoryId()); bson.append("BrandId", p.getBrandId()); bson.append("Price", p.getPrice()); bson.append("Picture", p.getPicture()); bson.append("Description", p.getDescription()); bson.append("Status", p.isStatus()); Document updateData = new Document(); updateData.append("$set", bson); Bson filter = Filters.eq("_id", p.getProductId()); MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("products"); collection.updateOne(filter, updateData); } // xóa public void delete(String productId) { MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("products"); collection.deleteOne(new BsonDocument("_id", new BsonString(productId))); } //phân trang public ProductPage paging(int pageno, int pagesize) { ProductPage page=new ProductPage(); MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("products"); long records=collection.countDocuments(); MongoCursor<Document> cursor= collection.find().limit(pagesize).skip((pageno-1)*pagesize).cursor(); List<Product> products=new ArrayList<Product>(); while (cursor.hasNext()) { Document doc = cursor.next(); products.add(new Product(doc.getString("_id"), doc.getString("ProductName"), doc.getInteger("CategoryId"), doc.getInteger("BrandId"), doc.getInteger("Price"), doc.getString("Picture"), doc.getString("Description"),doc.getBoolean("Status"))); } page.setProducts(products); long total=records%pagesize==0?records/pagesize:(records/pagesize)+1; page.setPageSize(pagesize); page.setCurrentPage(pageno); page.setTotalPages(total); return page; } //lấy dữ liệu từ nhiều bảng public List<ProductModel> getProductFull(){ List<ProductModel> data=new ArrayList<ProductModel>(); MongoCollection<Document> collection = MongoFactory.getDatabase().getCollection("products"); MongoCursor<Document> cursor= collection.aggregate(Arrays.asList( new Document("$lookup",new Document("from","categories").append("localField","CategoryId").append("foreignField","_id").append("as","Categories")) )).cursor(); while(cursor.hasNext()) { Document doc = cursor.next(); data.add(new ProductModel(doc.getString("_id"),doc.getString("ProductName"), doc.getList("Categories",Document.class).get(0).getString("CategoryName"), doc.getInteger("Price"),doc.getString("Picture"),doc.getBoolean("Status"))); } return data; } } |
- Tạo lớp com.hanam88.controllers/ProductController.java (Controller xử lý luồng nghiệp vụ của product)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
package com.hanam88.controllers; import java.io.File; import java.io.IOException; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; 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 org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import com.hanam88.entities.Product; import com.hanam88.entities.ProductPage; import com.hanam88.services.ProductService; @Controller public class ProductController { @Resource(name="productService") ProductService productService; @RequestMapping(value={"/","trang-chu"}) public String index(Model model) { model.addAttribute("page", "products"); model.addAttribute("products",productService.getProductFull()); return "index"; } @RequestMapping(value="chi-tiet/{id}") public String detail(@PathVariable("id") String id, Model model) { model.addAttribute("page", "productdetail"); model.addAttribute("product",productService.getProduct(id)); return "index"; } @RequestMapping(value="tim-theo-danh-muc") public String searchcategory(Integer cateid, Model model) { model.addAttribute("page", "productcategory"); model.addAttribute("categories",productService.getCategories()); cateid=cateid==null?0:cateid; model.addAttribute("cateid",cateid); model.addAttribute("products",productService.getProductCategory(cateid)); return "index"; } @RequestMapping(value="tim-theo-ten") public String searchcategory(Integer cateid,String searchname, Model model) { model.addAttribute("page", "productsearchname"); model.addAttribute("categories",productService.getCategories()); cateid=cateid==null?0:cateid; model.addAttribute("cateid",cateid); model.addAttribute("searchname",searchname); model.addAttribute("products",productService.search(cateid, searchname)); return "index"; } @RequestMapping(value="tim-theo-gia") public String searchcategory(Integer fromPrice,Integer toPrice, Model model) { fromPrice=fromPrice==null?0:fromPrice; toPrice=toPrice==null?0:toPrice; model.addAttribute("page", "productsearchprice"); model.addAttribute("fromPrice",fromPrice); model.addAttribute("toPrice",toPrice); model.addAttribute("products",productService.search(fromPrice, toPrice)); return "index"; } @RequestMapping(value="them-moi") public String add(Model model) { model.addAttribute("product", new Product()); model.addAttribute("page", "add"); model.addAttribute("categories",productService.getCategories()); model.addAttribute("brands",productService.getBrands()); return "index"; } @RequestMapping(value = "luu", method = RequestMethod.POST) public String save(@ModelAttribute("product") Product product, @RequestParam("file") MultipartFile file, Model model, HttpServletRequest req) { if (file != null && !file.isEmpty()) { String uploadRootPath = req.getServletContext().getRealPath("resources/images"); File destination = new File(uploadRootPath + "/" + file.getOriginalFilename()); try { file.transferTo(destination); } catch (IllegalStateException | IOException e) { e.printStackTrace(); } product.setPicture("/images/"+file.getOriginalFilename()); } productService.insert(product); return "redirect:/trang-chu"; } @RequestMapping(value = "xoa/{id}") public String delete(@PathVariable("id") String id) { productService.delete(id); return "redirect:/trang-chu"; } @RequestMapping(value = "sua/{id}") public String edit(@PathVariable("id") String id, Model model) { model.addAttribute("categories", productService.getCategories()); model.addAttribute("brands", productService.getBrands()); model.addAttribute("product", productService.getProduct(id)); model.addAttribute("page", "edit"); return "index"; } @RequestMapping(value = "cap-nhat", method = RequestMethod.POST) public String update(@ModelAttribute("product") Product product,String pictureOld, @RequestParam("file") MultipartFile file, Model model, HttpServletRequest req) { if (file != null && !file.isEmpty()) { String uploadRootPath = req.getServletContext().getRealPath("resources/images"); File destination = new File(uploadRootPath + "/" + file.getOriginalFilename()); try { file.transferTo(destination); } catch (IllegalStateException | IOException e) { e.printStackTrace(); } product.setPicture("/images/"+file.getOriginalFilename()); }else { product.setPicture(pictureOld); } productService.update(product); return "redirect:/trang-chu"; } @RequestMapping(value = "phan-trang") public String paging(Integer pageno, Model model) { pageno = pageno == null ? 1 : pageno; model.addAttribute("page", "productpaging"); ProductPage productPage = productService.paging(pageno, 3); model.addAttribute("products", productPage.getProducts()); model.addAttribute("totalpage", productPage.getTotalPages()); model.addAttribute("currentpage", pageno); return "index"; } } |
- Tạo trang src/main/webapp/WEB-INF/views/index.jsp (hiển thị cấu trúc trang chủ mặc định hiển thị tất cả các sản phẩm)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Spring MVC với MongoDB</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/css/bootstrap.min.css" /> <script src="${pageContext.servletContext.contextPath}/resources/ckeditor/ckeditor.js"></script> <style> #content { padding: 10px; } </style> </head> <body> <div class="container"> <nav class="nav"> <a class="nav-link active" href="${pageContext.servletContext.contextPath}/trang-chu">Trang chủ</a> | <a class="nav-link" href="${pageContext.servletContext.contextPath}/tim-theo-danh-muc">Lọc theo danh mục</a> | <a class="nav-link" href="${pageContext.servletContext.contextPath}/tim-theo-ten">Tìm kiếm theo tên</a> | <a class="nav-link" href="${pageContext.servletContext.contextPath}/tim-theo-gia">Tìm kiếm theo giá</a> | <a class="nav-link" href="${pageContext.servletContext.contextPath}/phan-trang">Phân trang</a> </nav> <hr> <div id="content"> <c:if test="${!(empty page)}"> <jsp:include page="${page}.jsp"></jsp:include> </c:if> </div> </div> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js@1.12.9/dist/umd/popper.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.0.0/dist/js/bootstrap.min.js"></script> </body> </html> |
- Tạo trang src/main/webapp/WEB-INF/views/products.jsp (hiển thị tất cả các sản phẩm và include vào trang index.jsp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<%@ 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="f" uri="http://java.sun.com/jsp/jstl/fmt"%> <h4>Hiển thị tất sản phẩm</h4> <span style="color:blue">${msg}</span> <p><a href="them-moi" class="btn btn-primary">Thêm mới</a></p> <table class="table table-bordered"> <tr> <th>Mã sản phẩm</th> <th>Tên sản phẩm</th> <th>Loại sản phẩm</th> <th>Giá</th> <th>Ảnh</th> <th>Tình trạng</th> <th></th> </tr> <c:forEach items="${products}" var="p"> <tr> <td>${p.productId}</td> <td>${p.productName}</td> <td>${p.categoryName}</td> <td>${p.price}</td> <td><img src="resources${p.picture}" width="100"/></td> <td><c:choose> <c:when test="${p.status==true}"> Còn hàng </c:when> <c:otherwise> Hết hàng </c:otherwise> </c:choose> </td> <td> <a href="sua/${p.productId}" class="btn btn-info">Sửa</a> <a href="xoa/${p.productId}" class="btn btn-danger" onclick="return confirm('Bạn có muốn xóa không?')">Xóa</a> <a href="chi-tiet/${p.productId}" class="btn btn-success">Chi tiết</a> </td> </tr> </c:forEach> </table> |
- Tạo trang src/main/webapp/WEB-INF/views/add.jsp (thêm mới sản phẩm và include vào trang index.jsp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <h3>Thêm mới sản phẩm</h3> <form:form action="luu" method="post" modelAttribute="product" enctype="multipart/form-data"> <table class="table"> <tr> <td>Mã sản phẩm</td> <td><form:input path="productId" /></td> </tr> <tr> <td>Tên sản phẩm</td> <td><form:input path="productName" /></td> </tr> <tr> <td>Loại sản phẩm</td> <td><form:select path="categoryId" items="${categories}" itemValue="categoryId" itemLabel="categoryName"></form:select> </td> </tr> <tr> <td>Thương hiệu</td> <td><form:select path="brandId" items="${brands}" itemValue="brandId" itemLabel="brandName"></form:select> </td> </tr> <tr> <td>Giá</td> <td><form:input path="price" value="0" /></td> </tr> <tr> <td>Mô tả đầy đủ</td> <td><form:textarea path="description"></form:textarea></td> </tr> <tr> <td>Ảnh</td> <td><input type="file" name="file" /></td> </tr> <tr> <td>Tình trạng</td> <td><form:checkbox path="status" checked="checked" />Còn hàng</td> </tr> <tr> <td colspan="2"><button>Lưu</button></td> </tr> </table> </form:form> <script> CKEDITOR.replace('description') </script> |
- Tạo trang src/main/webapp/WEB-INF/views/edit.jsp (sửa sản phẩm và include vào trang index.jsp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<%@ 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"%> <h3>Sửa sản phẩm</h3> <form:form action="${pageContext.servletContext.contextPath}/cap-nhat" method="post" modelAttribute="product" enctype="multipart/form-data"> <input type="hidden" name="pictureOld" value="${product.picture}" /> <table class="table"> <tr> <td>Mã sản phẩm</td> <td><form:input path="productId" /></td> </tr> <tr> <td>Tên sản phẩm</td> <td><form:input path="productName" /></td> </tr> <tr> <td>Loại sản phẩm</td> <td><form:select path="categoryId" items="${categories}" itemValue="categoryId" itemLabel="categoryName"></form:select></td> </tr> <tr> <td>Thương hiệu</td> <td><form:select path="brandId" items="${brands}" itemValue="brandId" itemLabel="brandName"></form:select></td> </tr> <tr> <td>Giá</td> <td><form:input path="price"/></td> </tr> <tr> <td>Mô tả đầy đủ</td> <td><form:textarea path="description"></form:textarea></td> </tr> <tr> <td>Ảnh</td> <td><input type="file" name="file" /></td> </tr> <tr> <td>Tình trạng</td> <td><form:checkbox path="status"/>Còn hàng</td> </tr> <tr> <td colspan="2"><button>Lưu</button></td> </tr> </table> </form:form> <script> CKEDITOR.replace('description') </script> |
- Tạo trang src/main/webapp/WEB-INF/views/productdetail.jsp (hiển thị chi tiết sản phẩm và include vào trang index.jsp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<%@ 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="f" uri="http://java.sun.com/jsp/jstl/fmt"%> <h4>CHI TIẾT SẢN PHẨM</h4> <div class="row" style="border: 1px gray solid;border-radius:5px;"> <div class="col-3"> <img src="${pageContext.servletContext.contextPath}/resources${product.picture}" width="95%" /> </div> <div class="col-9"> <p>${product.productName}</p> <p> Giá mới:<f:formatNumber value="${product.price}" /> đ </p> <p>Loại: ${product.categoryId}</p> <p>Thương hiệu: ${product.brandId}</p> </div> <div class="col-12"> <h4>Mô tả</h4> <p>${product.description}</p> <p><a href="javascript:history.back()">Quay lại</a> </div> </div> |
- Tạo trang src/main/webapp/WEB-INF/views/productcategory.jsp (hiển thị các sản phẩm theo loại và include vào trang index.jsp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<%@ 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="f" uri="http://java.sun.com/jsp/jstl/fmt"%> <h4>Tìm kiếm theo danh mục sản phẩm</h4> <form action="" method="post"> <select name="cateid" onchange="forms[0].submit()" class="form-control"> <option value="0">---------Chọn danh mục sản phẩm---------</option> <c:forEach var="c" items="${categories}"> <c:choose> <c:when test="${c.categoryId==cateid}"> <option value="${c.categoryId}" selected>${c.categoryName}</option> </c:when> <c:otherwise> <option value="${c.categoryId}">${c.categoryName}</option> </c:otherwise> </c:choose> </c:forEach> </select> </form> <hr> <table class="table table-bordered"> <tr> <th>Mã sản phẩm</th> <th>Tên sản phẩm</th> <th>Giá</th> <th>Ảnh</th> <th>Tình trạng</th> <th></th> </tr> <c:forEach items="${products}" var="p"> <tr> <td>${p.productId}</td> <td>${p.productName}</td> <td>${p.price}</td> <td><img src="resources${p.picture}" width="100"/></td> <td><c:choose> <c:when test="${p.status==true}"> Còn hàng </c:when> <c:otherwise> Hết hàng </c:otherwise> </c:choose> </td> </tr> </c:forEach> </table> |
- Tạo trang src/main/webapp/WEB-INF/views/productsearchname.jsp (tìm kiếm sản phẩm theo tên - loại và include vào trang index.jsp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<%@ 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="f" uri="http://java.sun.com/jsp/jstl/fmt"%> <h4>Tìm kiếm theo loại và tên</h4> <form action="" method="post"> Chọn loại hoa <select name="cateid"> <option value="0">---------Chọn danh mục sản phẩm---------</option> <c:forEach var="c" items="${categories}"> <c:choose> <c:when test="${c.categoryId==cateid}"> <option value="${c.categoryId}" selected>${c.categoryName}</option> </c:when> <c:otherwise> <option value="${c.categoryId}">${c.categoryName}</option> </c:otherwise> </c:choose> </c:forEach> </select> <input type="text" name="searchname" value="${searchname}" placeholder="Nhập tên cần tìm"/> <button class="btn btn-primary key">Tìm</button> </form> <hr> <table class="table table-bordered"> <tr> <th>Mã sản phẩm</th> <th>Tên sản phẩm</th> <th>Giá</th> <th>Ảnh</th> <th>Tình trạng</th> <th></th> </tr> <c:forEach items="${products}" var="p"> <tr> <td>${p.productId}</td> <td>${p.productName}</td> <td>${p.price}</td> <td><img src="resources${p.picture}" width="100"/></td> <td><c:choose> <c:when test="${p.status==true}"> Còn hàng </c:when> <c:otherwise> Hết hàng </c:otherwise> </c:choose> </td> </tr> </c:forEach> </table> |
- Tạo trang src/main/webapp/WEB-INF/views/productsearchprice.jsp (tìm kiếm sản phẩm theo khoảng giá và include vào trang index.jsp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<%@ 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="f" uri="http://java.sun.com/jsp/jstl/fmt"%> <h4>Tìm kiếm theo khoảng giá</h4> <form action="tim-theo-gia" method="post"> Nhập giá từ <input type="number" name="fromPrice" value="${fromPrice}"/> đến giá <input type="number" name="toPrice" value="${toPrice}"/> <button class="btn btn-primary key">Tìm</button> </form> <hr> <table class="table table-bordered"> <tr> <th>Mã sản phẩm</th> <th>Tên sản phẩm</th> <th>Giá</th> <th>Ảnh</th> <th>Tình trạng</th> <th></th> </tr> <c:forEach items="${products}" var="p"> <tr> <td>${p.productId}</td> <td>${p.productName}</td> <td>${p.price}</td> <td><img src="resources${p.picture}" width="100"/></td> <td><c:choose> <c:when test="${p.status==true}"> Còn hàng </c:when> <c:otherwise> Hết hàng </c:otherwise> </c:choose> </td> </tr> </c:forEach> </table> |
- Tạo trang src/main/webapp/WEB-INF/views/productpaging.jsp (phân trang sản phẩm và include vào trang index.jsp)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<%@ 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="f" uri="http://java.sun.com/jsp/jstl/fmt"%> <h4>Phân trang sản phẩm</h4> <hr> <table class="table table-bordered"> <tr> <th>Mã sản phẩm</th> <th>Tên sản phẩm</th> <th>Giá</th> <th>Ảnh</th> <th>Tình trạng</th> </tr> <c:forEach items="${products}" var="p"> <tr> <td>${p.productId}</td> <td>${p.productName}</td> <td>${p.price}</td> <td><img src="resources${p.picture}" width="100"/></td> <td><c:choose> <c:when test="${p.status==true}"> Còn hàng </c:when> <c:otherwise> Hết hàng </c:otherwise> </c:choose> </td> </tr> </c:forEach> </table> Trang: <c:forEach var="i" begin="1" end="${totalpage}"> <c:choose> <c:when test="${i==currentpage}"> <span> ${i} </span> </c:when> <c:otherwise> <a href="phan-trang?pageno=${i}"> ${i} </a> </c:otherwise> </c:choose> </c:forEach> |
Bước 8: Run và kiểm tra kết quả
- Màn hình hiển thị tất cả các sản phẩm với các nút thêm/xóa/sửa/xem chi tiết
- Màn hình thêm sản phẩm
- Màn hình sửa sản phẩm
- Màn hình chi tiết sản phẩm
- Màn hình lọc sản phẩm theo danh mục
- Màn hình tìm kiếm theo loại và tên
- Màn hình tìm kiếm theo khoảng giá
- Màn hình phân trang sản phẩm
Link tải source code
Video đang quay
thay lời cảm ơn!
Các bài cũ hơn
- Các thao tác cơ bản CRUD-Tìm kiếm-Phân trang trong Spring MVC-Hibernate-SQL Server (11:41 PM - 28/02/2024)
- [Java-Web] Tìm hiểu về đa ngôn ngữ với Internationalization và Localization trong JSP Servlet sử dụng thư viện JSTL (04:50 PM - 26/02/2024)
- [Java Web] Lọc, phân trang, tìm kiếm dữ liệu với SQL Server trong JSP Servlet (09:24 AM - 23/02/2024)
- [Java Web] Upload file-Tích hợp CKEditor vào JSP Servlet (03:38 PM - 20/02/2024)
- [Java Web] Thêm-Xóa-Sửa dữ liệu trong SQL Server sử dụng JDBC và JSP Servlet (04:20 PM - 19/02/2024)