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 và 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