What is in this blog?
So we are going to look into Java Spring Boot for creating a basic backend system, which interacts with a database and does basic CRUD (Create, Read, Update, Delete) operations.
The main idea is to cover the most basic working of this backend framework, like the simplest form of function that a backend framework can perform.
Ok, so this post explores how to implement a basic, robust CRUD API using Spring Boot, the industry standard for modern Java backend development, backed by a MySQL database.
What is Spring Boot
Spring Boot is a Java framework that helps you build web and backend applications easily. It takes care of most of the setup and configuration for you, so you can focus on writing your code instead of managing complex settings.
Let's get started.
First, install Java (JDK) in your system.
Then, we have to create a Java Spring project. To do that, go to the Spring initializer website and create a new project. Give the application a name, select Java versions, and add dependencies. Dependencies are additional libraries or packages that help a Java application access and use different functionalities.
Hit generate, and the package will be in your system.
Open the generated folder in any IDE. The most preferred one for Java-related projects is IntelliJ IDEA. You can go and download the community version from the official site.
First, you have to know what all the stuff is inside the generated folder. In short, you have to know the Spring architecture.
A typical Spring Boot application that handles CRUD operations follows a layered architecture to maintain separation of concerns:
- Entity/Model: The Java class representing the data structure in the database (e.g., User or Product).
- Repository Layer: The interface that interacts directly with the database. Spring Data JPA makes this simple by automatically providing basic CRUD methods.
- Service Layer: Contains the business logic. It uses the Repository to perform database operations.
- Controller Layer: The entry point for the application. It receives HTTP requests, calls the Service layer, and returns an HTTP response.
| Operation | Function | HTTP Method | Spring Annotation | Repository Method | Purpose |
|---|---|---|---|---|---|
| Create | Insert Data | POST | @PostMapping | save(entity) | Add a new record to the database. |
| Read | Retrieve Data | GET | @GetMapping | findAll(), findById(id) | Fetch one or all records. |
| Update | Modify Data | PUT | @PutMapping | save(entity) | Change an existing record's data. |
| Delete | Remove Data | DELETE | @DeleteMapping | deleteById(id) | Permanently remove a record. |
1. Create (C)
Goal: To save a new entity (like a new user) to the MySQL database.
Controller: An endpoint annotated with @PostMapping receives the new entity data, typically as a JSON body in the request.
@PostMapping("/addStudent")
public String postDetails(@RequestBody StudentEntity studentEntity){
System.out.println("Student entity received: "+ studentEntity);
//we are gonna access the save details function via the service class
studentService.saveDetails(studentEntity);
return "ADDED TO TABLE SUCCESSFULLY";
}
Service: The Controller passes the data to a service method, which then calls the Repository's built-in save(entity) method.
//first function for adding to a database
public StudentEntity saveDetails(StudentEntity studentEntity){
return studentRepository.save(studentEntity);//to save and access we have to use repo
//save saves our data in our table
}
Result: A new row is inserted into the corresponding MySQL table.
2. Read (R)
Goal: To fetch data from the database. This usually involves two main scenarios:
Read All: An endpoint annotated with @GetMapping (e.g., /api/users). The Service calls the Repository's findAll() method, returning a list of all entities.
@GetMapping("/getStudent")
public List<StudentEntity> getDetails(){
return studentService.getAllDetails();
}
Read by ID: An endpoint like /api/users/{id}. The Controller uses the path variable (id) to call the Service, which in turn calls the Repository's findById(id) method. This method returns an Optional, requiring a check to handle cases where the ID does not exist.
@GetMapping("/getStudent/{id}")
public StudentEntity getDetailsById(@PathVariable int id){
return studentService.getAllDetailsById(id);
}
The service code for both
//get all details
public List<StudentEntity> getAllDetails(){
return studentRepository.findAll();
}
//fetch data by id
//we are using here entity itself cause we are returning a row itself , cause it is also an object of student hence we are returning so
public StudentEntity getAllDetailsById(int id){
return studentRepository.findById(id).orElse(null);
}
3. Update (U)
Goal: To modify an existing entity in the database.
Controller: An endpoint annotated with @PutMapping (e.g., /api/users/{id}). It takes both the ID (to find the existing record) and the updated entity data.
@PostMapping("/updateStudent")
public StudentEntity updateDetails(@RequestBody StudentEntity studentEntity){
return studentService.updateAllDetail(studentEntity);
}
Service:
First, the service calls findById(id) to retrieve the existing record.
If the record exists, the new data is applied to the existing entity object.
Finally, the service calls the Repository's save(updatedEntity) method again. Since the entity already has an ID, Spring Data JPA recognizes it as an update operation instead of an insert.
public StudentEntity updateAllDetail(StudentEntity studentEntity){
StudentEntity updateStudent = studentRepository.findById(studentEntity.getId()).orElse(null);//incase if the id is not present then we sent null
if(updateStudent != null)
{
updateStudent.setMark(studentEntity.getMark());
updateStudent.setName(studentEntity.getName());
studentRepository.save(updateStudent);
return updateStudent;
}
return null;
}
4. Delete (D)
Goal: To remove a record from the database.
Controller: An endpoint annotated with @DeleteMapping (e.g., /api/users/{id}).
@DeleteMapping("/deleteStudent/{id}")
public String deleteStudent(@PathVariable int id){
if(studentService.deleteStudentById(id))
return "Deleted Successfullly";
else {
return "Cant Delete";
}
Service: The Controller passes the ID to the service, which calls the Repository's deleteById(id) method.
public boolean deleteStudentById(int id ){
studentRepository.deleteById(id);//we cant studentEnitity type , cause it will not return that after deletion
return true;
}
Result: The corresponding record is permanently removed from the MySQL table.
By understanding these four operations and their simple mapping to Spring Boot's layered architecture and Spring Data JPA, you have the fundamental building blocks to create any data-driven application.
Wait, how do you configure a database? Let's see....
There is a file called application.properties in the Spring Boot application folder; you have to configure it with your database.
First of all you have to create a database; you can use MySQL Workbench for it or any other platform.
After that you can write these commands in your application.properties file:
# ===============================
# = DATA SOURCE CONFIGURATION
# ===============================
spring.datasource.url=jdbc:mysql://localhost:3306/your_database_name?useSSL=false&serverTimezone=UTC
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# ===============================
# = JPA / HIBERNATE CONFIGURATION
# ===============================
# Hibernate dialect for MySQL
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
# Automatically create or update tables based on entities
# Options: none, validate, update, create, create-drop
spring.jpa.hibernate.ddl-auto=update
# Show SQL statements in console
spring.jpa.show-sql=true
# Format SQL output for readability
spring.jpa.properties.hibernate.format_sql=true
# ===============================
# = SERVER CONFIGURATION
# ===============================
# Server port (optional)
server.port=8080
Replace the credentials, like the password and database name, with your database name and password.
Folder structure:
springboot-mvc-demo/
│
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── demo/
│ │ │ ├── controller/
│ │ │ │ └── HomeController.java
│ │ │ │
│ │ │ ├── model/
│ │ │ │ └── User.java
│ │ │ │
│ │ │ ├── repository/
│ │ │ │ └── UserRepository.java
│ │ │ │
│ │ │ ├── service/
│ │ │ │ └── UserService.java
│ │ │ │
│ │ │ └── DemoApplication.java
│ │ │
│ │ ├── resources/
│ │ │ ├── static/ # static assets (CSS, JS, images)
│ │ │ ├── templates/ # Thymeleaf (or JSP) views
│ │ │ │ └── index.html
│ │ │ ├── application.properties
│ │ │ └── application.yml # (alternative config)
│ │ │
│ │ └── webapp/ # optional if using JSP views
│ │ └── WEB-INF/
│ │ └── views/
│ │ └── home.jsp
│ │
│ └── test/
│ └── java/
│ └── com/
│ └── example/
│ └── demo/
│ └── DemoApplicationTests.java
│
├── pom.xml # if using Maven
└── build.gradle # if using Gradle
Ok, so now you can just get started. This is the basic step, and now you just have to build on top of it.
Good luck.
See the code at Github
If you have any suggestions for improvement, please feel free to leave a comment or reach out to me via inbox :)
Top comments (0)