JavaRush /Blog Java /Random-VI /Mùa xuân không đáng sợ, một lớp DTO
Павел
Mức độ

Mùa xuân không đáng sợ, một lớp DTO

Xuất bản trong nhóm
NỘI DUNG BÀI VIẾT Chúng ta tiếp tục nói về Mùa Xuân. Hôm nay chúng ta sẽ phân tích mẫu DTO, để hiểu bạn có thể đọc tại đây . Điều khó nhất về DTO là hiểu tại sao nó lại cần thiết. Hãy bắt đầu suy đoán về các loại rau, đồng thời viết một số mã, có thể điều gì đó sẽ trở nên rõ ràng hơn trong quá trình thực hiện. Tạo dự án khởi động mùa xuân , kết nối h2 Lombok . Tạo các gói: thực thể, kho lưu trữ, dịch vụ, tiện ích. Trong thực thể, tạo thực thể Sản phẩm:
package ru.java.rush.entities;

import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Accessors(chain = true)
@Entity
@Data
public class ProductEntity {

    @Id
    @Column
    @GenericGenerator(name = "generator", strategy = "increment")
    @GeneratedValue(generator = "generator")
    Integer id;

    @Column
    String name;

    @Column
    Integer purchasePrice;//закупочная цена

}
Triển khai các lớp ProducRepository, ProducService và lớp ItiiateUtil ( tương tự bài viết trước ). Giả sử chúng ta mua khoai tây với giá bán buôn là 20 rúp/kg và cà rốt với giá 14 rúp/kg. Chúng tôi sẽ cất các sản phẩm đã mua vào kho. Hãy thêm các bản ghi sau vào cơ sở dữ liệu: [Id =1, name= “Potatoes”, buyPrice = 20] [Id =2, name= “Carrots”, buyPrice = 14] Là những nhà đầu cơ tử tế, chúng ta phải bán hàng hóa của mình để kiếm lời, vì điều này, hãy đóng gói nó thật đẹp và chúng tôi sẽ tăng giá. Tức là chúng ta đã có những loại rau bẩn và kém hấp dẫn chất thành một đống, nhưng sẽ có những sản phẩm thuần chay sạch cao cấp thuộc phân khúc hạng sang. Đồng ý rằng đây sẽ không còn là sản phẩm (đối tượng) mà chúng tôi đã mua với số lượng lớn nữa. Đối với một sản phẩm mới, hãy tạo một gói dto và trong đó có lớp ProductDto
package ru.java.rush.dto;

import lombok.Data;

@Data
public class ProductDto {
    Integer id;
    String name;
    Integer purchasePrice;
    String  packaging;//упаковка
    Integer salePrice;//цена реализации
}
ProductDto có hai biến mà ProductEntity không có: “đóng gói” và “giá bán”. Đối tượng dto có thể chứa chính xác các biến giống như thực thể hoặc có thể có nhiều hoặc ít biến hơn. Chúng ta nhớ rằng việc chuyển đổi đối tượng này sang đối tượng khác là vấn đề ánh xạ. Trong gói utils chúng ta sẽ tạo lớp MappingUtils
package ru.java.rush.utils;

import org.springframework.stereotype.Service;
import ru.java.rush.dto.ProductDto;
import ru.java.rush.entities.ProductEntity;

@Service
public class MappingUtils {
//из entity в dto
    public ProductDto mapToProductDto(ProductEntity entity){
        ProductDto dto = new ProductDto();
        dto.setId(entity.getId());
        dto.setName(entity.getName());
        dto.setPurchasePrice(entity.getPurchasePrice());
        return dto;
    }
//из dto в entity
    public ProductEntity mapToProductEntity(ProductDto dto){
        ProductEntity entity = new ProductEntity();
        entity.setId(dto.getId());
        entity.setName(dto.getName());
        entity.setPurchasePrice(dto.getPurchasePrice());
        return entity;
    }
}
Chúng ta chỉ cần điền vào các trường từ một đối tượng bằng các trường tương tự từ một đối tượng khác. Trong lớp ProductService, chúng tôi triển khai các phương thức tìm kiếm một sản phẩm hoặc danh sách sản phẩm, nhưng trước đó, chúng tôi chuyển đổi thực thể thành dto bằng phương thức được viết ở trên.
private final ProductRepository productRepository;
private final MappingUtils mappingUtils;


//для листа продуктов мы использовали стрим
public List<ProductDto> findAll() {
    return productRepository.findAll().stream() //создали из листа стирим
            .map(mappingUtils::mapToProductDto) //оператором из streamAPI map, использовали для каждого element метод mapToProductDto из класса MappingUtils
.collect(Collectors.toList()); //превратor стрим обратно в коллекцию, а точнее в лист
}

//для одиночного продукта обошлись проще
public ProductDto findById(Integer id) {
    return mappingUtils.mapToProductDto( //в метод mapToProductDto
            productRepository.findById(id) //поместor результат поиска по id
                    .orElse(new ProductEntity()) //если ни чего не нашли, то вернем пустой entity
    );
}
Điều gì sẽ xảy ra nếu bây giờ chúng ta trưng bày những loại rau này? Hãy xem nào. Để thực hiện việc này, hãy viết đoạn mã sau vào ItiiateUtil và chạy nó.
System.out.println("\nВитрина магазина");
for (ProductDto dto : productService.findAll()) {
    System.out.println(dto);
}
Kết quả đầu ra là: Store display ProductDto(id=1, name=Potatoes, buyPrice=20, Packaging=null, salePrice=null) ProductDto(id=2, name=Carrots, buyPrice=14, Packaging=null, salePrice=null) Tôi cũng không! Sẽ không có ai mua những loại rau như vậy: chúng bẩn, không được đóng gói và không biết giá bán. Đã đến lúc logic kinh doanh. Chúng tôi triển khai nó trong lớp ProductService. Trước tiên hãy thêm một vài biến vào lớp này:
private final Integer margin = 5;//это наша накрутка на цену
private final String packaging = "Упаковано в лучшем виде";//так будет выглядеть упаковка
Đối với mỗi hành động: đóng gói và tăng giá, chúng ta sẽ tạo một phương thức riêng trong cùng một lớp:
// упаковываем товар
public void pack(List<ProductDto> list) {
    list.forEach(productDto ->
            productDto.setPackaging(packaging)
    );
}

// делаем деньги
public void makeMoney(List<ProductDto> list) {
    list.forEach(productDto ->
            productDto.setSalePrice(productDto.getPurchasePrice() * margin)
    );
}
Chúng ta quay lại ItiiateUtil và thay thế màn hình hiển thị bằng đoạn mã sau
List<ProductDto> productDtos = productService.findAll();

productService.pack(productDtos);
productService.makeMoney(productDtos);

System.out.println("\nВитрина магазина");
for (ProductDto dto : productDtos)) {
    System.out.println(dto);
}
Chúng tôi thực hiện: Hiển thị cửa hàng ProductDto(id=1, name=Potatoes, buyPrice=20, bao bì=Đóng gói theo cách tốt nhất có thể, salePrice=100) ProductDto(id=2, name=Carrots, buyPrice=14, bao bì=Đã đóng gói theo cách tốt nhất có thể, salePrice=70) Sản phẩm được đóng gói đẹp mắt, có giá, nhưng bạn đã thấy đâu đó trên cửa sổ hiển thị giá mà bạn mua số lượng lớn và một số id khác. Chúng tôi sửa đổi mã được viết ở trên bằng một tệp:
List<ProductDto> productDtos = productService.findAll();

productService.pack(productDtos);
productService.makeMoney(productDtos);

System.out.println("\nВитрина магазина");
for (ProductDto dto : productDtos) {
    System.out.println(String.format(
            "Купите: %s , по цене:  %d", dto.getName(), dto.getSalePrice()
    ));
}
lớp InitiateUtils cuối cùng sẽ trông như thế này:
@Service
@RequiredArgsConstructor
public class InitiateUtils implements CommandLineRunner {

    private final ProductService productService;

    @Override
    public void run(String... args) throws Exception {

        List<ProductEntity> products = new ArrayList<>(
                Arrays.asList(
                        new ProductEntity()
                                .setName("Картофель")
                                .setPurchasePrice(20),
                        new ProductEntity()
                                .setName("Морковь")
                                .setPurchasePrice(14)
                ));

        productService.saveAll(products);

        List<ProductDto> productDtos = productService.findAll();

        productService.pack(productDtos);
        productService.makeMoney(productDtos);

        System.out.println("\nВитрина магазина");
        for (ProductDto dto : productDtos) {
            System.out.println(String.format(
                    "Купите: %s , по цене:  %d", dto.getName(), dto.getSalePrice()
            ));
        }
    }
}
Hãy ra mắt: Cửa sổ cửa hàng Mua: Khoai tây, giá: 100 Mua: Cà rốt, giá: 70 Một điều khác! Bây giờ chúng tôi nghĩ rằng dto mang lại những điều tốt đẹp, ngoại trừ một loạt mã bổ sung: 1. Chúng tôi có thể thực hiện logic nghiệp vụ mà không cần thay đổi các đối tượng trong cơ sở dữ liệu (giả sử, chúng tôi không cần có các trường về bao bì và giá bán trong cái bàn này). Khoai tây sẽ tồn tại tốt trong kho ngay cả khi không có bao bì kèm theo giá, thậm chí chúng còn thừa ở đó. 2. Trong dòng này List<ProductDto> ProductDtos = ProductService.findAll() , chúng tôi đã tạo một bộ nhớ đệm gồm các đối tượng thuận tiện để làm việc trong logic nghiệp vụ. Đây là trường hợp chúng ta đặt một số hàng hóa ở phòng sau của cửa hàng. 3. Điều này cho phép chúng tôi thực hiện hai hành động kinh doanh: đóng gói và đánh dấu, nhưng chúng tôi chỉ đưa ra yêu cầu tới cơ sở dữ liệu một lần (các truy vấn đến cơ sở dữ liệu khá khó khăn về mặt hiệu suất). Bạn có thể đóng gói sản phẩm, dán thẻ giá và trưng bày - dần dần nhặt nó từ phòng tiện ích, thay vì mỗi lần chạy theo nó đến phòng bảo quản. Đối với câu hỏi: “Sao khó thế?”, mọi người cũng cố gắng tìm câu trả lời, đọc . Bài viết tiếp theo
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION