In this tutorial, we will learn how to perform CRUD operations using Spring Data JPA with MySQL database.
We will create a new Spring Boot 3 project to demonstrate the Spring Data JPA CRUD example.
Learn and master Spring Data JPA at Spring Data JPA Tutorial
Spring Data JPA Overview
We can use Spring Data JPA to reduce the amount of boilerplate code required to implement the data access object (DAO) layer.
Spring Data JPA is not a JPA provider. It is a library/framework that adds an extra layer of abstraction on top of our JPA provider (like Hibernate).
Spring Data JPA is not a JPA provider. It is a library/framework that adds an extra layer of abstraction on top of our JPA provider (like Hibernate).
Spring Data JPA provides repositories so we just need to extend them to get full the out-of-the-box implementation for CRUD operations for an entity.
In this tutorial, we will perform CRUD operations for the Product entity and we gonna use the MySQL database to store and retrieve the data.
Adding Maven Dependencies
Let's first add the required dependencies to use Spring Data JPA into our maven project:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
Create Product Entity
Next, let's create a Product entity to perform CRUD database operations.
package net.javaguides.springdatajpacourse.entity;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import jakarta.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
@Entity
@Table(name="products")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "sku")
private String sku;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@Column(name = "price")
private BigDecimal price;
@Column(name = "image_url")
private String imageUrl;
@Column(name = "active")
private boolean active;
@Column(name = "date_created")
@CreationTimestamp
private Date dateCreated;
@Column(name = "last_updated")
@UpdateTimestamp
private Date lastUpdated;
// getter and setter methods
@Override
public String toString() {
return "Product{" +
"id=" + id +
", sku='" + sku + '\'' +
", name='" + name + '\'' +
", description='" + description + '\'' +
", price=" + price +
", imageUrl='" + imageUrl + '\'' +
", active=" + active +
", dateCreated=" + dateCreated +
", lastUpdated=" + lastUpdated +
'}';
}
}
@Entity: This annotation indicates that the class is a JPA entity and should be managed by the persistence context.
@Table: This annotation specifies the name of the table to which the entity is mapped.
@Id: This annotation indicates that the field is the primary key of the entity.
@GeneratedValue: This annotation specifies the strategy used for generating the primary key value.
@Column: This annotation specifies the mapping of the field to the corresponding column in the database.
ProductRepository
Let's create ProductRepository which extends the JpaRepository interface:
import net.javaguides.springdatajpacourse.entity.Product;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ProductRepository extends JpaRepository<Product, Long> {
}
JpaRepository interface provides below methods to perform CRUD operations on a given Product entity:
- save() method to save/update the entity to the database table
- delete() and deleteById() methods to delete the entity from database table
- findById() method to get the entity from the database table
- findAll() method get all the entities from the database table
- deleteAll() method to delete all the entities from the database table
Configure MySQL and Hibernate Properties
Let's use the MySQL database to store and retrieve the data in this example and we gonna use Hibernate properties to create and drop tables.
Open the application.properties file and add the following configuration to it:
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false
spring.datasource.username=root
spring.datasource.password=Mysql@123
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
spring.jpa.hibernate.ddl-auto = create-drop
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
Make sure that you will create a demo database before running the Spring boot application.
Also, change the MySQL username and password as per your MySQL installation on your machine.
Test CRUD Methods
Let's write the JUnit test cases to perform CRUD operations on the Product entity:
import net.javaguides.springdatajpacourse.entity.Product;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.annotation.Rollback;
import java.math.BigDecimal;
import java.util.List;
@DataJpaTest
@Rollback(value = false)
@AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE)
class ProductRepositoryTest {
@Autowired
private ProductRepository productRepository;
@Test
void testSaveMethod() throws InterruptedException {
Product product = getProduct1();
// save product
productRepository.save(product);
}
@Test
void testUpdateMethod() throws InterruptedException {
Product product = getProduct1();
// save product
Product savedProduct = productRepository.save(product);
savedProduct.setName("product 1 updated");
savedProduct.setDescription("product 1 desc updated");
savedProduct.setPrice(new BigDecimal(300));
// update product
Product updatedProduct = productRepository.save(savedProduct);
System.out.println(updatedProduct.getName());
System.out.println(updatedProduct.getDescription());
System.out.println(updatedProduct.getPrice());
}
@Test
void testSaveAllMethod(){
Product product = getProduct1();
Product product2 = new Product();
product2.setName("product 2");
product2.setDescription("product 2 desc");
product2.setPrice(new BigDecimal(200));
product2.setSku("product 2 sku");
product2.setActive(true);
product2.setImageUrl("product2.png");
productRepository.saveAll(List.of(product, product2));
}
@Test
void testFindByIdMethod(){
Product product = getProduct1();
// save product
productRepository.save(product);
// get product by id
Product savedProduct = productRepository.findById(product.getId()).get();
System.out.println(savedProduct.getName());
}
@Test
void testFindAllMethod(){
Product product = getProduct1();
Product product2 = getProduct2();
productRepository.saveAll(List.of(product, product2));
productRepository.findAll().forEach((p) -> {
System.out.println(p.getName());
});
}
@Test
void testCountMethod(){
Product product = getProduct1();
Product product2 = getProduct2();
productRepository.saveAll(List.of(product, product2));
long count = productRepository.count();
System.out.println(count);
}
@Test
void testDeleteByIdMethod(){
Product product = getProduct1();
productRepository.save(product);
// delete product by id
productRepository.deleteById(product.getId());
}
@Test
void testDeleteMethod(){
Product product = getProduct1();
productRepository.save(product);
// delete product by id
productRepository.delete(product);
}
@Test
void testDeleteAllMethod(){
Product product = getProduct1();
Product product2 = getProduct2();
productRepository.saveAll(List.of(product, product2));
productRepository.deleteAll();
}
protected Product getProduct1(){
Product product = new Product();
product.setName("product 1");
product.setDescription("product 1 desc");
product.setPrice(new BigDecimal(100));
product.setSku("product 1 sku");
product.setActive(true);
product.setImageUrl("product1.png");
return product;
}
protected Product getProduct2(){
Product product2 = new Product();
product2.setName("product 2");
product2.setDescription("product 2 desc");
product2.setPrice(new BigDecimal(200));
product2.setSku("product 2 sku");
product2.setActive(true);
product2.setImageUrl("product2.png");
return product2;
}
}
We are using @DataJpaTest annotation to write a JUnit test for ProductRepository methods.
@AutoConfigureTestDatabase annotation is to disable embedded in-memory database support and enable MySQL database support.
Save Product Entity
@Test
void testSaveMethod() throws InterruptedException {
Product product = getProduct1();
// save product
productRepository.save(product);
}
Update Product Entity
@Test
void testUpdateMethod() throws InterruptedException {
Product product = getProduct1();
// save product
Product savedProduct = productRepository.save(product);
savedProduct.setName("product 1 updated");
savedProduct.setDescription("product 1 desc updated");
savedProduct.setPrice(new BigDecimal(300));
// update product
Product updatedProduct = productRepository.save(savedProduct);
System.out.println(updatedProduct.getName());
System.out.println(updatedProduct.getDescription());
System.out.println(updatedProduct.getPrice());
}
Save Multiple Products
@Test
void testSaveAllMethod(){
Product product = getProduct1();
Product product2 = new Product();
product2.setName("product 2");
product2.setDescription("product 2 desc");
product2.setPrice(new BigDecimal(200));
product2.setSku("product 2 sku");
product2.setActive(true);
product2.setImageUrl("product2.png");
productRepository.saveAll(List.of(product, product2));
}
Get Product Entity By Id
@Test
void testFindByIdMethod(){
Product product = getProduct1();
// save product
productRepository.save(product);
// get product by id
Product savedProduct = productRepository.findById(product.getId()).get();
System.out.println(savedProduct.getName());
}
Get All Product Entities
@Test
void testFindAllMethod(){
Product product = getProduct1();
Product product2 = getProduct2();
productRepository.saveAll(List.of(product, product2));
productRepository.findAll().forEach((p) -> {
System.out.println(p.getName());
});
}
Delete Product Entity
@Test
void testDeleteByIdMethod(){
Product product = getProduct1();
productRepository.save(product);
// delete product by id
productRepository.deleteById(product.getId());
}
@Test
void testDeleteMethod(){
Product product = getProduct1();
productRepository.save(product);
// delete product by id
productRepository.delete(product);
}
Delete All Products
@Test
void testDeleteAllMethod(){
Product product = getProduct1();
Product product2 = getProduct2();
productRepository.saveAll(List.of(product, product2));
productRepository.deleteAll();
}
Output:
Conclusion
In this tutorial, we have seen how to perform CRUD operations using Spring Data JPA with MySQL database. We have used JpaRepository interface methods such as save(), saveAll(), findById(), findAll(), delete(), deleteById(), and deleteAll() methods to perform CRUD operations on the Product entity.
Learn and master Spring Data JPA at Spring Data JPA Tutorial
Comments
Post a Comment
Leave Comment