Skip to content

Latest commit

ย 

History

History
69 lines (67 loc) ยท 3.53 KB

File metadata and controls

69 lines (67 loc) ยท 3.53 KB

MapStruct

  • Entity์™€ Dto ๊ฐ์ฒด ๊ฐ„์˜ ๋งคํ•‘์„ ์ง€์›ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    • Entity์™€ Dto ๊ฐ์ฒด ๊ฐ„์˜ ๋งคํ•‘์„ ์ง€์›ํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” ModelMapper์™€ MapStruct๊ฐ€ ์žˆ๋‹ค.
    • MapStruct๋Š” ์ปดํŒŒ์ผ ์‹œ ๋ฏธ๋ฆฌ ์ƒ์„ฑ๋œ ๊ตฌํ˜„์ฒด๋กœ ๋งคํ•‘ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋Ÿฐํƒ€์ž„ ๋น„์šฉ์ด ์ ๊ฒŒ ๋“ค๋ฉฐ ๋งคํ•‘ ์„ฑ๋Šฅ์ด ๋›ฐ์–ด๋‚˜๋‹ค.
    • MapStruct๋Š” ์ธํ„ฐํŽ˜์ด์Šค ๊ธฐ๋ฐ˜์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
      • ๊ฐ ๋งคํ•‘์„ ์œ„ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ •์˜ํ•˜๋ฉด ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅด ๊ตฌํ˜„ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

MapStruct์˜ ์ฃผ์š” ๊ธฐ๋Šฅ

  1. ๋‹ค์–‘ํ•œ ๋งคํ•‘ ์ „๋žต ๋ฐ ๊ธฐ๋Šฅ ์ œ๊ณต
  2. ์–ด๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜ ์„ค์ •
  3. ๋‹ค๋ฅธ ๋งคํ•‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ†ตํ•ฉ ๊ฐ€๋Šฅ
  4. Gradle ๋ฐ Maven ํ”Œ๋Ÿฌ๊ทธ์ธ ์ œ๊ณต
  5. Lombok ๊ณผ ํ†ตํ•ฉ ๊ฐ€๋Šฅ

MapStruct ์‚ฌ์šฉํ•˜๊ธฐ

๋งคํ•‘ ์ธํ„ฐํŽ˜์ด์Šค ์ž‘์„ฑ

  • ์ธํ„ฐํŽ˜์ด์Šค๋Š” @Mapper ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋งคํ•‘ ๋Œ€์ƒ ํด๋ž˜์Šค๋ฅผ ๋ช…์‹œํ•œ๋‹ค.
  • @Mapping ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๋งคํ•‘ ์‹œ ํŠน์ • ํ•„๋“œ๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ž‘์„ฑ ์˜ˆ์ œ

  • Source ํด๋ž˜์Šค๋ฅผ Target ํด๋ž˜์Šค๋กœ ๋งคํ•‘ํ•˜๋ ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑํ•œ๋‹ค.
  • ์ธํ„ฐํŽ˜์ด์Šค์™€ ๋ฉ”์„œ๋“œ ๋ช…์€ ์›ํ•˜๋Š” ๋Œ€๋กœ ์ง€์ • ๊ฐ€๋Šฅ
@Mapper
public interface SourceTargetMapper {
    SourceTargetMapper INSTANCE = Mappers.getMapper(SourceTargetMapper.class);
    
    @Mapping(source = "id", target = "targetNo")
    Target sourceToTarget(Source source);
}
  • ์˜ˆ์ œ์—์„œ๋Š” INSTANCE๋ฅผ ์„ ์–ธํ•˜์—ฌ ํด๋ผ์ด์–ธํŠธ์— ๋งคํผ ๊ตฌํ˜„์ฒด์— ๋Œ€ํ•œ ์—‘์„ธ์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
    • INSTANCE๋ฅผ ์„ ์–ธํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ์˜์กด์„ฑ ์ฃผ์ž…์œผ๋กœ SourceTargetMapper ๊ตฌํ˜„์ฒด๋ฅผ ์ฃผ์ž…ํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
    • @Autowired
      private SourceTargetMapper mapper;
  • @Mapping ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ Source ๊ฐ์ฒด์˜ id ๋ผ๋Š” ํ•„๋“œ๊ฐ’์„ Target ๊ฐ์ฒด์˜ targetNo ํ•„๋“œ๊ฐ’์œผ๋กœ ๋งคํ•‘ํ•œ๋‹ค.
    • source์™€ target ๋Œ€์ƒ์ด ๋‹ค๋ฅธ ํƒ€์ž…์ธ ๊ฒฝ์šฐ ํ˜• ๋ณ€ํ™˜์„ ์‹คํ–‰ํ•˜์—ฌ ๋งคํ•‘ํ•œ๋‹ค.

๋งคํ•‘ ๊ตฌํ˜„์ฒด ์ƒ์„ฑ

  • MapStruct๋Š” ์ปดํŒŒ์ผ ํƒ€์ž„์— ๋งคํ•‘ ๊ตฌํ˜„์ฒด๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค.
  • @Mapper(componentModel = "spring") ์™€ ๊ฐ™์ด componentModel="spring" ์†์„ฑ์„ ์ง€์ •ํ•ด์ฃผ๊ฒŒ ๋˜๋ฉด ์ž๋™ ์ƒ์„ฑ๋˜๋Š” ๊ตฌํ˜„์ฒด ํด๋ž˜์Šค๋ฅผ ์Šคํ”„๋ง ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค.
    • componentModel ์†์„ฑ์„ ์ƒ๋žตํ•˜๊ฒŒ ๋˜์–ด๋„ Spring ์ปดํฌ๋„ŒํŠธ ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธด ํ•œ๋‹ค.

๋งคํ•‘ ์‹คํ–‰

Target target = SourceTargetMapper.INSTANCE.sourceToTarget(source);

์ž‘์„ฑ ์˜ˆ์ œ2

@Mapper
public interface OrderMapper {
    @Mapping(source = "owner.name", target = "ownerName")
    @Mapping(source = "orderItems", target = "orderItems")
    @Mapping(source = "buyDate", target = "buyDate")   
    @Mapping(target = "totalPrice", qualifiedByName = "calculateTotalPrice")
    OrderDto mapToDto(Order order);
	
    @Named("calculateTotalPrice")
    default double calculateTotalPrice(Order order) {
        double total = 0.0;
        for (OrderItem item : order.getOrderItems()) {
            double itemPrice = item.getPrice();
            int quantity = item.getQuantity();
            total += itemPrice * quantity;
        }
        return total;
    }
}
  • calculateTotalPrice ๋ผ๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•œ๋‹ค.
  • @Mapping ์–ด๋…ธํ…Œ์ด์…˜์˜ qualifiedByName ์†์„ฑ์—์„œ @Named ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์ด๋ฆ„์ด ๋ถ€์—ฌ๋œ ์‚ฌ์šฉ์ž ์ •์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐธ์กฐํ•œ๋‹ค.
  • ์ฐธ์กฐํ•œ calculateTotalPrice ๋ฉ”์„œ๋“œ์—์„œ ๊ณ„์‚ฐํ•œ ๊ฐ’์„ OrderDto ๊ฐ์ฒด์˜ totalPrice ํ•„๋“œ์— ๋งคํ•‘ํ•œ๋‹ค.