2023. 3. 14. 15:51ใ๐พBackEnd/๐ฑ Spring
Dozer
dozermapper.github.io
Dozer๋ ๋ฌด์์ธ๊ฐ?
Dozer๋ Java ๊ธฐ๋ฐ์ ๊ฐ์ฒด ๋งคํ ๋๊ตฌ ์ค ํ๋์ ๋๋ค. ๊ฐ์ฒด ๋งคํ์ ์๋ก ๋ค๋ฅธ ํด๋์ค ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ณต์ฌํ๊ฑฐ๋ ๋งคํํ๋ ํ๋ก์ธ์ค๋ฅผ ์๋ฏธํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฝ์ ๋ฐ์ดํฐ๋ฅผ Java ๊ฐ์ฒด์ ๋งคํํ๊ฑฐ๋, ์๋ก ๋ค๋ฅธ API์์ ๋ฐํํ ๋ฐ์ดํฐ๋ฅผ ํ๋์ ๊ฐ์ฒด๋ก ๋งคํํ๋ ๋ฑ์ ์์ ์ ์ํํ ์ ์์ต๋๋ค.
์ฒ์์ ์ผ๋จ ์์กด์ฑ ์ถ๊ฐํ์
implementation'com.github.dozermapper:dozer-core:6.4.0'
Dozer๋ฅผ ์ฌ์ฉํ๊ธฐ ์ด์ ์ ์ฝ๋๋ฅผ ํ๋ฒ ์ดํด๋ณด์
- ๊ธฐ์กด์ ์ฝ๋๋ Builder๋ฅผ ์ด์ฉํ์ฌ ๋งคํ์ ํ๊ฒ ๋์์ค๋ค. ์ด ๋ฐฉ์์ ์์ฑ์๋ฅผ ํตํ ๋ฐฉ์๋ณด๋ค ์ ํํ๊ฒ ๋งคํ์ ๋ํ ์ ๋ณด๋ฅผ ์ ์ ์๊ฒ๋๋ค. ํ์ง๋ง ๋ฌธ์ ์ ์ ๋๋ฌด ๋ง์ ๊ฐ์ฒด๊ฐ ์์ผ๋ฉด ์์ฑํ๋ ์ฝ๋๊ฐ ๋๋ฌด ๊ธธ์ด์ง๋ค.
ProductData(DTO)
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductData {
private Long id;
@NotBlank
private String name;
@NotBlank
private String maker;
@NotNull
private Integer price;
private String imageUrl;
}
Product
@Entity
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String maker;
private Integer price;
private String imageUrl;
public void change(Product product) {
this.name = product.getName();
this.maker = product.getMaker();
this.price = product.getPrice();
this.imageUrl = product.getImageUrl();
}
}
Service
public Product createProduct(ProductData productData) {
Product product = Product.builder()
.name(productData.getName())
.maker(productData.getMaker())
.price(productData.getPrice())
.build();
return productRepository.save(product);
}
- ์ง๊ธ์ 3๊ฐ๋ฅผ ๋งคํ์ ํ์ง๋ง ์ด๊ฒ ๋ง์ฝ์ ๊ฒฝ์ฐ๊ฐ ๋ง์์ง๊ฒ ๋๋ฉด Builder ํจํด์ ๊ฐ๋ ์ฑ์ด ์ข์ ์ฝ๋์ ํจ๊ณผ๊ฐ ๋จ์ด์ง๊ฒ ๋๋ค. ๊ทธ๋์ Dozer๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ๊ฐ๊ฒฐํ๊ฒ ํํ์ด ๊ฐ๋ฅํ๋ค.
1. APP์ @Bean์ ๋๋กํ๋ค.
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
@Bean
public Mapper dozermapper(){
return DozerBeanMapperBuilder.buildDefault();
}
}
2. Service์ Mapper๋ฅผ ์ถ๊ฐํ๋ค.
import com.github.dozermapper.core.Mapper;
@Service
@Transactional
@RequiredArgsConstructor
public class ProductService {
private final ProductRepository productRepository;
private final Mapper mapper;
public Product createProduct(ProductData productData) {
Product product = mapper.map(productData,Product.class);
return productRepository.save(product);
}
private Product findProduct(Long id) {
return productRepository.findById(id)
.orElseThrow(() -> new ProductNotFoundException(id));
}
}
- ์ด๋ mapper.map(`๋งคํ ๋ฐ์ดํฐ(DTO)` , ๋ณํ) ํ์์ผ๋ก ๋งคํ์ ํด์ฃผ๋ฉด ๋๋ค.
- ๊ทธ๋ฌ๋ฉด Product product = mapper.map(productData,Product.class);๋ productData์
- @Mapping๋ ๋ฐ์ดํฐ๋ฅผ Product ๋ฐ์ดํฐ ํ์ ์ผ๋ก ๋งคํ์ด ๋๋ค.
3. DTO์ ๋งคํ์ ๋ํด ๋ช ์ํ๋ค. ProductData(DTO)
@Setter
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductData {
private Long id;
@NotBlank
@Mapping("name")
private String name;
@NotBlank
@Mapping("maker")
private String maker;
@NotNull
@Mapping("price")
private Integer price;
@Mapping("imageUrl")
private String imageUrl;
}
4. ํ ์คํธ ์ฝ๋๋ฅผ ํตํ์ฌ ํ์ธํ์
@DataJpaTest
class ProductServiceTest {
private ProductService productService;
private ProductRepository productRepository = mock(ProductRepository.class);
@BeforeEach
void setUp() {
Mapper mapper = DozerBeanMapperBuilder.buildDefault();
productService = new ProductService(productRepository, mapper);
Product product = Product.builder()
.id(1L)
.name("๊น๋ฌด๊ฑด")
.maker("๋์ดํค")
.price(1000)
.build();
given(productRepository.save(any(Product.class))).will(invocation -> {
Product source = invocation.getArgument(0);
return Product.builder()
.id(2L)
.name(source.getName())
.maker(source.getMaker())
.price(source.getPrice())
.build();
});
}
@Test
void createProduct() {
ProductData productData = ProductData.builder()
.name("์ฅ๋์ด")
.maker("๋ฅ์ด์๋")
.price(5000)
.build();
Product product = productService.createProduct(productData);
verify(productRepository).save(any(Product.class));
assertThat(product.getId()).isEqualTo(2L);
assertThat(product.getName()).isEqualTo("๊น๋ฌด๊ฑด");
assertThat(product.getMaker()).isEqualTo("๋์ดํค");
}
}
ํ ์คํธ ์ฝ๋๊ฐ ์ฑ๊ณต์ ์ผ๋ก ๋์์ ํ๋ค.
'๐พBackEnd > ๐ฑ Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Mockito๋ ์๊ณ ํ ์คํธ ์ฝ๋ ์์ฑํ์ (0) | 2023.03.24 |
---|---|
์ํธํ Bcrypt์ ๋ํ ์ฌ์ธต ๋ถ์ (2) | 2023.03.24 |
[ RFC ] ๊ณต์ ๋ฌธ์๋ฅผ ํตํ์ฌ Delete์ Status๋ฅผ ์์๋ณด์ (0) | 2023.03.12 |
[ Jackson ] Jackson mock ํ ์คํธ ์ญ์ง๋ ฌํ ์ค๋ฅ (0) | 2023.03.11 |
Spring Boot Test H2 In Memory ์ค์ ํ๊ธฐ (0) | 2023.02.28 |