in this blog we create spring boot crud operation using @controller annotation and Thymeleaf Template engine. Thymeleaf can work both in web and non-web environments for More Detail
| HTTP Method | Url Mapping | CRUD Action |
|---|---|---|
| POST | customer/customersave | Create a new customer |
| GET | customer/all-customer-list | Read a list of customers |
| GET | customer/single-customer-view | Read a single customer |
| POST | customer/customersave | Update an exiting customer |
| DELETE | customer/delete | Delete an existing customer |
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.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.code4devops</groupId>
<artifactId>SpringBootRestApiWithHibernate</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBootRestApiWithHibernate</name>
<description>Spring Boot RestApi With Hibernate</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Customer.java
package com.code4devops.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.fasterxml.jackson.annotation.JsonFormat;
@Entity
@Table(name = "customer_detail")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "customer_id", length = 10, nullable = false)
private int customer_id;
@Column(name = "customer_fname", length = 45, nullable = true)
private String customer_fname;
@Column(name = "customer_lname", length = 45, nullable = true)
private String customer_lname;
@Column(name = "customer_mobile", length = 45, nullable = true)
private String customer_mobile;
@Column(name = "customer_email", length = 45, nullable = true)
private String customer_email;
@Column(name = "customer_join_date", length = 45, nullable = true)
@JsonFormat(pattern="yyyy-MM-dd")
private String customer_join_date;
public Customer() {}
public Customer(String customer_fname, String customer_lname, String customer_mobile, String customer_email) {
this.customer_fname = customer_fname;
this.customer_lname = customer_lname;
this.customer_mobile = customer_mobile;
this.customer_email = customer_email;
}
public int getCustomer_id() {
return customer_id;
}
public void setCustomer_id(int customer_id) {
this.customer_id = customer_id;
}
public String getCustomer_fname() {
return customer_fname;
}
public void setCustomer_fname(String customer_fname) {
this.customer_fname = customer_fname;
}
public String getCustomer_lname() {
return customer_lname;
}
public void setCustomer_lname(String customer_lname) {
this.customer_lname = customer_lname;
}
public String getCustomer_mobile() {
return customer_mobile;
}
public void setCustomer_mobile(String customer_mobile) {
this.customer_mobile = customer_mobile;
}
public String getCustomer_email() {
return customer_email;
}
public void setCustomer_email(String customer_email) {
this.customer_email = customer_email;
}
public String getCustomer_join_date() {
return customer_join_date;
}
public void setCustomer_join_date(String customer_join_date) {
this.customer_join_date = customer_join_date;
}
@Override
public String toString() {
return customer_id + "|" + customer_fname + "|"+ customer_lname + "|" + customer_mobile + "|" + customer_email+ "|" + customer_join_date;
}
}
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/spring_boot _build_a_rest_api_with_hibernate?useSSL=false&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=root
CustomerDataAccessObject.java
package com.code4devops.dao;
import java.util.List;
import com.code4devops.entity.Customer;
public interface CustomerDataAccessObject {
public abstract List<Customer> findAll();
public abstract Customer findById(int customerId);
public abstract void save(Customer customer);
public abstract void deleteById(int customerId);
}
CustomerDataAccessObjectImplementation.java
package com.code4devops.dao;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.code4devops.entity.Customer;
@Repository
public class CustomerDataAccessObjectImplementation implements CustomerDataAccessObject{
@Autowired
private EntityManager entityManager;
@Override
public List<Customer> findAll() {
//get the current hibernate session
Session session=entityManager.unwrap(Session.class);
//create a query
//table name same as class name here in query it case sensitive
Query theQuery=session.createQuery("from Customer", Customer.class);
//execute query and get result list
List<Customer> customerList= theQuery.getResultList();
//return the results
return customerList;
}
@Override
public Customer findById(int customerId) {
//get the current hibernate session
Session session=entityManager.unwrap(Session.class);
//get the Customer Object by customerId
Customer customer=session.get(Customer.class, customerId);
//return the results
return customer;
}
@Override
public void save(Customer customer) {
//get the current hibernate session
Session session=entityManager.unwrap(Session.class);
//Remember One Thing : if id=0 the insert else update
session.saveOrUpdate(customer);
}
@Override
public void deleteById(int customerId) {
//get the current hibernate session
Session session=entityManager.unwrap(Session.class);
//delete Object with primary key
Query theQuery = session.createQuery("delete from Customer where customer_id=:customer_id");
theQuery.setParameter("customer_id", customerId);
theQuery.executeUpdate();
}
}
CustomerService.java
package com.code4devops.service;
import java.util.List;
import com.code4devops.entity.Customer;
public interface CustomerService {
public abstract List<Customer> findAll();
public abstract Customer findById(int customerId);
public abstract void save(Customer Customer);
public abstract void deleteById(int customerId);
}
CustomerServiceImplementation.java
package com.code4devops.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.code4devops.dao.CustomerDataAccessObject;
import com.code4devops.entity.Customer;
@Service
public class CustomerServiceImplementation implements CustomerService{
@Autowired
private CustomerDataAccessObject customerDataAccessObject;
@Override
@Transactional
public List<Customer> findAll() {
return customerDataAccessObject.findAll();
}
@Override
@Transactional
public Customer findById(int customerId) {
return customerDataAccessObject.findById(customerId);
}
@Override
@Transactional
public void save(Customer customer) {
customerDataAccessObject.save(customer);
}
@Override
@Transactional
public void deleteById(int customerId) {
customerDataAccessObject.deleteById(customerId);
}
}
index.html
<meta http-equiv="refresh" content="0;URL='customer/all-customer-list'">
customer-from.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" >
<head>
<meta charset="UTF-8">
<title>All Customer List</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<script type="text/javascript" th:src="@{/js/bootstrap.min.js}"></script>
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">CRM</a>
</div>
<ul class="nav navbar-nav">
<li class="active"><a th:href="@{/customer/all-customer-list}">Customer List</a></li>
<li><a th:href="@{/customer/customer-from}">Add Customer</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="#"><span class="glyphicon glyphicon-user"></span> Sign Up</a></li>
<li><a href="#"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
</ul>
</div>
</nav>
<div class="container">
<form action="#" th:action="@{customersave}" th:object="" method="post">
<input type="hidden" th:field="*{customer_id}">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<input type="text" th:field="*{customer_fname}" class="form-control" placeholder="customer first name">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<input type="text" th:field="*{customer_lname}" class="form-control" placeholder="customer last name">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<input type="text" th:field="*{customer_mobile}" class="form-control" placeholder="customer mobile">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<input type="text" th:field="*{customer_email}" class="form-control" placeholder="custome email">
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<input type="date" th:field="*{customer_join_date}" class="form-control" placeholder="customer join date">
</div>
</div>
<div class="col-sm-6">
<div class="form-group">
<button type="submit" class="btn btn-primary btn-sm mb-3">SAVE</button>
</div>
</div>
</div>
</form>
</div>
</body>
</html>
customer-list.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" >
<head>
<meta charset="UTF-8">
<title>All Customer List</title>
<link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
<script type="text/javascript" th:src="@{/js/bootstrap.min.js}"></script>
</head>
<body>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">CRM</a>
</div>
<ul class="nav navbar-nav">
<li class="active"><a th:href="@{/customer/all-customer-list}">Customer List</a></li>
<li><a th:href="@{/customer/customer-from}">Add Customer</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="#"><span class="glyphicon glyphicon-user"></span> Sign Up</a></li>
<li><a href="#"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
</ul>
</div>
</nav>
<div class="container">
<table class="table table-bordered table-striped">
<thead class="thead-dark">
<tr>
<th>Customer ID</th>
<th>Customer FName</th>
<th>customer LName</th>
<th>Customer Mobile</th>
<th>Customer Email</th>
<th>Customer Join Date</th>
<th>UPdate</th>
</tr>
</thead>
<tr th:each="tempCustomer : ">
<td th:text=""/>
<td th:text=""/>
<td th:text=""/>
<td th:text=""/>
<td th:text=""/>
<td th:text=""/>
<td><a th:href="@{/customer/single-customer-view(customer_id=)}" class="btn btn-primary btn-sm mb-3">Update</a></td>
<td><a th:href="@{/customer/delete(customer_id=)}" class="btn btn-danger btn-sm mb-3"
onclick="if(!(confirm('Are you sure you want to delete this custome'))) return false">Delete</a></td>
</tr>
</table>
<!-- <a th:href="@{/customer/customer-from}" class="btn btn-primary btn-sm mb-3">Add Customer</a> -->
</div>
</body>
</html>
ControllerForCustomer.java
package com.code4devops;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.code4devops.entity.Customer;
import com.code4devops.service.CustomerService;
@Controller
@RequestMapping("customer")
public class ControllerForCustomer {
@Autowired
private CustomerService customerService;
@GetMapping("/all-customer-list")
public String getAllCustomerList(Model model) {
List<Customer> list = customerService.findAll();
model.addAttribute("customerlist",list);
return "customer-list";
}
@GetMapping("/customer-from")
public String getCustomerFrom(Model model) {
Customer customer=new Customer();
model.addAttribute("customer",customer);
return "customer-from";
}
@PostMapping("/customersave")
public String getCustomerSave(@ModelAttribute("customer") Customer theCustomer) {
System.out.println(theCustomer);
customerService.save(theCustomer);
return "redirect:all-customer-list";
}
@GetMapping("/single-customer-view")
public String getSingleCustomerView(@RequestParam("customer_id") int customer_id, Model model) {
Customer customer= customerService.findById(customer_id);
model.addAttribute("customer", customer);
return "customer-from";
}
@GetMapping("/delete")
public String getEmployee(@RequestParam("customer_id") int customer_id) {
customerService.deleteById(customer_id);
return "redirect:all-customer-list";
}
}
SpringBootSecurityWithThymleafANDHibernate.java
package com.code4devops;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootSecurityWithThymleafANDHibernate {
public static void main(String[] args) {
SpringApplication.run(SpringBootSecurityWithThymleafANDHibernate.class, args);
}
}