In this exercise, we are going to start with a completed copy of the Spring Boot Personal Library Manager application, and upgrade it to store the library items in a database, and allow us to add, update, and delete items from the library.
The first step in upgrading the application is to set up the database. Open your mysql workbench and create a new schema
called springboot2
. You do not need to create any tables, or set anything up in the database as Spring Boot JPA will
do that for you.
Next, we need to update the application.properties
file to configure the database connection. Open the
src/main/resources/application.properties
file and modify the following line to reflect your password for the MySQL
server:
spring.datasource.password=root
You should also review the other properties in the application.properties
file to ensure they are set correctly for your
environment. The spring.datasource.url
property should point to the springboot2
schema you created earlier, and
the spring.jpa.hibernate.ddl-auto
property should be set to update
to allow JPA to create and update the database
schema as needed.
Take a few moments to review the existing application. Under the main package, you will find the application class
(SpringBoot2Application
) and three sub-packages:
Controllers
: Contains the REST controllers for the applicationModels
: Contains the model classes for the applicationRepositories
: Contains the database access repository classes for the application (currently empty.)
The current set of controllers only allow reading from each of the three library item types (books, albums, and movies), and it reads them from a hard-coded list of items in the controller. We will be replacing this with a database by implementing and using JPA repository classes.
The first step in updating the models is to add an id
member to each of the models. This will allow us to uniquely
identify each item in the database. You should add this as a private int id
member to each of the models, and provide
getters and setters for the id
member. You should also update the constructors for each of the models to include the
new id
member.
Next, you should add JPA annotations to each of the models.
- Add import statements for the JPA annotations at the top of each model class:
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
- Add the
@Entity
annotation to each of the models. This tells JPA that the model is an entity that should be stored in the database. - Add the
@Id
annotation to theid
member of each model. This tells JPA that theid
member is the primary key for the entity. - Also add the
@GeneratedValue(strategy = GenerationType.IDENTITY)
annotation to theid
member of each model. This tells JPA that theid
member should be automatically generated by the database when a new entity is created.
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
// ...
}
And that's it for the models. We do not need to add @Column
annotations to the other members of the models, as JPA
will automatically choose reasonable defaults for the column names and types based on the member names and types.
Next, we need to add JPA repositories for each of the models. JPA repositories are interfaces that extend the
JpaRepository
interface, and provide methods for accessing the database. Spring Boot will automatically create
implementations of these interfaces for us.
Add a new package under the main package called Repositories
. This is where we will be adding the JPA
repositories for the application.
Right-click on the Repositories
package and create a new Java Interface called BookRepository
. This interface
should extend the JpaRepository
interface, and should be parameterized with the Book
model class and the type of
the id
member of the Book
model class (which is Integer
.)
package com.example.springBoot2.repositories;
import com.example.springBoot2.models.Book;
import org.springframework.data.jpa.repository.JpaRepository;
public interface BookRepository extends JpaRepository<Book, Integer> {
}
Once you have created the BookRepository
interface, you should add a similar interface for the Album
and Movie
The next step is to update the controllers to use the JPA repositories to access the database.
For ALL of the controllers, we will be making the following changes:
- Remove all code from the inside of the controller class.
- Add private final fields for the JPA repository that corresponds to the controllers.
- Add a constructor to the controllers that takes the JPA repository as an argument and assigns it to the private final field.
- Add a
@RequestMapping
annotation to the class to specify the base URL for the controller. (i.e.,/books
,/albums
,/movies
)
Example for the BookController
:
package com.example.springBoot2.controllers;
import com.example.springBoot2.models.Book;
import com.example.springBoot2.repositories.BookRepository;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/books")
public class BookController {
private final BookRepository bookRepository;
public BookController(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
}
- Implement the
getAllItems
method in each of the controllers. This method should call thefindAll
method on the JPA repository and return the result, and should be annotated with@GetMapping
- Implement the
getItem
method in each of the controllers. This method should call thefindById
method on the JPA repository and return the result, and should be annotated with@GetMapping('/{id}')
and have a mapped@PathVariable
parameter for theid
of typeint
. - Implement the
addItem
method in each of the controllers. This method should call thesave
method on the JPA repository and return the result, and should be annotated with@PostMapping
with a@RequestBody
parameter - Implement the
updateItem
method in each of the controllers. This method should call thesave
method on the JPA repository and return the result, and should be annotated with@PutMapping('/{id}')
with a@PathVariable
parameter for theid
of typeint
and a@RequestBody
parameter. - Implement the
deleteItem
method in each of the controllers. This method should call thedeleteById
method on the JPA repository and should be annotated with@DeleteMapping('/{id}')
with a@PathVariable
parameter for theid
of typeint
.
Once you have completed the project, and have successfully built the application and have it running, you should test the application by adding, updating, and deleting items from the library. You can use Postman to test the application by sending HTTP requests to the appropriate endpoints.
A postman collection export file is included in the project directory. You can import this file into Postman to get a set of pre-configured requests for testing this application.
After importing the Postman collection, run the "Create" requests for each of the item types (books, albums, and movies.) Then run the "Get All" requests to verify that the items were created successfully.
You can also open MySQL Workbench and browse the tables in the springboot2
schema to verify that the items were
created successfully in the database.