Thymeleaf CRUD opeartion in Spring Boot

Project Structure

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.3</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>Spring-Annotation</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>Spring-Annotation</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.9.7</version>
			<scope>runtime</scope>
		</dependency>
		<!-- https://mvnrepository.com/artifact/aspectj/aspectjrt -->
		<dependency>
			<groupId>aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.5.4</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-validation</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

StudentController.java


package com.example.demo.controller;
import java.util.List;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.ModelAndView;

import com.example.demo.model.Student;
import com.example.demo.repo.StudentRepository;

@Controller
public class StudentController {
	@Autowired
	private StudentRepository studentRepository;

	@GetMapping("/")
	public String welcome(Student student) {
		return "home";
	}

	@GetMapping("/add")
	public String add(Student student) {
		return "index";
	}

	@PostMapping("/form")
	public String formData(@Valid Student student, BindingResult result, Model model) {

		if (result.hasErrors()) {
			return "index";
		}

		studentRepository.save(student);
		model.addAttribute("msg", "Successfully Added");
		return "index";
	}

	@PostMapping("/updateform")
	public String updateFormData(@Valid Student student, BindingResult result) {
		if (result.hasErrors()) {
			return "index";
		}
		studentRepository.save(student);
		return "redirect:/students";
	}

	@GetMapping("/students")
	public ModelAndView getAllStudents(ModelAndView mv) {
		List<Student> list = studentRepository.findAll();
		mv.addObject("students", list);
		mv.setViewName("success");
		return mv;
	}

	@GetMapping("/delete/{roll}")
	public String delete(@PathVariable int roll) {
		Student student = studentRepository.findById(roll).get();
		studentRepository.delete(student);
		return "redirect:/students";
	}

	@GetMapping("/update/{roll}")
	public ModelAndView edit(@PathVariable int roll, ModelAndView mv) {
		Student student = studentRepository.findById(roll).get();
		mv.addObject("student", student);
		mv.setViewName("updatepage");
		return mv;
	}
}

Student.java


package com.example.demo.model;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.validation.constraints.Email;
import javax.validation.constraints.Min;
import javax.validation.constraints.Size;

import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;

@Component
@Entity
public class Student {
	@NonNull
	@Size(min = 5,max =30 )
	private String name;
	@NonNull
	@Min(value = 1)
	@Id
	private int roll;
	@Email(regexp = "^[a-zA-Z0-9]{1,20}@[a-zA-Z]{1,20}.[a-zA-Z]{2,3}$")
	private String email;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getRoll() {
		return roll;
	}

	public void setRoll(int roll) {
		this.roll = roll;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

}

StudentRepository.java


package com.example.demo.repo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.demo.model.Student;

@Repository
public interface StudentRepository extends JpaRepository<Student, Integer>{

	
	
}

SpringAnnotationAPplication.java


package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@EnableAspectJAutoProxy
public class SpringAnnotationApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringAnnotationApplication.class, args);
	}

}

application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/springcrud
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update

head.html

<head>
<title>ThymeLeaf Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
	href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script
	src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<nav class="navbar navbar-inverse btn-primary">
	<div class="container-fluid">
		<div class="navbar-header">
			<button type="button" class="navbar-toggle" data-toggle="collapse"
				data-target="#myNavbar">
				<span class="icon-bar"></span> <span class="icon-bar"></span> <span
					class="icon-bar"></span>
			</button>
			<a class="navbar-brand" href="#">Thymeleaf CRUD</a>
		</div>
		<div class="collapse navbar-collapse" id="myNavbar">
			<ul class="nav navbar-nav">

			</ul>
			<ul class="nav navbar-nav navbar-right">
				<li><a href="/"> Home</a></li>
				<li><a href="/add"> Add Student</a></li>
				<li><a href="/students"> Student List</a></li>
			</ul>
		</div>
	</div>
</nav>

index.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<span th:insert="head.html"></span>
<div align="center">
	<b th:text="${msg}"></b>
</div>
<body>
	<div class="container">
		<form action="#" th:action="@{form}" th:object="${student}"
			method="post">

			<div class="form-group">
				<label for="roll">Roll:</label> <input type="text"
					th:field="*{roll}" id="roll" class="form-control" />
				<p th:if="${#fields.hasErrors('roll')}" th:errors="*{roll}">Roll
					Error</p>
			</div>

			<div class="form-group">
				<label for="name">Full Name:</label> <input type="text"
					th:field="*{name}" id="name" class="form-control" />
				<p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name
					Error</p>
			</div>

			<div class="form-group">
				<label for="email">Email:</label> <input type="email"
					th:field="*{email}" id="email" class="form-control" />
				<p th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Email
					Error</p>
			</div>

			<button type="submit" class="btn btn-primary btn-block">Add
				Student</button>

		</form>
	</div>
</body>
</html>

success.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<span th:insert="head.html"></span>
<div class="container table-responsive">

<h1 align="center" th:if="${students.isEmpty()}">No Student Available</h1>

	<table class="table table-hover" th:if="${!students.isEmpty()}">
		<thead>
			<tr>
				<th>Roll</th>
				<th>Name</th>
				<th>Email</th>
				<th>Update/Delete</th>
			</tr>
		</thead>
		<tbody>

			<tr th:each="student : ${students}">
				<td th:text="${student.roll}"></td>
				<td th:text="${student.name}"></td>
				<td th:text="${student.email}"></td>
				<td><a th:href="@{/update/{roll}(roll=${student.roll})}" class="btn btn-primary">Edit</a>&nbsp;<a
					th:href="@{/delete/{roll}(roll=${student.roll})}" class="btn btn-danger">Delete</a></td>
			</tr>
		</tbody>
	</table>
</div>

updatepage.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<span th:insert="head.html"></span>
<body>
	<div class="container">
		<form action="#" th:action="@{/updateform}" th:object="${student}"
			method="post">

			<div class="form-group">
				<label for="roll">Roll:</label> <input type="text"
					th:field="*{roll}" id="roll" class="form-control" />
				<p th:if="${#fields.hasErrors('roll')}" th:errors="*{roll}">Roll
					Error</p>
			</div>

			<div class="form-group">
				<label for="name">Full Name:</label> <input type="text"
					th:field="*{name}" id="name" class="form-control" />
				<p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name
					Error</p>
			</div>

			<div class="form-group">
				<label for="email">Email:</label> <input type="email"
					th:field="*{email}" id="email" class="form-control" />
				<p th:if="${#fields.hasErrors('email')}" th:errors="*{email}">Email
					Error</p>
			</div>

			<button type="submit" class="btn btn-primary btn-block">Update Student</button>

		</form>
	</div>
</body>
</html>

Output Screens

No comments: