- vừa được xem lúc

Hướng dẫn sử dụng MapStruct + Lombok

0 0 2

Người đăng: Tran Nhan

Theo Viblo Asia

Hướng dẫn sử dụng MapStruct + Lombok

Hướng dẫn mì ăn liền kết hợp 2 thư viện để thực hiện mapping entity và dto trong Java.


Các dependencies

  • Dependencies trong code SpringBoot(3.4.1), springweb,jpa, sql (ở đây là mysql, nhớ tạo db trước nha mấy bro).
  • Dependencies cho lombok và Mapstruct (thêm lombok-mapstruct-binding nếu dùng lombok+mapstruct).
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.1</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.nhan</groupId> <artifactId>myhibernate</artifactId> <version>0.0.1-SNAPSHOT</version> <name>myhibernate</name> <description>myhibernate</description> <url/> <licenses> <license/> </licenses> <developers> <developer/> </developers> <scm> <connection/> <developerConnection/> <tag/> <url/> </scm> <properties> <java.version>17</java.version> <org.mapstruct.version>1.6.3</org.mapstruct.version> <org.lombok.version>1.18.36</org.lombok.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${org.lombok.version}</version> <optional>true</optional> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct</artifactId> <version>${org.mapstruct.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok-mapstruct-binding</artifactId> <version>0.2.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${java.version}</source> <target>${java.version}</target> <annotationProcessorPaths> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${org.lombok.version}</version> </path> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${org.mapstruct.version}</version> </path> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok-mapstruct-binding</artifactId> <version>0.2.0</version> </path> </annotationProcessorPaths> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${org.lombok.version}</version> </exclude> <exclude> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${org.mapstruct.version}</version> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>

Application.properties

spring.application.name=myhibernate spring.datasource.url=${DATASOURCE_URL:jdbc:mysql://localhost:3306/myhibernate} spring.datasource.username=${DATASOURCE_USERNAME:nhan} spring.datasource.password=${DATASOURCE_PASSWORD:nhan} spring.data.jdbc.dialect=mysql spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

Code implements

Ví dụ với 2 endpoint:

Endpoint Method Description Request Body Response Body
/customers POST Create new customer CustomerDto CustomerDto
/customers/all GET Get all customers Không List<CustomerDto>

Entity

Sử dụng Jpa để mapping tự động. Tạo entity đơn giản là Customer

  • Lớp Customer
@AllArgsConstructor @NoArgsConstructor @Getter @Setter @Entity public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private String email; private String gender; }

Dto Customer

public record CustomerDto(Long id, String name, String email, String gender) { }

MapStuct Mapper

@Mapper(componentModel = "spring") public interface CustomerMapper { // Nếu muốn dùng instance thay vì inject
// CustomerMapper INSTANCE = Mappers.getMapper( CustomerMapper.class);  @Mapping(target = "id", ignore = true) Customer toEntity(CustomerDto customerDto); CustomerDto toDto(Customer customer); }

Respository

public interface CustomerRepository extends JpaRepository<Customer, Long> { }

Service và impl

public interface CustomerService { CustomerDto createCustomer(CustomerDto customerDto); List<CustomerDto> getAllCustomers(); } // implement
@Service public class CustomerServiceImpl implements CustomerService { // private CustomerMapper customerMapper = CustomerMapper.INSTANCE;  private final CustomerMapper customerMapper; private final CustomerRepository customerRepository; public CustomerServiceImpl(CustomerMapper customerMapper, CustomerRepository customerRepository) { this.customerMapper = customerMapper; this.customerRepository = customerRepository; } @Override public CustomerDto createCustomer(CustomerDto customerDto) { Customer customer = customerMapper.toEntity(customerDto); customer = customerRepository.save(customer); return customerMapper.toDto(customer); } @Override public List<CustomerDto> getAllCustomers() { return customerRepository.findAll().stream().map(customerMapper::toDto).toList(); } }

Controller

@RestController @RequestMapping("/customers") public class CustomerController { private final CustomerService customerService; public CustomerController(CustomerService customerService) { this.customerService = customerService; } @PostMapping public CustomerDto createCustomer(@RequestBody CustomerDto customerDto) { return customerService.createCustomer(customerDto); } @GetMapping("/all") public List<CustomerDto> getAllCustomers() { return customerService.getAllCustomers(); } }

Test api

Ở đây mình dùng Httpie Desktop để test 2 endpoint trên

  1. Tạo mới Customer. Endpoint /customers, method post, body CusomerDto
{ "id": 2, "name": "tran nhan", "email": "nhan@gmail.com", "gender": "male"
}

Response: (id là generation nên tạo cusomer truyền id không bị ảnh hưởng)

create cusomer response
  1. Lấy danh sách cusomer. Request: /cusomers/all, method get. Response:
get all cusomer response

Notes

  • Để hiểu rõ hơn các class được sinh ra xem các file được tự động mapping ở targets/classses/package_tương_ứng.
  • Đi một ngày đàng học một sàng khôn. Viết cho đã, đọc github, stackoverflow cho đã rồi up bài xong search ra bài của ông anh khác đã viết trên viblo là đảo lombok xuống dưới mapstruct là không cần thêm cái lombok-mapstruct-binding. Viết là để chia sẻ kiến thức nha anh em. Cái mới ra đời chưa chắc tốt hơn cái cũ nhưng chắc chắn là sẽ có cái tác dụng gì đó, rác còn có thể tái chế mà ae.

References

Bình luận

Bài viết tương tự

- vừa được xem lúc

Sử dụng Hibernate với Kotlin dựa trên Spring Boot

Trong bài viết sẽ mô phỏng các bước để sử dụng hibernate với Kotlin. Hibernate là một framework phụ vụ object-relational-mapping(ORM) trên JVM sử dụng để lưu trữ liên tục các Plain Old Java Object (POJOs) trong quan hệ cơ sở dữ liệu.

0 0 35

- vừa được xem lúc

Cách tốt nhất để ánh xa mối quan hệ @OneToMany với JPA và Hibernate

1. Giới thiệu.

0 0 66

- vừa được xem lúc

Java Spring - Tổng hợp các chủ đề từ cơ bản đến nâng cao

Trong bài viết này mình xin được tổng hợp một số chủ đề từ cơ bản đến nâng cao khi lập trình web với Java. Bên cạnh các kiến thức căn bản như làm thế nào để tạo mới project từ https://start.

0 0 63

- vừa được xem lúc

Dùng hibernate đã lâu? Thế bạn có biết JPA là gì?

JPA là gì. JPA có thể xem như cầu nối giữa Java object và cơ sở dữ liệu quan hệ.

0 0 30

- vừa được xem lúc

Giải thích về các Framework Java phổ biến

Java là một trong những ngôn ngữ lập trình phổ biến nhất hiện nay để phát triển các ứng dụng web, di động và máy tính. Có rất nhiều framework được phát triển để hỗ trợ các nhà phát triển trong việc xâ

0 0 22

- vừa được xem lúc

Vấn đề N+1 queries

1. Vấn đề N+1 queries là gì.

0 0 11