Bizim artık Controller ile Repository katmanları arasında artık soyut bir bağlantı kurarak controller'ın repository'ye direkt olarak erişmesini engelliyoruz ve işi artık iş katmanı(business) layer'a yolluyoruz.

Artık Service katmanında bizim Entity'lerimize benzeye DTO (Data Transfer Object)

classlarımız oluşturulur.

Controller class yapısındaki package isimlendirmesi

X.presentation.rest (@RestController)

X.presentation.mvc (@Controller)

Controller'dan service'ye DTO classı aktarılır.

Service Katmanı

X.business.service

X.business.service.impl (@Service)

Service'dan Repository'e Entity classı aktarılır.

Repository Katmanı

X.data.repository (@Repository)

Repository'den DB katmanına Entity classı aktarılır.

DB Layer

x.data.entity (@Entity)

Şimdi bir örneğe bakalım.


Product.java (Entity Classı)

package com.kerem.springapp.data.entity;
 
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
 
@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long productId;
    private String productName;
    private double salesPrice;
 
    public Product() {
    }
 
    public Product(long productId, String productName, double salesPrice) {
        this.productId = productId;
        this.productName = productName;
        this.salesPrice = salesPrice;
    }
 
    public long getProductId() {
        return productId;
    }
 
    public void setProductId(long productId) {
        this.productId = productId;
    }
 
    public String getProductName() {
        return productName;
    }
 
    public void setProductName(String productName) {
        this.productName = productName;
    }
 
    public double getSalesPrice() {
        return salesPrice;
    }
 
    public void setSalesPrice(double salesPrice) {
        this.salesPrice = salesPrice;
    }
 
}


ProductRepository.java


package com.kerem.springapp.data.repository;
 
import com.kerem.springapp.data.entity.Product;
import org.springframework.data.repository.CrudRepository;
 
public interface ProductRepository extends CrudRepository<Product, Long>{
    
}


DTO (Data Transfer Object) classımız


package com.kerem.springapp.business.dto;
 
public class ProductDto {
 
    private long productId;
    private String productName;
    private double salesPrice;
 
    public ProductDto() {
    }
 
    public ProductDto(long productId, String productName, double salesPrice) {
        this.productId = productId;
        this.productName = productName;
        this.salesPrice = salesPrice;
    }
 
    public long getProductId() {
        return productId;
    }
 
    public void setProductId(long productId) {
        this.productId = productId;
    }
 
    public String getProductName() {
        return productName;
    }
 
    public void setProductName(String productName) {
        this.productName = productName;
    }
 
    public double getSalesPrice() {
        return salesPrice;
    }
 
    public void setSalesPrice(double salesPrice) {
        this.salesPrice = salesPrice;
    }
 
}


ProductService.java ve ProductServiceImpl.java


public interface ProductService {
    
    public void save(ProductDto productDto);
    public ProductDto findById(Long productId);
    public List<ProductDto> findAll();
    public void deleteById(long productId);
}



package com.kerem.springapp.business.service.impl;
 
import com.kerem.springapp.business.dto.ProductDto;
import com.kerem.springapp.business.service.ProductService;
import com.kerem.springapp.data.entity.Product;
import com.kerem.springapp.data.repository.ProductRepository;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
@Service
public class ProductServiceImpl implements ProductService {
 
    @Autowired
    private ProductRepository productRepository;
 
    @Override
    public void save(ProductDto productDto) {
        Product product = fromDto(productDto);
        productRepository.save(product);
    }
 
    @Override
    public ProductDto findById(Long productId) {
        ProductDto productDto = null;
        if (productId == null || productId == 0){
            productDto = new ProductDto(0, "", 0.0);
            return productDto;
        }
        Optional<Product> productOptional = productRepository.findById(productId);
        if (productOptional.isPresent()) {
            Product product = productOptional.get();
            productDto = fromEntity(product);
        } else {
            productDto = new ProductDto(0, "", 0.0);
        }
        return productDto;
    }
 
    @Override
    public List<ProductDto> findAll() {
        List<ProductDto> productDtos = new ArrayList<>();
        Iterable<Product> products = productRepository.findAll();
        for(Product product : products){
            productDtos.add(fromEntity(product));
        }
        return productDtos;
    }
    
    @Override
    public void deleteById(long productId) {
        productRepository.deleteById(productId);
    }
    
    public ProductDto fromEntity(Product product){
        return new ProductDto(product.getProductId(),product.getProductName(),product.getSalesPrice());
    }
    public Product fromDto(ProductDto productDto){
        return new Product(productDto.getProductId(),productDto.getProductName(),productDto.getSalesPrice());
    }
}


MVC tarafı için controller classı (@Controller)

ProductController.java


package com.kerem.springapp.presentation.mvc;
 
import com.kerem.springapp.business.dto.ProductDto;
import com.kerem.springapp.business.service.ProductService;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
 
@Controller
public class ProductController {
 
 
    @Autowired
    private ProductService productService;
 
    @GetMapping(path = {"/product/edit", "/product/edit/{id}"})
    public String editProduct(Model model, @PathVariable(value = "id", required = false) Long id) {
        ProductDto productDto = productService.findById(id);
        model.addAttribute("product", productDto);
        return "/inventory/ProductEdit";
    }
 
    @PostMapping(path ={"/product/edit", "/product/edit/{id}"})
    public String editProduct(@Valid @ModelAttribute("product") ProductDto productDto, BindingResult bindingResult, Model model,
            @PathVariable(value = "id", required = false) Long id) {
        if (bindingResult.hasErrors()) {
            model.addAttribute("errors", bindingResult);
            return "/inventory/ProductEdit";
        }
        model.addAttribute("message", "başarılı bir şekilde saved");
        productService.save(productDto);
        return "/inventory/ProductSuccess";
    }
 
    @GetMapping("/product/list")
    public String getProducts(Model model) {
        model.addAttribute("products", productService.findAll());
        return "/inventory/ProductList";
    }
 
    @GetMapping("/product/delete/{id}")
    public String deleteProduct(@PathVariable("id") Long id, RedirectAttributes redirectAttributes) {
        String message = "";
        if (id == null || id == 0) {
            message = "Lütfen geçerli bir id giriniz";
            redirectAttributes.addFlashAttribute("message", message);
            return "redirect:/product/list";
        }
        message = "Başarılı bir şekilde silindi";
        redirectAttributes.addFlashAttribute("message", message);
        productService.deleteById(id);
        return "redirect:/product/list";
    }
 
}


REST tarafı için controller classı(@RestController)

ProductResource.java


package com.kerem.springapp.presentation.rest;
 
import com.kerem.springapp.business.dto.ProductDto;
import com.kerem.springapp.business.service.ProductService;
import java.util.List;
import static javax.print.attribute.standard.MediaSizeName.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class ProductResource {
    
    @Autowired
    private ProductService productService;
    
    @GetMapping("/api/product/{id}")
    public ProductDto getProductDto(@PathVariable("id") Long id){
        return productService.findById(id);
    }
    
    @GetMapping("/api/products")
    public List<ProductDto> getProducts(){
        return productService.findAll();
    }
    
    @PostMapping("/api/product")
    public void saveProduct(@RequestBody ProductDto productDto){
        productService.save(productDto);
    }
    
    @PutMapping("/api/product")
    public void putProduct(@RequestBody ProductDto productDto){
        productService.save(productDto);
    }
    
    @DeleteMapping("/api/product/{id}")
    public void deleteProduct(@PathVariable("id") Long productDtoId){
        productService.deleteById(productDtoId);
    }
}