Read/Write to database from Spring Boot RESTful service

Vidisha Pal
6 min readMar 24, 2022

--

We will create a simple Spring Boot app that will have a RESTful API to save data to H2 database. We will then retrieve the data from the database and finally update the data.

H2 is an in-memory database. Therefore, any data saved to the database is lost once we shut down or restart the Spring boot application.

Let us assume that we have a personal blog where users can add comments and view all existing comments.

The Spring boot app will save new user comments from this blog in an in-memory database.

To begin, we open Spring Initializr from https://start.spring.io/ and add the below dependencies. Click on Generate and after the project downloads, we open it in our IDE of choice (I am using IntelliJ ).

After we open the project in our IDE, let us create a file called application.yml under the src/main/resources folder.

In this file we configure the name of our application as blog-service under the spring.application.name property.

We also configure our application to run on port 8010. The property for this is server.port

To connect to H2 database we configure the URL, username, password and the database driver with the following properties spring.datasource.url, spring.datasource.username, spring.datasource.password and spring.datasource.driverClassName respectively.

Finally, we want to enable the H2 console so that we can connect to our database and view the tables and records.

To enable H2 console, we configure spring.h2.console.enabled to true.

To add user comments from our blog into our database, let us create a controller class, a service class, a data transfer object (DTO) class, a domain class and a repository interface as below.

Comment.java

Our domain entity class called Comment.java. The annotations @Entity and @Table is used to denote that this class is an entity and a table called comment will be mapped to this class.

@Data and @Builder annotations from project Lombok makes it easy to auto-generate boilerplate code like getters, setters and constructors.

Finally, this class will have unique id, a userId attribute to know the user who has made the comment, a description attribute to store the actual comment and a createdBy attribute to store the username of the user.

import lombok.Builder;
import lombok.Data;
import javax.persistence.*;
import java.util.Date;
import java.util.UUID;
@Entity
@Table(name="comment")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Comment {
@Id
@GeneratedValue()
private UUID id;
@Column(nullable = false)
private String userId;
@Column(nullable = false)
private String description;
private Date createdDate;@Column(nullable = false)
private String createdBy;
private Date updatedDate;}

CommentsDTO.java

The data transfer object class is used to for API requests and responses and Spring will automatically convert our comments JSON requests and responses to an object of CommentDTO.

import lombok.Builder;
import lombok.Data;
import java.util.Date;
import java.util.UUID;
import javax.validation.constraints.NotNull;
@Data
@Builder
public class CommentDTO {
private UUID id; private String userId;@NotNull(message = "comment cannot be empty")
private String description;
private Date createdDate; private Date updatedDate; private String createdBy;}

CommentsRepository.java

The CommentRepository interface extends Spring Data JPA’s CrudRepository.

We will use save() method of Spring Data JPA to save new comments and findAll() method of Spring Data JPA to retrieve all comments.

import com.pal.vidisha.springreact.myblog.domain.Comment;
import org.springframework.data.repository.CrudRepository;
import java.util.UUID;public interface CommentRepository extends CrudRepository<Comment, UUID> {
}

CommentsController.java

The controller class accepts RESTful APIs, denoted by @RestController annotation.

We also annotate the class with @RequestMapping(“/comments”), so that all requests to http://localhost:8010/comments are directed to this class.

We have defined a method called createComment which is annotated with @PostMapping. This method will accept only POST requests.

This method accepts a parameter of CommentDTO.

@RequestBody annotation denotes that the API POST request will have a body which will be mapped to CommentDTO class.

We have autowired CommentService class and this is where the business logic to save the comment is written.

Finally, we return a ResponseEntity object of type CommentDTO with a HTTP status of 201.

To retrieve all comments, we have a getComments() method. This method is annotated with @GetMapping annotation, meaning that it accepts only GET API requests.

We call getAllComments() method from CommentsService.java class where we retrieve all comments from the database and return a list of comments back as response.

import com.pal.vidisha.springreact.myblog.dto.CommentDTO;
import com.pal.vidisha.springreact.myblog.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import java.util.Date;
@RestController
@RequestMapping("/comments")
public class CommentsController {
@Autowired
CommentService commentService;
@PostMapping(
consumes = {
MediaType.APPLICATION_JSON_VALUE ,
MediaType.APPLICATION_XML_VALUE},
produces= {
MediaType.APPLICATION_JSON_VALUE ,
MediaType.APPLICATION_XML_VALUE
})
public ResponseEntity<CommentDTO> createComment(
@Valid @RequestBody CommentDTO commentDTO)
throws Exception {

commentDTO.setCreatedDate(new Date());
commentDTO.setCreatedBy("vidisha.pal@myemail.com");

commentService.saveComment(commentDTO);
return new ResponseEntity<>(commentDTO, HttpStatus.CREATED);
}
@GetMapping(
consumes = {
MediaType.APPLICATION_JSON_VALUE ,
MediaType.APPLICATION_XML_VALUE},
produces= {
MediaType.APPLICATION_JSON_VALUE ,
MediaType.APPLICATION_XML_VALUE
})
public ResponseEntity<List<CommentDTO>> getComments()
throws Exception {

List<CommentDTO> commentsDTO = commentService.getAllComments();
return new ResponseEntity<>(commentsDTO, HttpStatus.CREATED);
}
}

CommentsService.java

The service class is annotated with @Service, and is used to convert a CommentDTO object to a Comment domain entity object and then save the comment.

We use Lombok’s builder method to convert the DTO to domain object and vice versa.

There are two methods, saveComment() saves a new comment and getAllComments() retrieves all comments from the database.

To save a comment, we use commentRepository.save(comment)

To retrieve all comments from the database, we use commentRepository.findAll()

import com.pal.vidisha.springreact.myblog.domain.Comment;
import com.pal.vidisha.springreact.myblog.dto.CommentDTO;
import com.pal.vidisha.springreact.myblog.repository.CommentRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
public class CommentService {
@Autowired
CommentRepository commentRepository;
public void saveComment(CommentDTO commentDTO) {
Comment comment = Comment
.builder()
.description(commentDTO.getDescription())
.createdDate(new Date())
.createdBy(commentDTO.getCreatedBy())
.userId("1")
.build();
commentRepository.save(comment);
}

public List<CommentDTO> getAllComments(){
Iterable<Comment> comments = commentRepository.findAll();
List<CommentDTO> commentsDTO = new ArrayList<>();

comments.forEach( comment -> {
commentsDTO.add(CommentDTO
.builder()
.userId(comment.getUserId())
.description(comment.getDescription())
.createdBy(comment.getCreatedBy())
.createdDate(comment.getCreatedDate())
.build());
});
return commentsDTO;
}
}

Run the application and add a new comment

Let us start up our application now.

To run the application from terminal, use mvn spring-boot: run. Alternatively, we can run the application from the IDE.

Once the application starts up, we should be able to see the below line in the terminal logs.

The below line in the logs shows that our h2-console is available and the JDBC URl is jdbc:h2:mem:myblog.

H2 console available at '/h2-console'. Database available at 'jdbc:h2:mem:myblog'

At the moment, there are no data in our database. Let us add a new comment.

Open Postman and create a new POST request with URL http://localhost:8010/comments.

The body of the request is

{
"description": "test comment",
"userId": 11,
"createdDate": null,
"updatedDate": null,
"createdBy": "vidisha.pal@myemail.com"
}

Add headers of Content-Type and Accept with values application/json

If we post the request, we should see an HTTP status of 201, CREATED.

Finally, let us connect to H2 console. Open a new browser window and type http://localhost:8010/h2-console.

We change the JDBC URL to our configured Spring Boot application URL jdbc:h2:mem:myblog

and the password to sa

If we click Test Connection, it should be successful. Now we can connect to the database.

Finally, we can see that a new table called COMMENT has been created.

Further, our new user comment has been successfully saved in the database.

Retrieve all comments

To retrieve comments, let us add a few more comments.

Finally, if we send a GET request in Postman at http://localhost:8010/comments , we get back the three comments that we have saved.

Thank you for reading!

--

--