Java/Spring

[SpringBoot/JPA] ModelMapper๋กœ Entity์™€ DTO ๋ณ€ํ™˜ํ•˜๊ธฐ

๋ฒผ๋ฆฌ01 2024. 3. 13. 00:32

๐Ÿ“Œํ™˜๊ฒฝ

IntelliJ Ultimate

Java 17

 

Spring boot 3.2.3

Gradle - Groovy

Dependencies: 

Spring Web

Thymeleaf

Spring Data JPA

lombok

MariaDB 10.11

Spring Dev tool

 

๐Ÿ“ŒModelMapper๋ž€?

์„œ๋กœ ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ๊ฐ’์„ ํ•œ๋ฒˆ์— ๋ณต์‚ฌ(๋งคํ•‘)ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ. ์˜ˆ๋ฅผ ๋“ค์–ด, ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์™€ ์ผ์น˜ํ•˜๋Š” ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด๊ฐ€ ์žˆ๊ณ  ์ด ๊ฐ’์„ DTO์— ๋‹ด๊ฑฐ๋‚˜ ํ˜น์€ ๊ทธ ๋ฐ˜๋Œ€์˜ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋ ค๊ณ  ํ•  ๋•Œ, ํ•„๋“œ๋ฅผ ํ•˜๋‚˜์”ฉ ๋งคํ•‘์‹œํ‚จ๋‹ค๋ฉด ๋ˆ„๋ฝ๋˜๊ฑฐ๋‚˜ ๊ฐ’์ด ๋ณ€์งˆ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. `modelMapper`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—”ํ‹ฐํ‹ฐ์™€ DTO์˜ ๋ณ€ํ™˜์„ ๊ฐ„๋‹จํžˆ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

๐Ÿ“Œํ๋ฆ„

1. `build.gradle`์— `modelMapper`์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

2. `configuration` ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

 

๐Ÿ“Œ๊ตฌํ˜„

`build.gradle`์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

dependencies{
  .
  .
  .
  implementation 'org.modelmapper:modelmapper:3.1.0'
}

 

 

config ํŒจํ‚ค์ง€์— `RootConfig` ํด๋ž˜์Šค๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

package org.zerock.b02.config;

import org.modelmapper.ModelMapper;
import org.modelmapper.convention.MatchingStrategies;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RootConfig {

    @Bean
    public ModelMapper getMapper(){
        ModelMapper modelMapper = new ModelMapper();
        modelMapper.getConfiguration()
                .setFieldMatchingEnabled(true)
                .setFieldAccessLevel(org.modelmapper.config.Configuration.AccessLevel.PRIVATE)
                .setMatchingStrategy(MatchingStrategies.LOOSE);

        return modelMapper;
    }
}

 

 

 

dto ํŒจํ‚ค์ง€์— `BoardDTO`๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. ํ•„๋“œ๋Š” `Board`์™€ ๋™์ผํ•˜๋‹ค.

 

package org.zerock.b02.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BoardDTO {

    private Long bno;
    private String title;
    private String content;
    private String writer;
    private LocalDateTime regDate;
    private LocalDateTime modDate;
}

 

 

 

โœ๏ธ CREATE(INSERT)

service ํŒจํ‚ค์ง€์— `BoardService` ์ธํ„ฐํŽ˜์ด์Šค์™€ ๊ทธ ๊ตฌํ˜„์ฒด๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

 

package org.zerock.b02.service;

import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.stereotype.Service;
import org.zerock.b02.domain.Board;
import org.zerock.b02.dto.BoardDTO;
import org.zerock.b02.repository.BoardRepository;

@Service
@Slf4j
@RequiredArgsConstructor
@Transactional
public class BoardServiceImpl implements BoardService{

    private final ModelMapper modelMapper;
    private final BoardRepository boardRepository;

    @Override
    public Long register(BoardDTO boardDTO) {
        Board board = modelMapper.map(boardDTO, Board.class);

        Long bno = boardRepository.save(board).getBno();

        return bno;

    }
}

 

 

์—ฌ๋Ÿฌ ๋ฒˆ์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์ด ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ ์šฉํ•ด์•ผํ•œ๋‹ค.

๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ ํ›„์—๋Š” ๋ฐฉ๊ธˆ ์ž‘์„ฑํ•œ ๊ฒŒ์‹œ๊ธ€๋กœ ์ด๋™ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— bno๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

 

 

 

 

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

 

package org.zerock.b02.service;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.zerock.b02.dto.BoardDTO;

@SpringBootTest
@Slf4j
public class BoardServiceTests {

    @Autowired
    private BoardService boardService;

    @Test
    public void registerTest(){

//        ์—ฌ๋Ÿฌ ๋ฒˆ์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์ด ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ ์šฉํ•ด์•ผํ•จ
//        @Transactional ์• ๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์Šคํ”„๋ง์ด ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ๊ฐ์‹ธ๋Š” ๋ณ„๋„์˜ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ฆ
//        [boardService class name] org.zerock.b02.service.BoardServiceImpl$$SpringCGLIB$$0
        log.info("[boardService class name] " + boardService.getClass().getName());

        BoardDTO boardDTO = BoardDTO.builder()
                .title("Sample title...")
                .content("Sample content...")
                .writer("user00")
                .build();

        Long bno = boardService.register(boardDTO);

        log.info("[after register bno] " + bno);
    }
}

 

 

2024-03-13T00:21:59.047+09:00  INFO 60814 --- [b02] [    Test worker] o.zerock.b02.service.BoardServiceTests   : [after register bno] 101

 

 

 

DB์— ์ž˜ ๋“ค์–ด๊ฐ”๊ณ  bno์ด ์ง„์งœ ๋ฝ‘ํž˜ ใ„ทใ„ท ์–ด์ผ€ ํ•œ ๊ฑฐ์ง€ (24/03/13) ๊ณต๋ถ€ํ•  ๊ฒƒ

 

 

 

๐Ÿ“Ž READ(SELECT)

 

// BoardServiceImpl

    @Override
    public BoardDTO readOne(Long bno) {

        Optional<Board> result = boardRepository.findById(bno);

    //        ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์™„์ „ํžˆ ์ผ์น˜ํ•˜๋Š” ์—”ํ‹ฐํ‹ฐ ๊ฐ์ฒด
        Board board = result.orElseThrow();

    //        ์—”ํ‹ฐํ‹ฐ -> dto ๋ณ€ํ™˜
        BoardDTO boardDTO = modelMapper.map(board, BoardDTO.class);

        return boardDTO;
    }

 

   @Test
    public void readOneTest(){
        Long bno = 101L;

        BoardDTO boardDTO = boardService.readOne(bno);

        log.info("[readOne] " + boardDTO);
    }

 

2024-03-13T00:31:42.667+09:00  INFO 60964 --- [b02] [    Test worker] o.zerock.b02.service.BoardServiceTests   : [readOne] BoardDTO(bno=101, title=Sample title..., content=Sample content..., writer=user00, regDate=2024-03-13T00:21:59.022021, modDate=2024-03-13T00:21:59.022021)

 

 

 

๐Ÿ“ UPDATE

 

    // BoardService

    @Override
    public void modify(BoardDTO boardDTO) {
        Optional<Board> result = boardRepository.findById(boardDTO.getBno());

        Board board = result.orElseThrow();

        board.update(boardDTO.getTitle(), boardDTO.getContent());

        boardRepository.save(board);
    }

 

  @Test
    public void modifyTest(){

        BoardDTO boardDTO = BoardDTO.builder()
                .bno(101L)
                .title("modified Title...")
                .content("modified Content...")
                .build();

        boardService.modify(boardDTO);
    }

 

 

 

๐Ÿ”ช DELETE

 

 @Override
    public void remove(Long bno) {
        boardRepository.deleteById(bno);
    }

 

 

 

๐Ÿ“Œ์ฐธ๊ณ 

์ž๋ฐ” ์›น ๊ฐœ๋ฐœ ์›Œํฌ๋ถ - ๊ตฌ๋ฉ๊ฐ€๊ฒŒ ์ฝ”๋”ฉ๋‹จ