CodeGym /Courses /Module 5. Spring /Doing CRUD Operations with a Database

Doing CRUD Operations with a Database

Module 5. Spring
Level 5 , Lesson 5
Available

Before diving headfirst into the code, let's refresh what CRUD is. CRUD is an acronym that stands for the four main operations when working with data in a database:

  • Create (creation): adding new records to the database.
  • Read (reading): retrieving data from the database.
  • Update (updating): modifying existing records.
  • Delete (deleting): removing records from the database.

Now let's move on to implementing these operations. We'll use the entities and repositories you already created. If you missed anything, now's a good time to grab your code!


Creating a test entity

Let's take a simple entity, for example Product:


import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;

@Entity
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    private Double price;

    // Constructors, getters and setters
    public Product() {}

    public Product(String name, Double price) {
        this.name = name;
        this.price = price;
    }

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}

The entity is ready! Now let's turn to the repository to work with the database and implement all four CRUD operations.


Repository for working with the database

You've previously wired up JpaRepository to work with the database. Here's a sample repository for our Product:


import org.springframework.data.jpa.repository.JpaRepository;

public interface ProductRepository extends JpaRepository<Product, Long> {
    // Basic CRUD methods are already built-in
}

Note that we extended the interface from JpaRepository, which means all CRUD methods are already there! But let's see how to actually use them.


Implementing CRUD operations

Now for the good part! Let's create a service and a controller to perform the CRUD operations.

1. Create (Creation)

Saving a new object to the database is done using the save() method.

Example of a product creation method in the service:


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

@Service
public class ProductService {

    private final ProductRepository productRepository;

    @Autowired
    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    public Product createProduct(String name, Double price) {
        Product product = new Product(name, price);
        return productRepository.save(product);
    }
}

Now let's add the method in the controller:


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/products")
public class ProductController {

    private final ProductService productService;

    @Autowired
    public ProductController(ProductService productService) {
        this.productService = productService;
    }

    @PostMapping
    public Product createProduct(@RequestBody Product product) {
        return productService.createProduct(product.getName(), product.getPrice());
    }
}

When you send an HTTP POST request to /products with JSON in the body, running this operation is easy.

Example request:


POST /products HTTP/1.1
Content-Type: application/json

{
    "name": "Laptop",
    "price": 1200.00
}

After executing this request, the new product will be added to the database!


2. Read (Reading)

To get data from the DB you can use findById() or findAll().

Example in the service:


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

public List<Product> getAllProducts() {
  return productRepository.findAll();
  }

  public Optional<Product> getProductById(Long id) {
    return productRepository.findById(id);
    }

Now implement the methods in the controller:


@GetMapping
public List<Product> getAllProducts() {
    return productService.getAllProducts();
}

@GetMapping("/{id}")
public Product getProductById(@PathVariable Long id) {
    return productService.getProductById(id)
                         .orElseThrow(() -> new RuntimeException("Product not found"));
}

These methods handle:

  • GET /products: returns a list of all products.
  • GET /products/{id}: returns a product by ID.

3. Update (Updating)

Updates are done using save(). If an object with the given ID exists, it will be updated.

First let's add an update method in the service:


public Product updateProduct(Long id, String name, Double price) {
    Product product = productRepository.findById(id)
            .orElseThrow(() -> new RuntimeException("Product not found"));

    product.setName(name);
    product.setPrice(price);
    return productRepository.save(product);
}

And add it to the controller:


@PutMapping("/{id}")
public Product updateProduct(@PathVariable Long id, @RequestBody Product updatedProduct) {
    return productService.updateProduct(id, updatedProduct.getName(), updatedProduct.getPrice());
}

Example request:


PUT /products/1 HTTP/1.1
Content-Type: application/json

{
    "name": "Updated Laptop",
    "price": 1500.00
}

If a product with ID 1 exists, it will be updated.


4. Delete (Deleting)

Deletion is done using deleteById().

Method in the service:


public void deleteProduct(Long id) {
    productRepository.deleteById(id);
}

Method in the controller:


@DeleteMapping("/{id}")
public void deleteProduct(@PathVariable Long id) {
    productService.deleteProduct(id);
}

Now send the request:


DELETE /products/1 HTTP/1.1

This request will delete the product with ID 1.


Error handling

When working with databases, errors often occur, such as EntityNotFoundException. Make sure you handle them properly, for example by using custom exceptions or global error handlers.


Practical application

In real applications, CRUD operations are the backbone of any data-driven system. From user and order management to books in a library — these methods are used everywhere. Also, interviewers often ask about core CRUD methods and may ask you to demonstrate the relevant code.


CRUD shouldn't be a mystery anymore! So it's time to make databases your allies.

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION