Java spring boot mapping

Spring Boot – Map Entity to DTO using ModelMapper

In enterprise applications, we use RESTful services to establish the communication between client and server. The general idea is that the client sends the request to the server and the server responds to that request with some response. Generally, we have three different layers in most of the application Web Layer, Business Layer, and Database Layer. The objects in these layers are mostly different from each other. For example, The web layer object is completely different from the same object in the database layer. As database objects may contain fields that are not required in the web layer object such as auto-generated fields, password fields, etc.

What is DTO?

DTO stands for Data Transfer Object, these are the objects that move from one layer to another layer. DTO can be also used to hide the implementation detail of database layer objects. Exposing the Entities to the web layer without handling the response properly can become a security issue. For example, If we have an endpoint that exposes the details of entities class called User. The endpoint handles the GET request. If the response is not handled properly with the GET endpoint one can get all the fields of the User class even the password also, which is not a good practice for writing restful services. To overcome these problems DTO came into the picture, with DTO we can choose which fields we need to expose to the web layer.

ModelMapper is a maven library which is used for the conversion of entities object to DTO and vice-versa.

In this example, we will create a restful application for user services that uses model mapper library conversion of entity to DTO.

Читайте также:  Use sqlite with java

Step By Step Implementation

Step 1: Create Spring Boot Project

In this step, we will create a spring boot project. To know how to create a spring boot project please refer to How to Create and Setup Spring Boot Project in Eclipse IDE?

Step 2: Add Dependency

In this step, we will add the dependency to our project. We will add the following dependency.

Fig 1 - Add Dependency

Step 3: Create Database Schema

We will be using MySQL for our application as a database. We need to create a database schema. Here, we will be using MySQL Workbench to create the database schema. For this Open MySQL Workbench > Schemas > Right-Click > Create Schema.

Fig 2 - Create Schema

This will open a popup window, where we need to fill in the name of our schema. Here, we are naming our schema as model_mapper_db.

Fig 3 - DB Schema Name

Once, we add the name of our schema, we need to click on Apply button, it will pop up one more window where we need to click again on Apply button. This will create our schema.

Fig 4 - Database Schema

Step 4: Configure Database

In this step, we will configure our database in our spring boot application. We need to write the following properties in our application.properties file.

server.port = 9090 #database configuration spring.datasource.url=jdbc:mysql://localhost:3306/model_mapper_db spring.datasource.username=root spring.datasource.password=root spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect #the ddl-auto=update : It will create the entity schema and map it to db automatically spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true

After this, we will run our application to see whether our application is configured to a database or not. For this go to Main Class In Spring Boot(Here, ModelMapperApplication.java) Right-Click > Run As > Java Application.

Fig 5 - Run Application

Once, we run our application as Java Application, we can see in the console that our application is started and set up the connection to the database.

Fig 6 - DB Connection Setup

Fig 6 – DB Connection Setup

Step 5: Create Entity Class

Now, we need to create our entity class. For our application, we will be using the User class as our entity class. It will have the following fields id, name, email, and password.

Источник

Java Guides

In a previous couple of tutorials, we created a Spring boot project, built CRUD Restful web services with DTO, and used the ModelMapper library to convert the JPA entity into DTO and vice versa.

Refer to previous tutorials:

In this tutorial, we will learn how to use the MapStruct library to map the JPA entity into DTO and vice versa in the Spring boot application.

MapStruct Library Overview

The MapStruct is an annotation-based code generator/mapper which greatly simplifies the mapping implementations of Java Beans. It follows convention over configuration and uses plain method invocations. MapStruct operations are very fast, type-safe, and easy to understand.

MapStruct automates the process of creating a mapper to map data objects with model objects using annotations. It creates a mapper implementation at compile time which helps the developer to figure out errors during development and makes it easy to understand.

Check the official doc to read more about MapStruct at https://mapstruct.org/

Prerequisites

This tutorial is a continuation of below three tutorials so first, create CRUD REST APIs using below tutorials:

The complete source code of this tutorial is available on my GitHub repository at Spring Boot CRUD RESTful WebServices

Development Steps

If you want to use the MapStruct library in your existing Spring boot project then follow these simple steps:

1. Add Maven Dependencies

Let’s also add the annotationProcessorPaths section to the configuration part of the maven-compiler-plugin plugin.

 org.apache.maven.plugins maven-compiler-plugin 3.8.1 17 17  org.mapstruct mapstruct-processor $ org.projectlombok lombok $ org.projectlombok lombok-mapstruct-binding $   

Note that we have added below annotation processor path to the above plugin to support MapStruct annotations with Lombok annotations:

  org.projectlombok lombok $ org.projectlombok lombok-mapstruct-binding $ 

2. User JPA Entity and UserDto

package net.javaguides.springboot.entity; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @Getter @Setter @NoArgsConstructor @AllArgsConstructor @Entity @Table(name = "users") public class User < @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String firstName; @Column(nullable = false) private String lastName; @Column(nullable = false, unique = true) private String email; >
package net.javaguides.springboot.dto; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @Setter @Getter @NoArgsConstructor @AllArgsConstructor public class UserDto < private Long id; private String firstName; private String lastName; private String email; >

3. Create UserMapper

Next, let’s create a Mapper using MapStruct. Let’s create an AutoUserMapper interface and define the mapping methods to map Entity to DTO and vice versa.

package net.javaguides.springboot.mapper; import net.javaguides.springboot.dto.UserDto; import net.javaguides.springboot.entity.User; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @Mapper public interface AutoUserMapper

Notice we did not create an implementation class for our AutoUserMapper interface because MapStruct creates it for us during compilation time.

The @Mapper annotation marks the interface as a mapping interface and lets the MapStruct processor kick in during compilation.

 UserDto mapToUserDto(User user); User mapToUser(UserDto userDto);
 AutoUserMapper MAPPER = Mappers.getMapper(AutoUserMapper.class);

Mapping Fields With Different Field Names

From our previous example, MapStruct was able to map our beans automatically because they have the same field names. So, what if a bean we are about to map has a different field name?.

@Getter @Setter @NoArgsConstructor @AllArgsConstructor @Entity @Table(name = "users") public class User < @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private String firstName; @Column(nullable = false) private String lastName; @Column(nullable = false, unique = true) private String email; >
@Setter @Getter @NoArgsConstructor @AllArgsConstructor public class UserDto < private Long id; private String firstName; private String lastName; private String emailAddress; >

When mapping different field names, we will need to configure its source field to its target field, and to do that, we will need to add @Mapping annotation for each field.

@Mapper public interface AutoUserMapper

3. Use UserMapper in Service Class to map the JPA entity into DTO and vice versa

package net.javaguides.springboot.service.impl; import lombok.AllArgsConstructor; import net.javaguides.springboot.dto.UserDto; import net.javaguides.springboot.entity.User; import net.javaguides.springboot.mapper.AutoUserMapper; import net.javaguides.springboot.mapper.UserMapper; import net.javaguides.springboot.repository.UserRepository; import net.javaguides.springboot.service.UserService; import org.apache.logging.log4j.util.Strings; import org.modelmapper.ModelMapper; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @Service @AllArgsConstructor public class UserServiceImpl implements UserService < private UserRepository userRepository; private ModelMapper modelMapper; @Override public UserDto createUser(UserDto userDto) < // Convert UserDto into User JPA Entity // User user = UserMapper.mapToUser(userDto); //User user = modelMapper.map(userDto, User.class); User user = AutoUserMapper.MAPPER.mapToUser(userDto); User savedUser = userRepository.save(user); // Convert User JPA entity to UserDto //UserDto savedUserDto = UserMapper.mapToUserDto(savedUser); //UserDto savedUserDto = modelMapper.map(savedUser, UserDto.class); UserDto savedUserDto = AutoUserMapper.MAPPER.mapToUserDto(savedUser); return savedUserDto; >@Override public UserDto getUserById(Long userId) < User user = userRepository.findById(userId).get(); //return UserMapper.mapToUserDto(user); //return modelMapper.map(user, UserDto.class); return AutoUserMapper.MAPPER.mapToUserDto(user); >@Override public List getAllUsers() < Listusers = userRepository.findAll(); // return users.stream().map(UserMapper::mapToUserDto) // .collect(Collectors.toList()); // return users.stream().map((user) -> modelMapper.map(user, UserDto.class)) // .collect(Collectors.toList()); return users.stream().map((user) -> AutoUserMapper.MAPPER.mapToUserDto(user)) .collect(Collectors.toList()); > @Override public UserDto updateUser(UserDto user) < User existingUser = userRepository.findById(user.getId()).get() existingUser.setFirstName(user.getFirstName()); existingUser.setLastName(user.getLastName()); existingUser.setEmail(user.getEmail()); User updatedUser = userRepository.save(existingUser); //return UserMapper.mapToUserDto(updatedUser); //return modelMapper.map(updatedUser, UserDto.class); return AutoUserMapper.MAPPER.mapToUserDto(updatedUser); >@Override public void deleteUser(Long userId) < userRepository.deleteById(userId); >>

4. Test CRUD REST APIs using the Postman Client

Источник

Оцените статью