JavaRush /Java блогы /Random-KK /Көктем қорқынышты емес, DTO қабаты
Павел
Деңгей

Көктем қорқынышты емес, DTO қабаты

Топта жарияланған
МАҚАЛА ЦИКЛІНІҢ МАЗМҰНЫ Көктем туралы әңгімемізді жалғастырамыз. Бүгін біз DTO үлгісін талдаймыз, түсіну үшін мына жерден оқи аласыз . DTO туралы ең қиын нәрсе - оның не үшін қажет екенін түсіну. Көкөністер туралы алыпсатарлықтарды бастайық, сонымен бірге codeты жазыңыз, мүмкін, жолда бір нәрсе анық болады. Spring-boot жобасын жасаңыз, h2 және Lombok қосыңыз . Пакеттерді жасаңыз: нысандар, репозиторийлер, қызметтер, утorталар. Нысандарда Өнім нысанын жасаңыз:
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;//закупочная цена

}
ProducRepository, ProducService сыныптарын және ItiiateUtil сыныбын іске асырыңыз ( алдыңғы мақалаға ұқсас ). Біз картопты көтерме бағамен келісін 20 рубльден, сәбізді келісін 14 рубльден алдық делік. Сатып алынған өнімді қоймаға қоямыз. Дерекқорға келесі жазбаларды қосайық: [Id =1, атауы= «Картоп», сатып алуБағасы = 20] [Идентификатор =2, аты= «Сәбіз», сатып алуБағасы = 14] Лайықты алыпсатарлар ретінде біз өз тауарларымызды тиімді сатуымыз керек, ол үшін оны әдемілеп орап алайық және бағасын көтереміз. Яғни, бізде лас және тартымсыз көкөністер үйіндіге жиналды, бірақ люкс сегментінен таза премиум вегетариандық өнімдер болады. Келісіңіз, бұл енді біз жаппай сатып алған өнім (нысан) болмайды. Жаңа өнім үшін dto бумасын және оның ішінде ProductDto класын жасаңыз
package ru.java.rush.dto;

import lombok.Data;

@Data
public class ProductDto {
    Integer id;
    String name;
    Integer purchasePrice;
    String  packaging;//упаковка
    Integer salePrice;//цена реализации
}
ProductDto-да ProductEntity қолданbyteын екі айнымалы бар: “орау” және “сату бағасы”. dto нысанында нысанмен бірдей айнымалылар болуы мүмкін немесе олардың көп немесе аз болуы мүмкін. Бір нысанды екіншісіне түрлендіру картаға түсіру мәселесі екенін есте ұстаймыз. Utils бумасында біз 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;
    }
}
Біз жай ғана бір нысанның өрістерін басқа нысанның ұқсас өрістерімен толтырамыз. ProductService сыныбында біз бір өнімді немесе өнімдер тізімін іздеу әдістерін енгіземіз, бірақ оған дейін жоғарыда жазылған әдісті пайдаланып нысанды dto түріне түрлендіреміз.
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
    );
}
Енді осы көкөністерді дисплейге қойсақ не болады? Қарайық. Ол үшін ItiiateUtil ішінде келесі codeты жазып, оны іске қосыңыз.
System.out.println("\nВитрина магазина");
for (ProductDto dto : productService.findAll()) {
    System.out.println(dto);
}
Нәтиже: Дүкен дисплейі ProductDto(id=1, name=картоп, сатып алуPrice=20, packaging=null, salePrice=null) ProductDto(id=2, name=Sәбіз, purchasePrice=14, packaging=null, salePrice=null) Жақсы, жоқ! Мұндай көкөністерді ешкім сатып алмайды: олар лас, қапталмаған, сату бағасы белгісіз. Бизнес логикасының уақыты келді. Біз оны ProductService сыныбына енгіземіз. Алдымен осы сыныпқа бірнеше айнымалыларды қосайық:
private final Integer margin = 5;//это наша накрутка на цену
private final String packaging = "Упаковано в лучшем виде";//так будет выглядеть упаковка
Әрбір әрекет үшін: орау және баға белгілеу, біз бір сыныпта бөлек әдіс жасаймыз:
// упаковываем товар
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)
    );
}
Біз ItiiateUtil-ге ораламыз және дисплейдегі дисплейді келесі codeпен ауыстырамыз
List<ProductDto> productDtos = productService.findAll();

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

System.out.println("\nВитрина магазина");
for (ProductDto dto : productDtos)) {
    System.out.println(dto);
}
Біз мыналарды орындаймыз: Дүкен дисплейі ӨнімDto(id=1, атауы=Картоп, сатып алуБағасы=20, қаптама=Ең жақсы түрде оралған, сатылымБағасы=100) ProductDto(id=2, атауы=Сәбіз, сатып алуБағасы=14, Қаптама=Қаптама) ең жақсы жолмен, salePrice=70) Өнім әдемі оралған, бағасы бар, бірақ сіз оны жаппай сатып алған бағаны және басқа идентификаторды терезе дисплейінде бір жерден көрдіңіз бе. Жоғарыда жазылған codeты файлмен өзгертеміз:
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()
    ));
}
сынып InitiateUtils сайып келгенде келесідей болуы керек:
@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()
            ));
        }
    }
}
Іске қосайық: Дүкен терезесі Сатып алу: Картоп, бағасы: 100 Сатып алу: Сәбіз, бағасы: 70 Тағы бір нәрсе! Енді біз көптеген қосымша codeтарды қоспағанда, жақсы нәрселер әкелді деп ойлаймыз: 1. Біз дерекқордағы нысандарды өзгертпестен бизнес логикасын орындай аламыз (айталық, бізде орау және сату бағасы туралы өрістердің болуы қажет емес. осы кесте). Картоп баға белгісімен қаптамасыз да сақтауда жақсы сақталады, олар тіпті артық. 2. Бұл жолда List<ProductDto> productDtos = productService.findAll() біз бизнес логикасы аясында жұмыс істеуге ыңғайлы нысандардың кэшін жасадық. Бұл тауарлардың бір бөлігін дүкеннің артқы бөлмесіне қоятын болсақ. 3. Бұл бізге екі іскерлік әрекетті орындауға мүмкіндік берді: орау және белгілеу, бірақ біз дерекқорға тек бір рет сұраныс жасадық (дерекқорға сұраулар өнімділік тұрғысынан айтарлықтай қиын). Өнімді қаптамаға салып, оған баға белгісін қойып, дисплейге қоюға болады - оны сақтау бөлмесіне дейін артынан жүгірмей, бірте-бірте қызметтік бөлмеден алып кетуге болады. «Неге сонша қиын?» Деген сұраққа адамдар да жауап табуға тырысады, оқыңыз . Келесі мақала
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION