Java EE Web Application (JSP/Servlet, EJB, JPA, SQL Server, Glassfish) With Many-To-Many Relationship

 Ứng dụng Java EE Web (JSP/Servlet, EJB, JPA, SQL Server, Glassfish) với quan hệ nhiều nhiều


Bài viết này mình sẽ hướng dẫn các bạn tạo ứng dụng quản lý user và role (many-to-many realationship) với Java EE và lưu dữ liệu ở MS SQL Server.
Đầu tiên trong SQL Server các bạn tạo database như sau:
CREATE DATABASE UserManagement
GO

USE UserManagement
GO

CREATE TABLE users(
	username VARCHAR(20) PRIMARY KEY,
	password VARCHAR(20)
)

CREATE TABLE roles(
	rolename VARCHAR(20) PRIMARY KEY,
	description VARCHAR(50)
)

CREATE TABLE userInRole(
	username VARCHAR(20) REFERENCES users(username),
	rolename VARCHAR(20) REFERENCES roles(rolename)
)

INSERT INTO roles values('admin', 'admin role')
INSERT INTO roles values('user', 'user role')

Tiếp theo ở Glassfish Server các bạn có thể tạo hoặc thay đổi tên database connect pool hoặc tái sử dụng SQLPool như ở bài viết: https://javadocfast.blogspot.com/2021/06/java-ee-web-application-jsp-servlet-ejb-jpa-sql-server-glassfish.html

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



Project sinh ra các phần gồm UserManagement, UserManagement-ejb và UserManagement-war:

Đầu tiên chúng ta sẽ xử lý phần UserManagement-ejb trước.
Cấu trúc source code UserManagement-ejb:
                

Package entity
: chứa các entity được map với các bảng trong cơ sở dữ liệu.
Package bean: chứa các session để gọi các entity bean khi có yêu cầu từ client.

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




Vì bảng userInRole không có khoá chính nên khi generate entity chỉ generate ra 2 entity Roles Users với quan hệ nhiều nhiều.

Tạo Session Beans For Entity Classes...:
Tại UserManagement-ejb => chuột phải vào New => Orther... => Enterprise JavaBeans => Session Beans For Entity Classes => Next





Tại UsersFacade.java mình tạo thêm hàm thêm role cho user:
Trong UsersFacade.java chuột phải chọn Insert Code... => Add Buissiness Method...

UsersFacade.java:
package bean;

import entity.Roles;
import entity.Users;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author Admin
 */
@Stateless
public class UsersFacade extends AbstractFacade<Users> implements UsersFacadeLocal {

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

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

    public UsersFacade() {
        super(Users.class);
    }

    @Override
    public void addRolesForUser(String username, String rolename) {
        Users users = em.find(Users.class, username);
        Roles roles = em.find(Roles.class, rolename);

        users.getRolesCollection().add(roles);
        roles.getUsersCollection().add(users);
    }
}
Tiếp theo mình sẽ xử lý phần UserManagement-war:
Cấu trúc source code UserManagement-war:
MainController.java: là 1 servlet xử lý yêu cầu.
show.jsp: hiển thị trang chủ bao gồm đường dẫn tạo mới user và search user.
create.jsp: chứa form tạo 1 user mới.
showUserRole.jsp: hiển thị các quyền của user được tìm thấy.

MainConroller.java:
package controller;

import bean.RolesFacadeLocal;
import bean.UsersFacadeLocal;
import entity.Roles;
import entity.Users;
import java.io.IOException;
import java.util.List;
import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "MainController", urlPatterns = {"/MainController"})
public class MainController extends HttpServlet {
    
    @EJB
    private UsersFacadeLocal usersFacade;
    
    @EJB
    private RolesFacadeLocal rolesFacade;
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        
        try {
            String view = request.getParameter("view");
            
            if (view == null) {
                show(request, response);
            } else {
                switch (view) {
                    case "create":
                        create(request, response);
                        break;
                    case "insert":
                        insert(request, response);
                        break;
                    case "showUserWithRole":
                        showUserWithRole(request, response);
                        break;
                    case "show":
                    default:
                        show(request, response);
                        break;
                }
            }
        } catch (IOException | ServletException e) {
            System.out.println(e.getMessage());
        }
    }    
    
    private void show(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.getRequestDispatcher("show.jsp").forward(request, response);
    }
    
    private void create(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        List<Roles> roles = rolesFacade.findAll();
        request.setAttribute("roles", roles);
        request.getRequestDispatcher("create.jsp").forward(request, response);
    }
    
    private void insert(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String[] roles = request.getParameterValues("roles");
        Users users = new Users();
        users.setUsername(username);
        users.setPassword(password);
        usersFacade.create(users);
        for (int i = 0; i < roles.length; i++) {
            usersFacade.addRolesForUser(username, roles[i]);
        }
        response.sendRedirect("MainController?view=show");
    }
    
    private void showUserWithRole(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String username = request.getParameter("username");
        Users users = usersFacade.find(username);
        if (users != null) {
            List<Roles> roles = (List<Roles>) users.getRolesCollection();
            request.setAttribute("username", username);
            request.setAttribute("roles", roles);
            request.getRequestDispatcher("showUserRole.jsp").forward(request, response);
        } else {
            response.sendRedirect("MainController?view=show");
        }
    }
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }    
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
    
}
index.jsp:
<jsp:forward page="UserController?view=show"/>
show.jsp:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>User Management</title>
    </head>
    <body>
        <h1>User Management</h1>
        <a href="MainController?view=create">Create new user</a><br/><br/>
        <form action="MainController?view=showUserWithRole" method="POST">
            Search by username: <input type="text" name="username">
            <input type="submit" value="Search">
        </form>
    </body>
</html>
create.jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>User Management</title>
    </head>
    <body>
        <h1>Create new user</h1>
        <form action="MainController?view=insert" method="POST">
            Username: <input type="text" name="username"><br/><br/>
            Password: <input type="password" name="password"><br/><br/>
            <c:forEach items="${roles}" var="role">
                <input type="checkbox" value="${role.rolename}" name="roles">${role.rolename}<br/>
            </c:forEach><br/>
            <input type="submit" value="Save">
        </form>
    </body>
</html>
showUserRole.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>User Management</title>
    </head>
    <body>
        <h1>Hi ${username}</h1>
        <table border="1">
            <tr>
                <th>Rolename</th>
                <th>Description</th>
            </tr>
            <c:forEach items="${roles}" var="role">
                <tr>
                    <td>${role.rolename}</td>
                    <td>${role.description}</td>
                </tr>
            </c:forEach>
        </table>
    </body>
</html>
Chạy ứng dụng:
Dữ liệu trước khi chạy:
Chạy ứng dụng:
Dữ liệu sau khi chạy:
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