Intermediate
Building a Complete CRUD REST API with Spring Data JPA
📂 Phase 6: Career Launch — Spring Boot, Projects, Interview Prep (Days 27–30) · JavaA real Spring Boot application is layered: a Controller handles HTTP requests, a Service holds business logic, and a Repository talks to the database. Spring Data JPA removes almost all of the repository boilerplate by generating the SQL for you.
The Three-Layer Architecture
HTTP Request
↓
@RestController → handles routing, request/response
↓
@Service → business logic, validation
↓
@Repository (JPA) → talks to the database
↓
Database
Step 1: Define the Entity
An entity is a Java class mapped to a database table using JPA annotations.
@Entity
@Table(name = "students")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private Integer age;
// Getters and setters
}
Step 2: Create the Repository
Extending JpaRepository gives you save(), findById(), findAll(), and deleteById() with zero implementation code.
public interface StudentRepository extends JpaRepository {
// Spring Data JPA can also auto-generate queries from method names:
List findByName(String name);
}
Step 3: Write the Service Layer
@Service
public class StudentService {
@Autowired
private StudentRepository studentRepository;
public Student createStudent(Student student) {
return studentRepository.save(student);
}
public List getAllStudents() {
return studentRepository.findAll();
}
public Student getStudentById(Long id) {
return studentRepository.findById(id)
.orElseThrow(() -> new RuntimeException("Student not found"));
}
public Student updateStudent(Long id, Student updated) {
Student existing = getStudentById(id);
existing.setName(updated.getName());
existing.setEmail(updated.getEmail());
existing.setAge(updated.getAge());
return studentRepository.save(existing);
}
public void deleteStudent(Long id) {
studentRepository.deleteById(id);
}
}
Step 4: Expose It Through the Controller
@RestController
@RequestMapping("/api/students")
public class StudentController {
@Autowired
private StudentService studentService;
@PostMapping
public Student create(@RequestBody Student student) {
return studentService.createStudent(student);
}
@GetMapping
public List getAll() {
return studentService.getAllStudents();
}
@GetMapping("/{id}")
public Student getOne(@PathVariable Long id) {
return studentService.getStudentById(id);
}
@PutMapping("/{id}")
public Student update(@PathVariable Long id, @RequestBody Student student) {
return studentService.updateStudent(id, student);
}
@DeleteMapping("/{id}")
public void delete(@PathVariable Long id) {
studentService.deleteStudent(id);
}
}
Connecting to MySQL
Configuration lives in application.properties — no XML, no manual DriverManager code like raw JDBC required:
spring.datasource.url=jdbc:mysql://localhost:3306/careerdb
spring.datasource.username=root
spring.datasource.password=yourpassword
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
Caution: ddl-auto=update is fine for learning and local development, but it can silently alter or drop columns in production. Real projects use migration tools like Flyway or Liquibase instead.
HTTP Methods Mapped to CRUD
| HTTP Method | CRUD Operation | Typical Status Code on Success |
|---|---|---|
| POST | Create | 201 Created |
| GET | Read | 200 OK |
| PUT | Update | 200 OK |
| DELETE | Delete | 204 No Content |
Interview tip: Be able to build this entire CRUD flow — entity, repository, service, controller — from memory on a whiteboard or shared screen. It is one of the single most common practical asks in fresher and junior Spring Boot interviews.