📘 Premium Read: Access my best content on Medium member-only articles — deep dives into Java, Spring Boot, Microservices, backend architecture, interview preparation, career advice, and industry-standard best practices.
✅ Some premium posts are free to read — no account needed. Follow me on Medium to stay updated and support my writing.
🎓 Top 10 Udemy Courses (Huge Discount): Explore My Udemy Courses — Learn through real-time, project-based development.
▶️ Subscribe to My YouTube Channel (172K+ subscribers): Java Guides on YouTube
- Building Real-Time REST APIs with Spring Boot and Deploy on AWS Cloud
- Testing Spring Boot Application with JUnit and Mockito (Includes Testcontainers)
- Learn Spring Data JPA with Hibernate: The Masterclass
MariaDB Database Overview
MariaDB is a popular fork of MySQL created by MySQL's original developers. It grew out of concerns related to MySQL's acquisition by Oracle. It offers support for both small data processing tasks and enterprise needs. It aims to be a drop-in replacement for MySQL requiring only a simple uninstall of MySQL and an install of MariaDB. MariaDB offers the same features as MySQL and much more.Key Features of MariaDB
- All of MariaDB is under GPL, LGPL, or BSD.
- MariaDB includes a wide selection of storage engines, including high-performance storage engines, for working with other RDBMS data sources.
- MariaDB uses a standard and popular querying language.
- MariaDB runs on a number of operating systems and supports a wide variety of programming languages.
- MariaDB offers support for PHP, one of the most popular web development languages.
- MariaDB offers Galera cluster technology.
- MariaDB also offers many operations and commands unavailable in MySQL and eliminates/replaces features impacting performance negatively.
Complete Spring Boot MariaDB CRUD Example
In our example application, we will perform CRUD operations on an Employee entity. We develop CRUD Rest web services using Spring boot and database as MariaDB. Finally, we will test it using Postman Client.MariaDB Configuration
Before configuring MariaDB in the Spring boot project, first, you need to create a database in the MariaDB server.mysql -u root
create database springboot_demo;
MariaDB Dependencies
<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client --> <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> <version>2.5.2</version> </dependency>
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>2.5.2</version>
</dependency>
MariaDB Configuration in Spring Boot Project
spring.datasource.url=jdbc:mariadb://localhost:3306/springboot_demo
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.hibernate.ddl-auto=create-drop
You don’t need to create any tables. The employees table will automatically be created by the Hibernate from the Employee entity that we will define in the next step.
Create JPA Entity - Employee.java
- id - primary key
- firstName - Employee first name
- lastName - Employee last name
- emailId - Employee email address
package net.guides.springboot2.springboot2jpacrudexample.model; import jakarta.persistence.*; @Entity @Table(name = "employees") public class Employee { private long id; private String firstName; private String lastName; private String emailId; public Employee() { } public Employee(String firstName, String lastName, String emailId) { this.firstName = firstName; this.lastName = lastName; this.emailId = emailId; } @Id @GeneratedValue(strategy = GenerationType.AUTO) public long getId() { return id; } public void setId(long id) { this.id = id; } @Column(name = "first_name", nullable = false) public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } @Column(name = "last_name", nullable = false) public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } @Column(name = "email_address", nullable = false) public String getEmailId() { return emailId; } public void setEmailId(String emailId) { this.emailId = emailId; } }
Create a Spring Data Repository - EmployeeRepository.java
package net.guides.springboot2.springboot2jpacrudexample.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import net.guides.springboot2.springboot2jpacrudexample.model.Employee; @Repository public interface EmployeeRepository extends JpaRepository<Employee, Long>{ }
9. Create Spring Rest Controller - EmployeeController.java
import java.util.HashMap; import java.util.List; import java.util.Map; import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import net.guides.springboot2.springboot2jpacrudexample.exception.ResourceNotFoundException; import net.guides.springboot2.springboot2jpacrudexample.model.Employee; import net.guides.springboot2.springboot2jpacrudexample.repository.EmployeeRepository; @RestController @RequestMapping("/api/v1") public class EmployeeController { @Autowired private EmployeeRepository employeeRepository; @GetMapping("/employees") public List < Employee > getAllEmployees() { return employeeRepository.findAll(); } @GetMapping("/employees/{id}") public ResponseEntity < Employee > getEmployeeById(@PathVariable(value = "id") Long employeeId) throws ResourceNotFoundException { Employee employee = employeeRepository.findById(employeeId) .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId)); return ResponseEntity.ok().body(employee); } @PostMapping("/employees") public Employee createEmployee(@Valid @RequestBody Employee employee) { return employeeRepository.save(employee); } @PutMapping("/employees/{id}") public ResponseEntity < Employee > updateEmployee(@PathVariable(value = "id") Long employeeId, @Valid @RequestBody Employee employeeDetails) throws ResourceNotFoundException { Employee employee = employeeRepository.findById(employeeId) .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId)); employee.setEmailId(employeeDetails.getEmailId()); employee.setLastName(employeeDetails.getLastName()); employee.setFirstName(employeeDetails.getFirstName()); final Employee updatedEmployee = employeeRepository.save(employee); return ResponseEntity.ok(updatedEmployee); } @DeleteMapping("/employees/{id}") public Map < String, Boolean > deleteEmployee(@PathVariable(value = "id") Long employeeId) throws ResourceNotFoundException { Employee employee = employeeRepository.findById(employeeId) .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId)); employeeRepository.delete(employee); Map < String, Boolean > response = new HashMap < > (); response.put("deleted", Boolean.TRUE); return response; } }
Exception(Error) Handling for RESTful Services
Resource Not Present
{
"timestamp": 1512713804164,
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/some-dummy-url"
}
What happens when we throw an Exception?
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends Exception{
private static final long serialVersionUID = 1L;
public ResourceNotFoundException(String message){
super(message);
}
}
Customizing Error Response Structure
import java.util.Date;
public class ErrorDetails {
private Date timestamp;
private String message;
private String details;
public ErrorDetails(Date timestamp, String message, String details) {
super();
this.timestamp = timestamp;
this.message = message;
this.details = details;
}
public Date getTimestamp() {
return timestamp;
}
public String getMessage() {
return message;
}
public String getDetails() {
return details;
}
}
import java.util.Date;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<?> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<?> globleExcpetionHandler(Exception ex, WebRequest request) {
ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
return new ResponseEntity<>(errorDetails, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Running Application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- @Configuration tags the class as a source of bean definitions for the application context.
- @EnableAutoConfiguration tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.
- Normally you would add @EnableWebMvc for a Spring MVC app, but Spring Boot adds it automatically when it sees spring-webmvc on the classpath. This flags the application as a web application and activates key behaviors such as setting up a DispatcherServlet.
- @ComponentScan tells Spring to look for other components, configurations, and services in the hello package, allowing it to find the controllers.
Integration Testing for REST APIs
There is a separate beautiful article for integration testing for REST APIs on:>> Spring Boot 2 REST APIs Integration Testing
It looks like that class was deleted for Spring Boot 2.0.0.RC1. They expect you to use different exceptions for this namely InvalidConfigurationPropertyValueException.
ReplyDelete