DEV Community

Cover image for Complete Employee CRUD Application in Spring Boot + Thymeleaf + MySQL | Beginner’s Guide
Chitt Ranjan Mahto (Chirag)
Chitt Ranjan Mahto (Chirag)

Posted on

Complete Employee CRUD Application in Spring Boot + Thymeleaf + MySQL | Beginner’s Guide

inchirags@gmail.com Chirag's Spring Boot Tutorial https://www.chirags.in


Complete Employee CRUD Application in Spring Boot + Thymeleaf + MySQL | Beginner’s Guide


Let’s create a complete Employee CRUD (Create, Read, Update, Delete) application using Spring Boot, Thymeleaf, and MySQL, tailored for beginners. I’ll guide you step-by-step through the process, including setting up the project in IntelliJ IDEA, configuring the database, writing the code, and creating the frontend with Thymeleaf. The application will allow you to manage employee records (add, view, update, and delete employees).

Prerequisites

  1. IntelliJ IDEA: Install IntelliJ IDEA Community or Ultimate Edition.

  2. MySQL: Install MySQL (e.g., MySQL Community Server) and MySQL Workbench for database management.

  3. JDK: Install JDK 17 or later (Spring Boot 3.x requires Java 17+).

  4. Maven: IntelliJ IDEA includes Maven by default, so no separate installation is needed.

Step-by-Step Guide

Step 1: Set Up MySQL Database

  1. Open MySQL Workbench and create a new schema:
  • Name the schema employee_db.

  • Run the following SQL to create an employees table:

CREATE DATABASE employee_db;
USE employee_db;

CREATE TABLE employees (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    first_name VARCHAR(50) NOT NULL,
    last_name VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE
);
Enter fullscreen mode Exit fullscreen mode
  1. Note your MySQL username and password (default is often root and a custom password set during installation).

Step 2: Create a Spring Boot Project

  1. Open
https://start.spring.io/
Enter fullscreen mode Exit fullscreen mode
  1. Choose in Spring Initializr:
- Project: Maven
   - Language: Java
   - Spring Boot: Choose the latest stable version (e.g., 3.2.x or 3.3.x)
   - Group: com.example
   - Artifact: employeecrud
   - Java: 17 or higher
   - Packaging: Jar
Enter fullscreen mode Exit fullscreen mode
  1. Add the following dependencies:
- Spring Web: For RESTful web application.
   - Spring Data JPA: For database operations.
   - MySQL Driver: To connect to MySQL.
   - Thymeleaf: For server-side HTML rendering.
   - Spring Boot DevTools: For auto-restart during development 
Enter fullscreen mode Exit fullscreen mode

(optional).

  1. Click Create to generate the project.

Step 3: Configure MySQL in Spring Boot

  1. Open src/main/resources/application.properties and add the following configuration:
spring.datasource.url=jdbc:mysql://localhost:3306/employee_db
spring.datasource.username=root
spring.datasource.password=admin@123
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.thymeleaf.cache=false
- Replace your_mysql_password with your actual MySQL password.

- spring.jpa.hibernate.ddl-auto=update automatically updates the database schema based on your entities.

- spring.thymeleaf.cache=false disables Thymeleaf caching for development.
Enter fullscreen mode Exit fullscreen mode

Step 4: Create the Employee Entity

  1. Create a new package com.example.employeecrud.model in src/main/java/com/example/employeecrud.

  2. Create a Java class Employee.java:

package com.example.employeecrud.model;

import jakarta.persistence.*;

@Entity
@Table(name = "employees")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "first_name", nullable = false)
    private String firstName;

    @Column(name = "last_name", nullable = false)
    private String lastName;

    @Column(name = "email", nullable = false, unique = true)
    private String email;

    // Default constructor
    public Employee() {}

    // Parameterized constructor
    public Employee(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
Enter fullscreen mode Exit fullscreen mode
  • This class maps to the employees table in the database using JPA annotations.

Step 5: Create the Repository

  1. Create a new package com.example.employeecrud.repository.

  2. Create an interface EmployeeRepository.java:

package com.example.employeecrud.repository;

import com.example.employeecrud.model.Employee;
import org.springframework.data.jpa.repository.JpaRepository;

public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
Enter fullscreen mode Exit fullscreen mode
  • JpaRepository provides built-in methods for CRUD operations (e.g., save, findAll, findById, delete).

Step 6: Create the Service Layer

  1. Create a new package com.example.employeecrud.service.

  2. Create a class EmployeeService.java:

package com.example.employeecrud.service;

import com.example.employeecrud.model.Employee;
import com.example.employeecrud.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class EmployeeService {

    @Autowired
    private EmployeeRepository employeeRepository;

    // Get all employees
    public List<Employee> getAllEmployees() {
        return employeeRepository.findAll();
    }

    // Get employee by ID
    public Optional<Employee> getEmployeeById(Long id) {
        return employeeRepository.findById(id);
    }

    // Save or update employee
    public void saveEmployee(Employee employee) {
        employeeRepository.save(employee);
    }

    // Delete employee
    public void deleteEmployee(Long id) {
        employeeRepository.deleteById(id);
    }
}
Enter fullscreen mode Exit fullscreen mode
  • This service layer contains business logic and interacts with the repository.

Step 7: Create the Controller

  1. Create a new package com.example.employeecrud.controller.

  2. Create a class EmployeeController.java:

package com.example.employeecrud.controller;

import com.example.employeecrud.model.Employee;
import com.example.employeecrud.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    // Display list of employees
    @GetMapping("/")
    public String viewHomePage(Model model) {
        model.addAttribute("listEmployees", employeeService.getAllEmployees());
        return "index";
    }

    // Show new employee form
    @GetMapping("/showNewEmployeeForm")
    public String showNewEmployeeForm(Model model) {
        Employee employee = new Employee();
        model.addAttribute("employee", employee);
        return "new_employee";
    }

    // Save employee
    @PostMapping("/saveEmployee")
    public String saveEmployee(@ModelAttribute("employee") Employee employee) {
        employeeService.saveEmployee(employee);
        return "redirect:/";
    }

    // Show update form
    @GetMapping("/showFormForUpdate/{id}")
    public String showFormForUpdate(@PathVariable(value = "id") Long id, Model model) {
        Employee employee = employeeService.getEmployeeById(id).orElseThrow(() -> new IllegalArgumentException("Invalid employee Id:" + id));
        model.addAttribute("employee", employee);
        return "update_employee";
    }

    // Delete employee
    @GetMapping("/deleteEmployee/{id}")
    public String deleteEmployee(@PathVariable(value = "id") Long id) {
        employeeService.deleteEmployee(id);
        return "redirect:/";
    }
}
Enter fullscreen mode Exit fullscreen mode
  • This controller handles HTTP requests and maps them to Thymeleaf templates.

Step 8: Create Thymeleaf Templates

  1. Create a directory src/main/resources/templates if it doesn’t exist.

  2. Create the following Thymeleaf templates:

a. Home Page (index.html)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Employee Management System</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container my-5">
    <h2>Employee List</h2>
    <a th:href="@{/showNewEmployeeForm}" class="btn btn-primary mb-3">Add New Employee</a>
    <table class="table table-striped">
        <thead>
        <tr>
            <th>ID</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Email</th>
            <th>Actions</th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="employee : ${listEmployees}">
            <td th:text="${employee.id}"></td>
            <td th:text="${employee.firstName}"></td>
            <td th:text="${employee.lastName}"></td>
            <td th:text="${employee.email}"></td>
            <td>
                <a th:href="@{/showFormForUpdate/{id}(id=${employee.id})}" class="btn btn-warning btn-sm">Update</a>
                <a th:href="@{/deleteEmployee/{id}(id=${employee.id})}" class="btn btn-danger btn-sm">Delete</a>
            </td>
        </tr>
        </tbody>
    </table>
</div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

b. New Employee Form (new_employee.html)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Add New Employee</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container my-5">
    <h2>Add New Employee</h2>
    <form th:action="@{/saveEmployee}" th:object="${employee}" method="post">
        <div class="mb-3">
            <label for="firstName" class="form-label">First Name</label>
            <input type="text" class="form-control" id="firstName" th:field="*{firstName}" required>
        </div>
        <div class="mb-3">
            <label for="lastName" class="form-label">Last Name</label>
            <input type="text" class="form-control" id="lastName" th:field="*{lastName}" required>
        </div>
        <div class="mb-3">
            <label for="email" class="form-label">Email</label>
            <input type="email" class="form-control" id="email" th:field="*{email}" required>
        </div>
        <button type="submit" class="btn btn-primary">Save</button>
        <a th:href="@{/}" class="btn btn-secondary">Cancel</a>
    </form>
</div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

c. Update Employee Form (update_employee.html)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Update Employee</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container my-5">
    <h2>Update Employee</h2>
    <form th:action="@{/saveEmployee}" th:object="${employee}" method="post">
        <input type="hidden" th:field="*{id}">
        <div class="mb-3">
            <label for="firstName" class="form-label">First Name</label>
            <input type="text" class="form-control" id="firstName" th:field="*{firstName}" required>
        </div>
        <div class="mb-3">
            <label for="lastName" class="form-label">Last Name</label>
            <input type="text" class="form-control" id="lastName" th:field="*{lastName}" required>
        </div>
        <div class="mb-3">
            <label for="email" class="form-label">Email</label>
            <input type="email" class="form-control" id="email" th:field="*{email}" required>
        </div>
        <button type="submit" class="btn btn-primary">Update</button>
        <a th:href="@{/}" class="btn btn-secondary">Cancel</a>
    </form>
</div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode
  • This template is similar to new_employee.html but includes a hidden input field for the id to ensure the correct employee record is updated.

Step 9: Run the Application

  1. Ensure MySQL is Running:
  • Start your MySQL server (e.g., via MySQL Workbench or command line: mysql.server start on macOS or service mysql start on Linux).

  • Verify that the employee_db schema and employees table exist (from Step 1).

  1. Run the Spring Boot Application:
  • In IntelliJ IDEA, open the main application class (likely EmployeeCrudApplication.java in src/main/java/com/example/employeecrud).

  • Click the green "Run" button next to the main method or select Run > Run 'EmployeeCrudApplication'.

EmployeeCrudApplication.java

  • Alternatively, use the terminal in IntelliJ:

      mvn spring-boot:run
    
    - The application will start on http://localhost:8080.
    
  1. Access the Application:
  • Open a browser and navigate to http://localhost:8080.

  • You should see the home page listing employees (initially empty).

Step 10: Test the CRUD Functionality

  1. Create:
  • Click Add New Employee on the home page.

  • Fill in the form (e.g., First Name: Chirag, Last Name: Mahto, Email: chirag.mahto@example.com) and click Save.

  • You’ll be redirected to the home page, and the new employee should appear in the table.

  1. Read:
  • The home page (/) displays all employees in a table.

  • Verify that the employee you added is listed.

  1. Update:
  • Click Update next to an employee.

  • Modify the fields (e.g., change the first name to Purab) and click Update.

  • Return to the home page to confirm the changes.

  1. Delete:
  • Click Delete next to an employee.

  • The employee should be removed from the table.

Step 11: Project Structure Overview

Ensure your project structure looks like this:

employeecrud
├── src
│   ├── main
│   │   ├── java
│   │   │   ├── com.example.employeecrud
│   │   │   │   ├── controller
│   │   │   │   │   └── EmployeeController.java
│   │   │   │   ├── model
│   │   │   │   │   └── Employee.java
│   │   │   │   ├── repository
│   │   │   │   │   └── EmployeeRepository.java
│   │   │   │   ├── service
│   │   │   │   │   └── EmployeeService.java
│   │   │   └── EmployeeCrudApplication.java
│   │   ├── resources
│   │   │   ├── templates
│   │   │   │   ├── index.html
│   │   │   │   ├── new_employee.html
│   │   │   │   └── update_employee.html
│   │   │   └── application.properties
├── pom.xml
Enter fullscreen mode Exit fullscreen mode

This completes the Employee CRUD application. You now have a fully functional web application using Spring Boot, Thymeleaf, and MySQL.

For any doubts and query, please write on YouTube video 📽️ comments section.

Note : Flow the Process shown in video 📽️.

😉Subscribe and like for more videos:
https://www.youtube.com/@chiragstutorial
💛Don't forget to, 💘Follow, 💝Like, 💖Share 💙&, Comment

Thanks & Regards,
Chitt Ranjan Mahto "Chirag"
https://www.chirags.in


Note: All scripts used in this demo will be available in our website.
Link will be available in description.

Top comments (0)