Spring Boot CRUD Application with MySQL and JPA (Step-by-Step Guide)
Introduction
A CRUD application is one of the most common projects developers build when learning Spring Boot.
CRUD stands for:
- Create
- Read
- Update
- Delete
In this tutorial, you will build a complete REST API using:
- Spring Boot 3
- Spring Data JPA
- MySQL
- Maven
By the end of this guide, you'll have a working backend application capable of managing employee records.
What You Will Build
The application will support:
POST /employees GET /employees GET /employees/{id} PUT /employees/{id} DELETE /employees/{id}
Prerequisites
Before starting, ensure you have:
- Java 21 (or Java 17+)
- Spring Boot 3
- Maven
- MySQL Server
- IntelliJ IDEA or Eclipse
Related Reading:
- Spring Boot 3 Tutorial for Beginners
- Spring Boot Project Structure Explained
- Spring Boot REST API Best Practices
Spring Boot CRUD Maven Dependencies
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency>Spring Boot CRUD examples commonly use Spring Web, Spring Data JPA, and the MySQL driver.
Project Structure
src └── main ├── controller ├── service ├── repository ├── entity └── resources
Step 1: Create Database
CREATE DATABASE employee_db;
Step 2: Configure application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/employee_db spring.datasource.username=root spring.datasource.password=password spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true
Step 3: Create Entity
Employee.java
@Entity @Table(name = "employees") public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; private String department; }
Step 4: Create Repository
EmployeeRepository.java
@Repository public interface EmployeeRepository extends JpaRepository<Employee, Long> { }
Step 5: Create Service Layer
EmployeeService.java
@Service public class EmployeeService { @Autowired private EmployeeRepository repository; public List<Employee> getAllEmployees() { return repository.findAll(); } public Employee save(Employee employee) { return repository.save(employee); } }
Step 6: Create Controller
EmployeeController.java
@RestController @RequestMapping("/employees") public class EmployeeController { @Autowired private EmployeeService service; @GetMapping public List<Employee> getEmployees() { return service.getAllEmployees(); } @PostMapping public Employee createEmployee( @RequestBody Employee employee) { return service.save(employee); } }
Validation Dependency
If not already present, add:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
Update EmployeeDTO
import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; public class EmployeeDTO { private Long id; @NotBlank(message = "Name is required") private String name; @Email(message = "Please enter a valid email") private String email; @NotBlank(message = "Department is required") private String department; // Getters and Setters }
Enable Validation in Controller
@PostMapping public Employee createEmployee( @Valid @RequestBody EmployeeDTO employeeDTO) { return service.save(employeeDTO); }
Example Invalid Request
{ "name": "", "email": "invalid-email", "department": "" }
Validation Error Response
{ "name": "Name is required", "email": "Please enter a valid email", "department": "Department is required" }
Benefits of Validation
- Prevents bad data
- Improves API quality
- Better user experience
- Protects database integrity
Exception Handling in Spring Boot
Exception handling helps provide meaningful error messages when something goes wrong.
Without exception handling, users may receive confusing error responses.
Common Exceptions
Examples:
- Employee not found
- Invalid input
- Database errors
- Duplicate records
Create Custom Exception
EmployeeNotFoundException.java
public class EmployeeNotFoundException extends RuntimeException { public EmployeeNotFoundException(Long id) { super("Employee not found with id: " + id); } }
Throw Exception in Service Layer
public Employee getEmployeeById(Long id) { return repository.findById(id) .orElseThrow(() -> new EmployeeNotFoundException(id)); }
Create Global Exception Handler
GlobalExceptionHandler.java
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler( EmployeeNotFoundException.class) public ResponseEntity<String> handleEmployeeNotFound( EmployeeNotFoundException ex) { return ResponseEntity .status(HttpStatus.NOT_FOUND) .body(ex.getMessage()); } }
Example Error Response
{ "message": "Employee not found with id: 100" }
Why Use Global Exception Handling?
Benefits:
- Consistent API responses
- Cleaner controller code
- Easier maintenance
- Better debugging
CRUD Operations Flow
Client Request ↓ Controller ↓ Service ↓ Repository ↓ MySQL Database ↓ Response
Testing with Postman
Create Employee
POST /employees
Request Body:
{ "name":"Muhammad Zeeshan", "email":"zeeshan@example.com", "department":"IT" }
Get All Employees
GET /employees
Update Employee
PUT /employees/1
Delete Employee
DELETE /employees/1
Common Errors
Database Connection Failed
Check:
- MySQL running
- Username
- Password
- Database exists
Entity Not Found
Verify:
@Id @GeneratedValue
configuration.
Port Already In Use
Change:
server.port=8081
Best Practices
Use DTOs
Avoid exposing entities directly.
Add Validation
Use:
@NotBlank @Email
Add Exception Handling
Implement:
@RestControllerAdvice
Secure APIs
Use Spring Security and JWT.
FAQ
What is CRUD in Spring Boot?
CRUD stands for Create, Read, Update, and Delete operations used to manage data in applications.
Why use Spring Data JPA?
Spring Data JPA reduces boilerplate code and simplifies database operations.
Can I use PostgreSQL instead of MySQL?
Yes. Spring Boot supports PostgreSQL, MySQL, Oracle, SQL Server, and many other databases.
Is this a REST API?
Yes. The controller exposes REST endpoints using HTTP methods.
