Restful Crud Operation Using Java, Springboot And JPA

REST API :

REST : Representational state transfer
API : Application Programming Interface
-> Lightweight approach for communicating between application. It is language independent.
-> Commonly used data format is XML and JSON.

Benefits of using spring boot

i) Embedded HTTP server
ii) Create stand-alone Spring applications
iii) Save time on on preparing and configuring the environment
iv) It provides flexible XML configurations, robust batch processing, database transactions, easy workflow, along with a wide variety of tools for development.

CRUD stands for Create, Read, Update and Delete, which refers to the following four operations

HTTP Method CRUD Operation
POST Create a new entity
GET Read a list of entities or single entity
PUT/PATCH Update an existing entity
DELETE Delete an existing entity

Comparing JPA to native Hibernate Methods

Action Native Hibernate Method JPA Method
create/save new entity session.save() entityManager.persist()
Retrieve entity by id session.get()/load() entityManager.find()
Retrieve list of entities session.createQuery() entityManager.createQuery()
Save or Update entity session.saveOrUpdate() entityManager.merge()
Delete entity session.delete() entityManager.remove()

Tools and technologies used

  • Java (Version 8)
  • Spring Boot
  • JPA
  • Maven
  • MySql
  • Eclipse
  • Apache Tomcat
  • MySql workbench

Project Structure

Program To Create Project Using Spring Boot And JPA

How to create spring boot project

Folder Structure In Eclipse

Database Details

Create a database

customer.sql

CREATE DATABASE  IF NOT EXISTS `customer_cruddemo`;
USE `customer_cruddemo`;

--
-- Table structure for table `customer`
--

DROP TABLE IF EXISTS `customer`;

CREATE TABLE `customer` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(45) DEFAULT NULL,
  `last_name` varchar(45) DEFAULT NULL,
  `email` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

--
-- Data for table `customer`
--

INSERT INTO `customer` VALUES 
	(1,'Sachin','Kumar','[email protected]'),
	(2,'Mohan','Yadav','[email protected]'),
	(3,'Avani','Patel','[email protected]'),
	(4,'Mayank','Gupta','[email protected]'),
	(5,'Amar','Singh','[email protected]');

Properties file

Create application.properties in src/main/resources

application.properties

#
# JDBC properties
#
spring.datasource.url=jdbc:mysql://localhost:3306/customer_cruddemo?useSSL=false&serverTimezone=UTC
spring.datasource.username=hbcustomer
spring.datasource.password=hbcustomer

Jar Dependency

Add following dependency in pom.xml

<dependencies>
	<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>
	</dependency>
</dependencies>

Entity Class

Create entity class in com.codebaji.springboot.web.springbootjparestcruddemo.entity

Customer.java

package com.codebaji.springboot.web.springbootjparestcruddemo.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;

@Entity
@Table(name="customer")
public class Customer {

	@Id
	@Column(name="id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private int id;
	
	@Column(name="first_name")
	private String firstName;
	
	@Column(name="last_name")
	private String lastName;
	
	@Column(name="email")
	private String email;

	public Customer() {

	}

	public Customer(String firstName, String lastName, String email) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.email = email;
	}

	public int getId() {
		return id;
	}

	public void setId(int 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;
	}

	@Override
	public String toString() {
		return "Customer [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + "]";
	}
}

Controller Class

Create Controller class in com.codebaji.springboot.web.springbootjparestcruddemo.rest

CustomerRestController.java

package com.codebaji.springboot.web.springbootjparestcruddemo.rest;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.codebaji.springboot.web.springbootjparestcruddemo.entity.Customer;
import com.codebaji.springboot.web.springbootjparestcruddemo.service.CustomerService;

@RestController
@RequestMapping("/api")
public class CustomerRestController {
	
	@Autowired
	private CustomerService customerService;

        // expose "/customers" and return list of customers
	@GetMapping("/customers")
	public List<Customer> findAll(){
		
		return customerService.findAll();
	}
	
	// add mapping for GET /customers/{customerId}
	@GetMapping("/customers/{customerId}")
	public Customer findById(@PathVariable int customerId) {
		
		Customer theCustomer = customerService.findById(customerId);
		
		if(theCustomer == null) {
			throw new RuntimeException("Customer id not found - " + customerId);
		}
		
		return theCustomer;
	}
	
	// add mapping for POST /customers - add new customer
	@PostMapping("/customers")
	public Customer addCustomer(@RequestBody Customer theCustomer) {
		
		// also just in case they pass an id in JSON ... set id to 0
		// this is to force a save of new item ... instead of update
		theCustomer.setId(0);
		
		customerService.save(theCustomer);
		
		return theCustomer;
	}
	
	// add mapping for PUT /customers - update existing customer
	@PutMapping("/customers")
	public Customer updateCustomer(@RequestBody Customer theCustomer) {
		
		customerService.save(theCustomer);
		
		return theCustomer;
	}
	
	// add mapping for DELETE /customers/{customerId} - delete customer
	@DeleteMapping("/customers/{customerId}")
	public String deleteCustomer(@PathVariable int customerId) {
		
		Customer theCustomer = customerService.findById(customerId);
		
		// throw exception if null
		if(theCustomer == null) {
			throw new RuntimeException("Customer id not found - " + customerId);
		}
		
		customerService.deleteById(customerId);
		
		return "Customer employee id - " + customerId;
	}
}

Data Access Object (DAO) class

Create DAO class in com.codebaji.springboot.web.springbootjparestcruddemo.dao

CustomerDAO.java

package com.codebaji.springboot.web.springbootjparestcruddemo.dao;

import java.util.List;
import com.codebaji.springboot.web.springbootjparestcruddemo.entity.Customer;

public interface CustomerDAO {

	public List<Customer> findAll();
	
	public Customer findById(int theId);
	
	public void save(Customer theCustomer);
	
	public void deleteById(int theId);
}

CustomerDAOImpl.java

package com.codebaji.springboot.web.springbootjparestcruddemo.dao;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.codebaji.springboot.web.springbootjparestcruddemo.entity.Customer;

@Repository
public class CustomerDAOImpl implements CustomerDAO {
	
	// define field for entitymanager
	@Autowired
	private EntityManager entityManager;

	@Override
	public List<Customer> findAll() {
		
		// create a query
		Query theQuery = entityManager.createQuery("from Customer");
		
		// execute query and get result list
		List<Customer> customers = theQuery.getResultList();
		
		// return the results
		return customers;
	}

	@Override
	public Customer findById(int theId) {
		
		// get the customer
		Customer theCustomer = entityManager.find(Customer.class, theId);
		
		// return the customer
		return theCustomer;
	}

	@Override
	public void save(Customer theCustomer) {

		Customer newCustomer = entityManager.merge(theCustomer);
		
		theCustomer.setId(newCustomer.getId());
	}

	@Override
	public void deleteById(int theId) {
		
		// delete object with primary key
		Query theQuery = entityManager.createQuery("delete from Customer where id=:customerId");
		
		theQuery.setParameter("customerId", theId);
		
		theQuery.executeUpdate();
	}
}

Service Class

Create Service class in com.codebaji.springboot.web.springbootjparestcruddemo.service

CustomerService.java

package com.codebaji.springboot.web.springbootjparestcruddemo.service;

import java.util.List;
import com.codebaji.springboot.web.springbootjparestcruddemo.entity.Customer;

public interface CustomerService {

	public List<Customer> findAll();
	
	public Customer findById(int theId);
	
	public void save(Customer theCustomer);
	
	public void deleteById(int theId);
}

CustomerServiceImpl.java

package com.codebaji.springboot.web.springbootjparestcruddemo.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.codebaji.springboot.web.springbootjparestcruddemo.dao.CustomerDAO;
import com.codebaji.springboot.web.springbootjparestcruddemo.entity.Customer;

@Service
public class CustomerServiceImpl implements CustomerService {
	
	@Autowired
	private CustomerDAO customerDAO;

	@Override
	@Transactional
	public List<Customer> findAll() {

		return customerDAO.findAll();
	}

	@Override
	@Transactional
	public Customer findById(int theId) {

		return customerDAO.findById(theId);
	}

	@Override
	@Transactional
	public void save(Customer theCustomer) {

		customerDAO.save(theCustomer);
	}

	@Override
	@Transactional
	public void deleteById(int theId) {

		customerDAO.deleteById(theId);
	}
}

Details of annotations used in this project

  • @Entity : The @Entity annotation specifies that the class is an entity and is mapped to a database table.
  • @Table : The @Table annotation specifies the name of the database table to be used for mapping.
  • @Id : The @Id annotation specifies the primary key of an entity.
  • @Column : The Column annotation is used to specify the mapped column for a persistent property or field. If no Column annotation is specified, the default value will be applied.
  • @GeneratedValue : @GeneratedValue provides for the specification of generation strategies for the values of primary keys.
  • @Override : The @Override annotation indicates that the child class method is over-writing its base class method.
  • @RestController : Spring RestController takes care of mapping request data to the defined request handler method. It is Extension of @Controller. Handles REST requests and responses.
  • @RequestMapping : The @Entity annotation specifies that the class is an entity and is mapped to a database table. It maps HTTP request with a path to a controller method.
  • @Autowired : It marks a constructor, field, or setter method to be autowired by Spring dependency injection.
  • @GetMapping : It handles the HTTP GET requests matched with given URI expression. It is a shortcut for @RequestMapping(method = RequestMethod.GET).
  • @PostMapping : It maps HTTP POST requests onto specific handler methods. It is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.POST).
  • @PutMapping : It is used for mapping HTTP PUT requests onto specific handler methods. Specifically, @PutMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.PUT).
  • @DeleteMapping : @DeleteMapping annotation maps HTTP DELETE requests onto specific handler methods. It is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.DELETE).
  • @Repository : Indicates that an annotated class is a repository, which is an abstraction of data access and storage.
  • @Service : It indicates that an annotated class is a service class. @Service annotation is used with classes that provide some business functionalities.
  • @Transactional : It minimize(eliminate) code to manually stopping and starting transaction.
  • @RequestBody : Used to access the request body as POJO. It binds POJO to a method parameter.
  • @PathVariable : It indicates that a method parameter should be bound to a URI template variable.

Related Programs

Restful Crud Operation Using Java, Springboot And Hibernate
Share Me

Leave a Reply