Spring Boot REST API Using MySQL or MariaDB

Introduction

Spring Boot is a popular Java framework for building RESTful web services, and it provides out-of-the-box support for connecting to relational databases such as MySQL and MariaDB. In this guide, we’ll walk through the process of setting up a Spring Boot REST API with support for CRUD (Create, Read, Update, Delete) operations using either MySQL or MariaDB as the underlying database. We’ll cover everything from configuring the database connection to implementing the API endpoints for managing books in the database.

Also, see Spring Boot REST API Using the H2 database.

Spring Boot REST API Using MySQL or MariaDB

Creating a new Spring Boot project using Spring Initializr

Spring Initializr is a web-based tool that generates the initial structure of a Spring Boot project. It allows you to choose the dependencies you need and configure your project quickly and easily. To create a new Spring Boot project using Spring Initializr, follow these steps:

  1. Open a web browser and go to the Spring Initializr website at https://start.spring.io/.
  2. Select Gradle as the build tool.
  3. Select the latest version of Spring Boot as the project version.
  4. Choose a group name and an artifact name for your project. These values will be used to generate the package name for your project.
  5. Add the following dependencies to your project:
    • Spring Web
    • Spring Data JPA
    • H2 Database
  6. Click the Generate button to generate the project.

Once you have generated the project, you will get a ZIP file that contains the project files. Extract the files to a directory on your computer.

Importing the project into IntelliJ IDEA

Now that we have created our Spring Boot project, we can import it into IntelliJ IDEA. IntelliJ IDEA is a popular IDE for Java development that provides a rich set of features to help you write and debug your code. To import the project into IntelliJ IDEA, follow these steps:

  1. Open IntelliJ IDEA.
  2. Click on File > New > Project from Existing Sources.
  3. Select the directory where you extracted the project files and click Open.
  4. In the Import Project dialog, select Gradle as the project format and click Next.
  5. In the Gradle settings dialog, make sure that the Use auto-import option is checked and click OK.
  6. IntelliJ IDEA will now import the project and set up the necessary dependencies.

Once the project has been imported, you can start building your RESTful API.

Building a RESTful API for CRUD Operations

Now that we have our project set up in IntelliJ IDEA, we can start building our RESTful API. We will start with a simple API that allows us to retrieve a list of books. To build this API, we will need to create a few classes and configure our application.

Spring Boot REST API Using MySQL

Let us add MySQL support for our CRUD operations. To do this, we’ll need to make a few changes to our code.

First, we’ll need to add the MySQL connector dependency to our build.gradle file. Add the following line to the dependencies section:

implementation 'mysql:mysql-connector-java:8.0.26'

Next, we’ll need to configure our database connection in our application.properties file. Add the following lines to the file:

spring.datasource.url=jdbc:mysql://localhost:3306/bookstore
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update

This configures our application to use the MySQL database named “bookstore”, with a username of “root” and password of “password”. The spring.jpa.hibernate.ddl-auto=update line tells Spring to automatically create or update our database schema based on our entity classes.

Creating a Book class

The first thing we need to do is create a Book class that represents a book in our system. To create the Book class, follow these steps:

  1. In IntelliJ IDEA, right-click on the src/main/java directory and select New > Java Class.
  2. In the New Java Class dialog, enter Book as the class name and click OK.

We will need to update our Book entity class to work with our MySQL database. We will add JPA annotations to our class to map it to the database table. Update the class to look like this:

@Entity
@Table(name = "books")
public class Book {
 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
 
    @Column(nullable = false)
    private String title;
 
    @Column(nullable = false)
    private String author;
 
    @Column(nullable = false)
    private String description;
 
    @Column(nullable = false)
    private BigDecimal price;
 
    public Long getId() {
        return id;
    }
 
    public void setId(Long id) {
        this.id = id;
    }
 
    public String getTitle() {
        return title;
    }
 
    public void setTitle(String title) {
        this.title = title;
    }
 
    public String getAuthor() {
        return author;
    }
 
    public void setAuthor(String author) {
        this.author = author;
    }
 
    public String getDescription() {
        return description;
    }
 
    public void setDescription(String description) {
        this.description = description;
    }
 
    public BigDecimal getPrice() {
        return price;
    }
 
    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}

The @Entity annotation tells Spring that this class is a JPA entity, and the @Table(name = "books") annotation tells Spring to map this entity to a database table named “books”. We also added annotations to each field to specify their column names and constraints.

Next, we will need to create our BookRepository interface to extend the JpaRepository interface provided by Spring Data JPA. This interface provides us with a set of convenient methods for performing common database operations. Update the interface to look like this:

@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
}

Now we can use the methods provided by JpaRepository, such as save(), findById(), findAll(), deleteById(), and many more, to perform CRUD operations on our Book entity.

Finally, we will need to create our BookController to use our BookRepository to interact with the database. Update the constructor to inject an instance of BookRepository:

@RestController
@RequestMapping("/api/books")
public class BookController {
 
    private final BookRepository bookRepository;
 
    @Autowired
    public BookController(BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
 
    // ...
}

Now we can use the methods provided by BookRepository to handle incoming requests. For example, to create a new book in the database, we can use the save() method to persist a new Book object:

@PostMapping
public Book createBook(@RequestBody Book book) {
    return bookRepository.save(book);
}

Similarly, to retrieve all books from the database, we can use the findAll() method:

@GetMapping
public List<Book> getAllBooks() {
    return bookRepository.findAll();
}

To retrieve a single book by ID, we can use the findById() method:

@GetMapping("/{id}")
public ResponseEntity<Book> getBookById(@PathVariable(value = "id") Long bookId) {
    Optional<Book> book = bookRepository.findById(bookId);
    if (book.isPresent()) {
        return ResponseEntity.ok().body(book.get());
    } else {
        return ResponseEntity.notFound().build();
    }
}

To update an existing book, we can use the save() method again:

@PutMapping("/{id}")
public ResponseEntity<Book> updateBook(@PathVariable(value = "id") Long bookId,
                                        @RequestBody Book bookDetails) {
    Optional<Book> optionalBook = bookRepository.findById(bookId);
    if (optionalBook.isPresent()) {
        Book book = optionalBook.get();
        book.setTitle(bookDetails.getTitle());
        book.setAuthor(bookDetails.getAuthor());
        book.setDescription(bookDetails.getDescription());
        book.setPrice(bookDetails.getPrice());
        Book updatedBook = bookRepository.save(book);
        return ResponseEntity.ok().body(updatedBook);
    } else {
        return ResponseEntity.notFound().build();
    }
}

And finally, to delete a book from the database, we can use the deleteById() method:

@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteBook(@PathVariable(value = "id") Long bookId) {
    bookRepository.deleteById(bookId);
    return ResponseEntity.noContent().build();
}

And that’s it! With these changes, our RESTful API now supports CRUD operations using a MySQL database.

Here is the complete BookController class that supports CRUD operations with MySQL database:

@RestController
@RequestMapping("/api/books")
public class BookController {

    @Autowired
    private BookRepository bookRepository;

    @GetMapping
    public List<Book> getAllBooks() {
        return bookRepository.findAll();
    }

    @GetMapping("/{id}")
    public ResponseEntity<Book> getBookById(@PathVariable(value = "id") Long bookId) {
        Optional<Book> book = bookRepository.findById(bookId);
        if (book.isPresent()) {
            return ResponseEntity.ok().body(book.get());
        } else {
            return ResponseEntity.notFound().build();
        }
    }

    @PostMapping
    public Book createBook(@RequestBody Book book) {
        return bookRepository.save(book);
    }

    @PutMapping("/{id}")
    public ResponseEntity<Book> updateBook(@PathVariable(value = "id") Long bookId,
                                            @RequestBody Book bookDetails) {
        Optional<Book> optionalBook = bookRepository.findById(bookId);
        if (optionalBook.isPresent()) {
            Book book = optionalBook.get();
            book.setTitle(bookDetails.getTitle());
            book.setAuthor(bookDetails.getAuthor());
            book.setDescription(bookDetails.getDescription());
            book.setPrice(bookDetails.getPrice());
            Book updatedBook = bookRepository.save(book);
            return ResponseEntity.ok().body(updatedBook);
        } else {
            return ResponseEntity.notFound().build();
        }
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteBook(@PathVariable(value = "id") Long bookId) {
        bookRepository.deleteById(bookId);
        return ResponseEntity.noContent().build();
    }
}

MySQL database schema

If you want to create the database and the book table manually, then use the following schema.

Here is the MySQL database schema for the books table:

CREATE TABLE `books` (
  `id` int NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `author` varchar(255) NOT NULL,
  `description` text,
  `price` decimal(10,2) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

You can import this schema into your MySQL database using any MySQL client like MySQL Workbench or phpMyAdmin. Alternatively, you can also run this SQL script from the command line using the mysql command-line tool:

mysql -u your_username -p your_database_name < books_schema.sql

Just make sure to replace your_username and your_database_name with your actual MySQL username and database name.

In conclusion, Spring Boot provides a convenient and powerful framework for building RESTful APIs. With the help of Spring Data JPA, we can easily integrate our API with a database and perform common database operations with minimal code. By following the steps outlined in this guide, you should now have a solid understanding of how to build a Spring Boot RESTful API with MySQL support.

Spring Boot REST API Using MariaDB

Here is how you can modify the application.properties file to use MariaDB instead of MySQL:

spring.datasource.url=jdbc:mariadb://localhost:3306/library
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MariaDBDialect

And here is the complete BookController class that supports CRUD operations with MariaDB:

@RestController
@RequestMapping("/api/books")
public class BookController {

    @Autowired
    private BookRepository bookRepository;

    @GetMapping
    public List<Book> getAllBooks() {
        return bookRepository.findAll();
    }

    @GetMapping("/{id}")
    public ResponseEntity<Book> getBookById(@PathVariable(value = "id") Long bookId) {
        Optional<Book> book = bookRepository.findById(bookId);
        if (book.isPresent()) {
            return ResponseEntity.ok().body(book.get());
        } else {
            return ResponseEntity.notFound().build();
        }
    }

    @PostMapping
    public Book createBook(@RequestBody Book book) {
        return bookRepository.save(book);
    }

    @PutMapping("/{id}")
    public ResponseEntity<Book> updateBook(@PathVariable(value = "id") Long bookId,
                                            @RequestBody Book bookDetails) {
        Optional<Book> optionalBook = bookRepository.findById(bookId);
        if (optionalBook.isPresent()) {
            Book book = optionalBook.get();
            book.setTitle(bookDetails.getTitle());
            book.setAuthor(bookDetails.getAuthor());
            book.setDescription(bookDetails.getDescription());
            book.setPrice(bookDetails.getPrice());
            Book updatedBook = bookRepository.save(book);
            return ResponseEntity.ok().body(updatedBook);
        } else {
            return ResponseEntity.notFound().build();
        }
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteBook(@PathVariable(value = "id") Long bookId) {
        bookRepository.deleteById(bookId);
        return ResponseEntity.noContent().build();
    }
}

We will need to add the MariaDB connector dependency to our build.gradle file. Add the following line to the dependencies section:

dependencies {
    implementation 'org.mariadb.jdbc:mariadb-java-client:2.7.4'
    // other dependencies...
}

And also make sure to update the BookRepository interface to extend JpaRepository<Book, Long> instead of CrudRepository<Book, Long>:

public interface BookRepository extends JpaRepository<Book, Long> {
}

With these changes, you should be able to use MariaDB instead of MySQL in your Spring Boot application.

Testing the API

Once you’ve implemented your Spring Boot REST API with MySQL or MariaDB support, you can test the CRUD (Create, Read, Update, Delete) operations using Postman, a popular API testing tool. Here’s how to test each of the CRUD operations:

  1. Creating a new book: In Postman, make a POST request to the /api/books endpoint with a JSON payload representing the book you want to create. For example:
{
  "title": "The Great Gatsby",
  "author": "F. Scott Fitzgerald",
  "description": "The Great Gatsby",
  "price": 1925
}

If the request is successful, you should receive a 201 Created response with the newly created book object in the response body.

  1. Retrieving a book: In Postman, make a GET request to the /api/books/{id} endpoint, where {id} is the ID of the book you want to retrieve. If the book exists, you should receive a 200 OK response with the book object in the response body.
  2. Updating a book: In Postman, make a PUT request to the /api/books/{id} endpoint with a JSON payload representing the updated book. For example:
{
  "title": "The Great Gatsby",
  "author": "F. Scott Fitzgerald",
  "description": "The Great Gatsby",
  "price": 1925
}

If the request is successful, you should receive a 200 OK response with the updated book object in the response body.

  1. Deleting a book: In Postman, make a DELETE request to the /api/books/{id} endpoint, where {id} is the ID of the book you want to delete. If the request is successful, you should receive a 204 No Content response with no response body.

By testing each of these CRUD operations using Postman, you can ensure that your Spring Boot REST API with MySQL or MariaDB support is working as expected and can handle all the necessary data manipulations.

Conclusion

In this guide, we’ve walked through the process of building a Spring Boot REST API with support for CRUD operations using either MySQL or MariaDB as the underlying database. We started by setting up the database connection and creating a database schema for storing books. Then, we implemented the API endpoints for creating, reading, updating, and deleting books. With this foundation, you can extend the API to add more functionality and integrate it with other systems. Spring Boot’s easy-to-use framework and built-in database support make it a great choice for building robust and scalable RESTful APIs.

Visit our springboot-projects GitHub repository for the code.

Also, see the example code JavaExamples_NoteArena in our GitHub repository. See complete examples in our GitHub repositories.

Follow us on social media
Follow Author