CÔNG NGHỆ THÔNG TIN >> BÀI VIẾT CHỌN LỌC

Hibernate One to Many Mapping trong Spring Web MVC và cơ sở dữ liệu Oracle

Đăng lúc: 08:01 PM - 26/10/2023 bởi Charles Chung - 731

Trong bài viết này tôi sẽ hướng dẫn các bạn cách tạo quan hệ One to Many Mapping cho các Entity trong Hibernate, demo sử dụng Spring Web MVC và cơ sở dữ liệu Oracle, ngoài ra còn sử dụng thư viện xử lý upload ảnh kèm dữ liệu.

1. Kiến thức cần có

  • Căn bản về Oracle database, cách cài đặt cơ sở dữ liệu Oracle, công cụng SQL Developer, tạo database xem ở đây
  • Lập trình Java Core
  • HTML - CSS - JavaScript
  • JSP và Servlet

2. Các bước tạo ứng dụng Spring Hibernate và thực hiện các thao tác CRUD

Bước 1: Mở SQL Developer tạo bảng và nhập dữ liệu ( xem file db.sql đính kèm trong source code)

Bước 2: Tạo Dynamic Web Project

  • Khởi động Eclispe IDE -> vào menu File -> New -> Dynamic Web Project -> Nhập tên project "MappingJoinSpringHibernateOracle"
  • Tiếp tục kích vào Next -> Next -> Chọn Generate web.xml deyployment desciptor và kích Finish

Bước 3: Convert sang Maven Project

  • Kích chuột phải vào Project vừa tạo -> Configure -> Convert to Maven Project -> Finish

Bước 4: Khai báo các Maven Dependencies cần thiết

  • Mở file pom.xml và cấu hình các Maven Dependencies gồm: spring web, web mvc, spring-orm, hibernate, jdbc oracle, servlet api, jstl (xem bài trước), bổ sung thêm upload file dependency vào nhé

<!--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>

Bước 5: Cấu hình ứng dụng Spring Web Mvc

  • Trong thư mục WEB-INF tạo thư mục views và tệp tin spring-servlet.xml (xem bài trước), bổ sung thêm đoạn cấu hình sau

<!-- Cấu hình đường dẫn tài nguyên được phép truy cập trong thư mục gốc -->

<mvc:resources mapping="/**" location="/" />

<!-- Tạo bean xác định dữ liệu multipart khi upload file -->

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />

  • Mở tệp web.xml và cấu hình vào bên trong thẻ <web-app> (xem bài trước)

Bước 6: Tạo các tệp tin theo cấu trúc mô tả sau

 

Bước 7: Code cho các tệp theo gợi ý sau

  • Tệp entities/Emloyee.java

package entities;

import java.io.Serializable;

import java.util.Date;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.FetchType;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.ManyToOne;

import javax.persistence.Table;

import javax.persistence.Temporal;

import javax.persistence.TemporalType;

import org.springframework.format.annotation.DateTimeFormat;

@Entity

@Table(name="employees")

public class Employee implements Serializable {

@Id

@Column(name="employeeid")

private String employeeId;

@Column(name="fullname")

private String fullName;

@Column(name="birthday")

@Temporal(value = TemporalType.DATE)

@DateTimeFormat(pattern = "dd/MM/yyyy")

private Date birthDay;

@Column(name="picture")

private String picture;

@Column(name="gender")

private int gender;

@Column(name="address")

private String address;

@Column(name="phone")

private String phone;

@Column(name="email")

private String email;

@Column(name="departmentid")

private int departmentId;

@Column(name="active")

private int active;

@ManyToOne(fetch = FetchType.LAZY) // khi nào cần thì load phòng ban theo nhân viên

@JoinColumn(name="departmentId",insertable = false, updatable = false)

private Department department;

public Employee() {

// TODO Auto-generated constructor stub

}

public String getEmployeeId() {

return employeeId;

}

public void setEmployeeId(String employeeId) {

this.employeeId = employeeId;

}

public String getFullName() {

return fullName;

}

public void setFullName(String fullName) {

this.fullName = fullName;

}

public Date getBirthDay() {

return birthDay;

}

public void setBirthDay(Date birthDay) {

this.birthDay = birthDay;

}

public String getPicture() {

return picture;

}

public void setPicture(String picture) {

this.picture = picture;

}

public int getGender() {

return gender;

}

public void setGender(int gender) {

this.gender = gender;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

public String getPhone() {

return phone;

}

public void setPhone(String phone) {

this.phone = phone;

}

public String getEmail() {

return email;

}

public void setEmail(String email) {

this.email = email;

}

public int getDepartmentId() {

return departmentId;

}

public void setDepartmentId(int departmentId) {

this.departmentId = departmentId;

}

public int getActive() {

return active;

}

public void setActive(int active) {

this.active = active;

}

public Department getDepartment() {

return department;

}

public void setDepartment(Department department) {

this.department = department;

}

}

  • Tệp entities/Department.java

package entities;

import java.io.Serializable;

import java.util.List;

import javax.persistence.CascadeType;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.FetchType;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.OneToMany;

import javax.persistence.Table;

@Entity

@Table(name="departments")

public class Department implements Serializable {

@Id

@Column(name="departmentid")

@GeneratedValue(strategy = GenerationType.IDENTITY)

private int departmentId;

@Column(name="departmentname")

private String departmentName;

@Column(name="active")

private int active;

// tạo quan hệ với employee thông qua trường department, lazy: khi nào cần thì load nhân viên, all: sử dụng mọi cascade

@OneToMany(mappedBy = "department",fetch = FetchType.LAZY)

private List<Employee> employees;

public Department() {

// TODO Auto-generated constructor stub

}

public int getDepartmentId() {

return departmentId;

}

public void setDepartmentId(int departmentId) {

this.departmentId = departmentId;

}

public String getDepartmentName() {

return departmentName;

}

public void setDepartmentName(String departmentName) {

this.departmentName = departmentName;

}

 

public int getActive() {

return active;

}

public void setActive(int active) {

this.active = active;

}

public List<Employee> getEmployees() {

return employees;

}

public void setEmployees(List<Employee> employees) {

this.employees = employees;

}

}

  • Tệp dao/GenericDAO.java

package dao;

import java.util.List;

public interface GenericDAO<T,K> {

public List<T> getAll();

public T find(K key);

public void add(T obj);

public void update(T obj);

public void delete(K key);

public List<T> search(String name);

}

  • Tệp dao/DepartmentDAO.java

package dao;

import java.util.List;

import entities.Department;

public interface DepartmentDAO extends GenericDAO<Department, Integer> {

}

  • Tệp dao/DepartmentImpl.java

package dao;

import java.util.List;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Repository;

import entities.Department;

@Repository

public class DepartmentImpl implements DepartmentDAO {

@Autowired

private SessionFactory sessionFactory;

public List<Department> getAll()

{

Session session=sessionFactory.openSession();

session.beginTransaction();

List result=session.createQuery("from Department").list();

session.getTransaction().commit();

return result;

}

@Override

public Department find(Integer key) {

Session session=sessionFactory.getCurrentSession();

session.beginTransaction();

Department dep= session.find(Department.class, key);

session.getTransaction().commit();

return dep;

}

@Override

public void add(Department obj) {

Session session=sessionFactory.getCurrentSession();

session.beginTransaction();

session.save(obj);

session.getTransaction().commit();

}

@Override

public void update(Department obj) {

Session session=sessionFactory.getCurrentSession();

session.beginTransaction();

session.update(obj);

session.getTransaction().commit();

}

@Override

public void delete(Integer key) {

Session session=sessionFactory.getCurrentSession();

session.beginTransaction();

Department dep= session.find(Department.class, key);

session.remove(dep);

session.getTransaction().commit();

}

@Override

public List<Department> search(String name) {

Session session=sessionFactory.openSession();

session.beginTransaction();

List result=session.createQuery("from Department where departmentName like :name").setParameter("name", "%"+name+"%").list();

session.getTransaction().commit();

return result;

}

}

  • Tệp dao/EmployeeDAO.java

package dao;

import java.util.List;

import entities.Employee;

public interface EmployeeDAO extends GenericDAO<Employee, String> {

public List<Employee> paging(int page, int pagesize);

public List<Employee> findByDepartment(int key);

}

  • Tệp dao/EmployeeImpl.java

package dao;

import java.util.List;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Repository;

import entities.Department;

import entities.Employee;

@Repository

public class EmployeeImpl implements EmployeeDAO {

@Autowired

private SessionFactory sessionFactory;

@Override

public List<Employee> getAll() {

Session session=sessionFactory.openSession();

session.beginTransaction();

List result=session.createQuery("from Employee").list();

session.getTransaction().commit();

return result;

}

@Override

public Employee find(String key) {

Session session=sessionFactory.getCurrentSession();

session.beginTransaction();

Employee emp= session.find(Employee.class, key);

session.getTransaction().commit();

return emp;

}

@Override

public void add(Employee obj) {

Session session=sessionFactory.getCurrentSession();

session.beginTransaction();

session.save(obj);

session.getTransaction().commit();

}

@Override

public void update(Employee obj) {

Session session=sessionFactory.getCurrentSession();

session.beginTransaction();

session.update(obj);

session.getTransaction().commit();

}

@Override

public void delete(String key) {

Session session=sessionFactory.getCurrentSession();

session.beginTransaction();

Employee dep= session.find(Employee.class, key);

session.remove(dep);

session.getTransaction().commit();

}

@Override

public List<Employee> search(String name) {

Session session=sessionFactory.openSession();

session.beginTransaction();

List result=session.createQuery("from Employee where fullName like :name").setParameter("name", "%"+name+"%").list();

session.getTransaction().commit();

return result;

}

@Override

public List<Employee> paging(int page, int pagesize) {

Session session=sessionFactory.openSession();

session.beginTransaction();

List result=session.createQuery("from Employee").setFirstResult((page-1)*pagesize).setMaxResults(pagesize).list();

session.getTransaction().commit();

return result;

}

@Override

public List<Employee> findByDepartment(int key) {

Session session=sessionFactory.openSession();

session.beginTransaction();

List result=session.createQuery("from Employee where departmentId like :depid").setParameter("depid", key).list();

session.getTransaction().commit();

return result;

}

}

  • Tệp controllers/HomeController.java

package controllers;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.ModelAttribute;

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 java.io.File;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import dao.DepartmentImpl;

import dao.EmployeeImpl;

import entities.Employee;

@Controller

public class HomeController {

@Autowired

private DepartmentImpl departmentImpl;

@Autowired

private EmployeeImpl employeeImpl;

public HomeController() {

// TODO Auto-generated constructor stub

}

@RequestMapping(value= {"/","danh-muc.htm"},method = RequestMethod.GET)

public String index(Model model) {

model.addAttribute("departments", departmentImpl.getAll());

return "index";

}

@RequestMapping(value= "them-nhan-vien.htm",method = RequestMethod.GET)

public String addEmployee(Model model) {

model.addAttribute("departments", departmentImpl.getAll());

model.addAttribute("employee",new Employee());

return "createEmployee";

}

@RequestMapping(value= "luu-nhan-vien.htm",method = RequestMethod.POST)

public String saveEmployee(@ModelAttribute("employee")Employee employee,@RequestParam(value="files")MultipartFile[] files,Model model, HttpServletRequest req) {

//upload 1 ảnh

if(files.length>0) {

String uploadRootPath = req.getServletContext().getRealPath("images");

System.out.println(uploadRootPath+"/"+files[0].getOriginalFilename());

File destination = new File(uploadRootPath+"/"+files[0].getOriginalFilename());

try {

files[0].transferTo(destination);

} catch (IllegalStateException | IOException e) {

e.printStackTrace();

}

employee.setPicture("images/"+files[0].getOriginalFilename());

}

employeeImpl.add(employee);

return "redirect:danh-muc.htm";

}

@RequestMapping(value= "xoa-nhan-vien.htm",method = RequestMethod.GET)

public String delete(@RequestParam(value="id")String id) {

employeeImpl.delete(id);

return "redirect:danh-muc.htm";

}

}

  • Tệp views/index.jsp

<%@ 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>Danh sách phòng ban - nhân viên</title>

<link rel="stylesheet"

href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">

</head>

<body>

<div class="container">

<h1>DANH SÁCH PHÒNG BAN</h1>

<p>

<a class="btn btn-success" href="them-nhan-vien.htm">Thêm nhân viên</a>

</p>

<div class="accordion" id="accordionExample">

<c:forEach var="d" items="${departments}">

<div class="card">

<div class="card-header" id="headingOne">

<h2 class="mb-0">

<button class="btn btn-block text-left" type="button"

data-toggle="collapse" data-target="#D${d.departmentId}"

aria-expanded="true" aria-controls="collapseOne">

${d.departmentName}</button>

</h2>

</div>

<div id="D${d.departmentId}" class="collapse"

aria-labelledby="headingOne" data-parent="#accordionExample">

<div class="card-body">

<h4>Danh sách nhân viên</h4>

<table class="table table-bordered">

<tr>

<th></th>

<th>Tên</th>

<th>Ảnh</th>

<th>Tình trạng</th>

<th></th>

</tr>

<c:forEach var="e" items="${d.employees}">

<tr>

<td>${e.employeeId}</td>

<td>${e.fullName}</td>

<td><img src="${e.picture}" width="100" /></td>

<td>

<c:choose>

<c:when test="${e.active==1}">Đang làm</c:when>

<c:otherwise>Đã nghỉ</c:otherwise>

</c:choose>

</td>

<td><a class="btn btn-danger"

onclick="return confirm('Bạn có muốn xóa không?')"

href="xoa-nhan-vien.htm?id=${e.employeeId}">Xóa</a></td>

</tr>

</c:forEach>

</table>

</div>

</div>

</div>

</c:forEach>

</div>

</div>

<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"></script>

<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.min.js"></script>

</body>

</html>

  • Tệp views/createEmployee.jsp

<%@ 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://www.springframework.org/tags/form"%>

<!DOCTYPE html>

<html>

<head>

<title>Thêm mới nhân viên</title>

<link rel="stylesheet"

href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">

</head>

<body>

<div class="container">

<h1>Thêm mới nhân viên</h1>

<f:form action="luu-nhan-vien.htm" modelAttribute="employee"

method="post" enctype="multipart/form-data">

<table class="table">

<tr>

<td> số</td>

<td><f:input path="employeeId" /></td>

</tr>

<tr>

<td>Tên nhân viên</td>

<td><f:input path="fullName" /></td>

</tr>

<tr>

<td>Ngày sinh</td>

<td><f:input path="birthDay" /></td>

</tr>

<tr>

<td>Giới tính</td>

<td>

<select name="gender" id="gender">

<option value="1">Nam</option>

<option value="0">Nữ</option>

</select>

</td>

</tr>

<tr>

<td>Địa chỉ</td>

<td><f:input path="address" /></td>

</tr>

<tr>

<td>Điện thoại</td>

<td><f:input path="phone" /></td>

</tr>

<tr>

<td>Email</td>

<td><f:input type="email" path="email" /></td>

</tr>

<tr>

<td>Phòng ban</td>

<td>

<f:select path="departmentId" items="${departments}" itemLabel="departmentName" itemValue="departmentId"></f:select>

</td>

</tr>

<tr>

<td>Ảnh</td>

<td><input type="file" id="files" name="files"

multiple="multiple" accept="image/*" />

</tr>

<tr>

<td>Tình trạng</td>

<td>

<select name="active" id="active">

<option value="1">Đang làm</option>

<option value="0">Đã nghỉ</option>

</select>

</td>

</tr>

<tr>

<td colspan="2"><button>Lưu</button></td>

</tr>

</table>

</f:form>

</div>

</body>

</html>

Bước 8: Run application

  • Kích chuột phải vào project chọn Run As -> Run on Server -> Tomcat v9.0

Kích để tải source code bài Hibernate One to Many Mapping trong Spring Web MVC và cơ sở dữ liệu Oracle

Kích để tải dource code phiên bản làm việc với cơ sở dữ liệu  SQL Server

Training online liên hệ: Charles Chung

Video

thay lời cảm ơn!

QUẢNG CÁO - TIẾP THỊ