Java EE Web Application(JavaServer Faces, EJB, JPA, SQL Server, Glassfish) With Search Function

 Ứng dụngJava EE Web (JavaServer Faces, EJB, JPA, SQL Server, Glassfish) với chức năng tìm kiếm


Tạo database tên Shopee và copy đoạn script bên dưới chạy:


USE [Shopee]
GO
/****** Object:  Table [dbo].[category]    Script Date: 6/1/2021 11:13:07 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[category](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[name] [varchar](50) NULL,
 CONSTRAINT [PK_category] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[product]    Script Date: 6/1/2021 11:13:07 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[product](
	[id] [int] IDENTITY(1,1) NOT NULL,
	[name] [varchar](50) NULL,
	[price] [float] NULL,
	[cat_id] [int] NULL,
 CONSTRAINT [PK_product] PRIMARY KEY CLUSTERED 
(
	[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[category] ON 
INSERT [dbo].[category] ([id], [name]) VALUES (1, N'phone')
INSERT [dbo].[category] ([id], [name]) VALUES (2, N'laptop')
SET IDENTITY_INSERT [dbo].[category] OFF
SET IDENTITY_INSERT [dbo].[product] ON 
INSERT [dbo].[product] ([id], [name], [price], [cat_id]) VALUES (1, N'iphone sx 2021', 20000, 1)
INSERT [dbo].[product] ([id], [name], [price], [cat_id]) VALUES (2, N'lenovo w540', 50000, 2)
INSERT [dbo].[product] ([id], [name], [price], [cat_id]) VALUES (3, N'samsung galaxy', 25000, 1)
SET IDENTITY_INSERT [dbo].[product] OFF
ALTER TABLE [dbo].[product]  WITH CHECK ADD  CONSTRAINT [FK_product_category] FOREIGN KEY([cat_id])
REFERENCES [dbo].[category] ([id])
ON UPDATE CASCADE
GO
ALTER TABLE [dbo].[product] CHECK CONSTRAINT [FK_product_category]
GO
Tạo hoặc thay đổi tên database connect pool với glassfish4 tái sử dụng SQLPoolbài trước:

Tạo project EJB:
Chọn File -> New Project... -> Java EE -> Enterprise Application -> Next



Tạo Entity Classes from Database:
Tại ProductManagement-ejb => chuột phải chọn New => Other... => Persistence => Entity Classes from Database => Next




Tạo Session Beans For Entity Classes...:
Tại ProductManagement-ejb => chuột phải chọn New => Other... => Enterprise JavaBeans => Session Beans For Entity Classes => Next



Trong CategoryFacade.java và ProductFacade.java thêm lệnh để xoá cache:

Trong ProductFacade.java thêm hàm search:
Trong ProductFacade.java chuột phải chọn Insert Code... -> Add Business Method...


ProductFacade.java:
package bean;

import entity.Product;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class ProductFacade extends AbstractFacade<Product> implements ProductFacadeLocal {

    @PersistenceContext(unitName = "ProductManagement-ejbPU")
    private EntityManager em;

    @Override
    protected EntityManager getEntityManager() {
        em.getEntityManagerFactory().getCache().evictAll();
        return em;
    }

    public ProductFacade() {
        super(Product.class);
    }

    @Override
    public List<Product> searchByPriceBetween(int from, int to) {
        Query q  = em.createQuery("SELECT p FROM Product p WHERE p.price >= :from AND p.price <= :to");
        q.setParameter("from", from);
        q.setParameter("to", to);
        return q.getResultList();
    } 
}
Thêm JSF Framework: chuột phải vào ProductManagement-war -> Properties -> Frameworks -> Add -> JavaServer Faces



Sau khi thêm JSF Framework nó sẽ thêm web.xml:
<?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>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>
Tạo JSF Managed Bean: chuột phải vào ProductManagement-war -> New -> Orther... -> JavaServer Faces -> Next

ProductJSFManagedBean.java:
package controller;

import bean.CategoryFacadeLocal;
import bean.ProductFacadeLocal;
import entity.Category;
import entity.Product;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import java.util.List;
import javax.ejb.EJB;

@Named(value = "product")
@SessionScoped
public class ProductJSFManagedBean implements Serializable {

    @EJB
    private ProductFacadeLocal productFacade;

    @EJB
    private CategoryFacadeLocal categoryFacade;

    private List<Product> products;
    private List<Category> categories;
    private Product crudProduct;
    private Category crudCategory;
    private int from;
    private int to;
    private int crudCatId;

    public ProductJSFManagedBean() {
    }

    public List<Product> getProducts() {
        return products;
    }

    public void setProducts(List<Product> products) {
        this.products = products;
    }

    public List<Category> getCategories() {
        return categories;
    }

    public void setCategories(List<Category> categories) {
        this.categories = categories;
    }

    public Product getCrudProduct() {
        return crudProduct;
    }

    public void setCrudProduct(Product crudProduct) {
        this.crudProduct = crudProduct;
    }

    public Category getCrudCategory() {
        return crudCategory;
    }

    public void setCrudCategory(Category crudCategory) {
        this.crudCategory = crudCategory;
    }

    public int getFrom() {
        return from;
    }

    public void setFrom(int from) {
        this.from = from;
    }

    public int getTo() {
        return to;
    }

    public void setTo(int to) {
        this.to = to;
    }

    public int getCrudCatId() {
        return crudCatId;
    }

    public void setCrudCatId(int crudCatId) {
        this.crudCatId = crudCatId;
    }

    public String show() {
        crudCatId = 0;
        products = productFacade.findAll();
        categories = categoryFacade.findAll();
        return "show?faces-redirect=true";
    }

    public String create() {
        crudCatId = 0;
        categories = categoryFacade.findAll();
        crudProduct = new Product();
        return "create?faces-redirect=true";
    }

    public String insert() {
        Category category = categoryFacade.find(crudCatId);
        crudProduct.setCatId(category);
        productFacade.create(crudProduct);
        return show();
    }

    public String edit(Product product) {
        crudProduct = product;
        crudCatId = product.getCatId().getId();
        return "edit?faces-redirect=true";
    }

    public String update() {
        Category category = categoryFacade.find(crudCatId);
        crudProduct.setCatId(category);
        productFacade.edit(crudProduct);
        return show();
    }

    public String delete(Product product) {
        productFacade.remove(product);
        return show();
    }

    public String searchByPrice() {
        if (from < to) {
            products = productFacade.searchByPriceBetween(from, to);
            return "show?faces-redirect=true";
        } else {
            return show();
        }
    }

    public String searchByCatId() {
        if (crudCatId != 0) {
            products = (List<Product>) categoryFacade.find(crudCatId).getProductCollection();
            return "show?faces-redirect=true";
        } else {
            return show();
        }
    }
}
CategoryJSFManagedBean.java:
Sử dụng @Inject để nhúng ProductJSFManagedBean vào
package controller;

import bean.CategoryFacadeLocal;
import entity.Category;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.inject.Inject;

@Named(value = "category")
@SessionScoped
public class CategoryJSFManagedBean implements Serializable {

    @EJB
    private CategoryFacadeLocal categoryFacade;
    
    @Inject
    private ProductJSFManagedBean productJSFManagedBean;
    
    private Category crudCat;
    
    public CategoryJSFManagedBean() {
    }

    public Category getCrudCat() {
        return crudCat;
    }

    public void setCrudCat(Category crudCat) {
        this.crudCat = crudCat;
    }
    
    public String create(){
        crudCat = new Category();
        return "createCat?faces-redirect=true";
    }
    
    public String insert(){
        categoryFacade.create(crudCat);
        return productJSFManagedBean.show();
    }
    
}
index.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Product Management</title>
    </h:head>
    <h:body>
        <f:view>
            <h:form>
                <h:commandLink value="Show product" action="#{product.show()}"/>
            </h:form>
        </f:view>
    </h:body>
</html>

show.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Product Management</title>
    </h:head>
    <h:body>
        <f:view>
            <h:form>
                <h1><h:outputText value="Product List"/></h1>
                <div>
                    Price<h:inputText value="#{product.from}"/>-<h:inputText value="#{product.to}"/>
                    <h:commandButton value="Filter" action="#{product.searchByPrice()}"/>
                </div>
                <div>
                    <h:outputLabel value="Search By Category" for="catId" />
                    <h:selectOneMenu id="catId" value="#{product.crudCatId}" title="CatId" >
                        <f:selectItem itemLabel="---Select---" itemValue="#{0}" noSelectionOption="true"/>
                        <f:selectItems value="#{product.categories}" var="cat" itemValue="#{cat.id}" itemLabel="#{cat.name}"/>
                    </h:selectOneMenu>
                    <h:commandButton value="Search" action="#{product.searchByCatId()}"/>
                </div>
                <h:commandLink value="Create new product" action="#{product.create()}"/> | 
                <h:commandLink value="Create new category" action="#{category.create()}"/>
                <h:dataTable value="#{product.products}" var="item" border="1">
                    <h:column>
                        <f:facet name="header">
                            <h:outputText value="Id"/>
                        </f:facet>
                        <h:outputText value="#{item.id}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText value="Name"/>
                        </f:facet>
                        <h:outputText value="#{item.name}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText value="Price"/>
                        </f:facet>
                        <h:outputText value="#{item.price}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText value="Category"/>
                        </f:facet>
                        <h:outputText value="#{item.catId.name}"/>
                    </h:column>
                    <h:column>
                        <f:facet name="header">
                            <h:outputText value="Action"/>
                        </f:facet>
                        <h:commandLink value="Delete" action="#{product.delete(item)}"/> | 
                        <h:commandLink value="Edit" action="#{product.edit(item)}"/>
                    </h:column>
                </h:dataTable>
            </h:form>
        </f:view>
    </h:body>
</html>

create.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Product Management</title>
    </h:head>
    <h:body>
        <f:view>
            <h:form>
                <h1><h:outputText value="Create new product"/></h1>
                <h:panelGrid columns="2">
                    <h:outputLabel value="Name:" for="name" />
                    <h:inputText id="name" value="#{product.crudProduct.name}" title="Name" />
                    <h:outputLabel value="Price:" for="price" />
                    <h:inputText id="price" value="#{product.crudProduct.price}" title="Price" />
                    <h:outputLabel value="Category:" for="catId" />
                    <h:selectOneMenu id="catId" value="#{product.crudCatId}" title="CatId" >
                        <f:selectItem itemLabel="---Select---" itemValue="#{null}" noSelectionOption="true"/>
                        <f:selectItems value="#{product.categories}" var="cat" itemValue="#{cat.id}" itemLabel="#{cat.name}"/>
                    </h:selectOneMenu>
                </h:panelGrid>
                <h:commandButton value="Save" action="#{product.insert()}"/>
            </h:form>
        </f:view>

    </h:body>
</html>
edit.xhml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Product Management</title>
    </h:head>
    <h:body>
        <f:view>
            <h:form>
                <h1><h:outputText value="Update product"/></h1>
                <h:panelGrid columns="2">
                    <h:outputLabel value="Id:" for="id" />
                    <h:inputText id="id" value="#{product.crudProduct.id}" title="Id" readonly="true"/>
                    <h:outputLabel value="Name:" for="name" />
                    <h:inputText id="name" value="#{product.crudProduct.name}" title="Name"/>
                    <h:outputLabel value="Price:" for="price" />
                    <h:inputText id="price" value="#{product.crudProduct.price}" title="Price" />
                    <h:outputLabel value="Category:" for="catId" />
                    <h:selectOneMenu id="catId" value="#{product.crudCatId}" title="CatId" >
                        <f:selectItem itemLabel="---Select---" itemValue="#{null}" noSelectionOption="true"/>
                        <f:selectItems value="#{product.categories}" var="cat" itemValue="#{cat.id}" itemLabel="#{cat.name}"/>
                    </h:selectOneMenu>
                </h:panelGrid>
                <h:commandButton value="Save" action="#{product.update()}"/>
            </h:form>
        </f:view>

    </h:body>
</html>
createCat.xhtml
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Product Management</title>
    </h:head>
    <h:body>
        <f:view>
            <h:form>
                <h1><h:outputText value="Create new category"/></h1>
                <h:panelGrid columns="2">
                    <h:outputLabel value="Name:" for="name" />
                    <h:inputText id="name" value="#{category.crudCat.name}" title="Name" />
                </h:panelGrid>
                <h:commandButton value="Save" action="#{category.insert()}"/>
            </h:form>
        </f:view>

    </h:body>
</html>

Giao diện các trang:


Demo chức năng tìm kiếm theo giá:

Demo chức năng tìm kiếm theo category:

Cấu trúc ProductManagement-war:

Lưu ý : sau khi code xong hoặc fix code, chỉ cần Clean and Build, sau đó Run module kim tử tháp là chạy được

Nhận xét

Bài đăng phổ biến từ blog này

Java EE Web Application (JSP/Servlet, EJB, JPA, SQL Server, Glassfish) Full Tutorial

Build validation using VanillaJS for Form Submit

Java EE Web Application (JavaServer Faces, EJB, JPA, SQL Server, Glassfish) Full Tutorial