# Re:0 - Starting Life in Backend - Day3

seal

你才不是一個沒人要的女同學
誰會不厭其煩的安慰那無知的少年
我走進了你的世界別怪我太耀眼
我願意用我十年奮鬥換你一個小時的笑臉
你當時特別的可愛 但能不能靠近點
你不說真心話你讓我怎麼為你大冒險


Level 5: Business Logic and Service Layer

Target :Introduce the service layer to decouple business logic from the controller

Solution:

Service

package com.example.demo2.service;

import com.example.demo2.model.Car;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;

import java.util.List;
import java.util.Optional;

public interface CarService {

    Optional<Car> findById(long id);

    //name
    List<Car> findByName(String name);
    List<Car> findByNameLikeIgnoreCase(String name);

    //age
    List<Car> findTop3ByAgeGreaterThan(int age);
    List<Car> findByAgeOrderByNameAsc(int age);

    //price
    List<Car> findByPriceBetweenOrderByPriceAsc(double price1, double price2);

    public List<Car> getAll();
    public Car add(Car car);
    public void deleteById(long id);
    public void deleteByName(String name);
    public Optional<Car> update(long id, Car car);

}

Although I did not write an abstract class here, this is actually an abstract writing method.

This service interface declares a set of operations supported by the service layer

Implements

package com.example.demo2.service;

import com.example.demo2.model.Car;
import com.example.demo2.repository.CarRepository;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class CarServiceImpl implements CarService {

    private final  CarRepository carRepository;

    public CarServiceImpl(CarRepository carRepository) {
        this.carRepository = carRepository;
    }

    @Override
    public Optional<Car> findById(long id){
        return carRepository.findById(id);
    }

    //name
    @Override
    public List<Car> findByName(String name){
        return carRepository.findByName(name);
    }
    @Override
    public List<Car> findByNameLikeIgnoreCase(String name){
        return carRepository.findByNameLikeIgnoreCase(name);
    }

    //age
    @Override
    public List<Car> findTop3ByAgeGreaterThan(int age){
        return carRepository.findTop3ByAgeGreaterThan(age);
    }
    @Override
    public List<Car> findByAgeOrderByNameAsc(int age){
        return carRepository.findByAgeOrderByNameAsc(age);
    }

    //price
    @Override
    public List<Car> findByPriceBetweenOrderByPriceAsc(double price1, double price2){
        return carRepository.findByPriceBetweenOrderByPriceAsc(price1, price2);
    }
    @Override
    public List<Car> getAll(){
        return carRepository.findAll();
    }
    @Override
    public Car add(Car car){
        return carRepository.save(car);
    }

    @Override
    public void deleteById(long id){
        carRepository.deleteById(id);
    }

    @Override
    public void deleteByName(String name){

        carRepository.deleteByName(name);
    }

    @Override
    public Optional<Car> update(long id, Car car){
        Optional<Car> existingCarOptional = carRepository.findById(id);
        if(existingCarOptional.isPresent()){
            Car existingCar = existingCarOptional.get();
            existingCar.setName(car.getName());
            existingCar.setAge(car.getAge());
            existingCar.setPrice(car.getPrice());
            return Optional.of(carRepository.save(existingCar));
        }
        else {
            return Optional.empty();
        }
    }

}

This Implement code mainly implements the abstract method in the service layer

Here use a new type —— Optional ; The Optional type is mainly used to handle values that may or may not exist, thereby avoiding null pointer exceptions

Level 5-s

public Optional<Car> update(long id, Car car){
        Optional<Car> existingCarOptional = carRepository.findById(id);
        if(existingCarOptional.isPresent()){
            Car existingCar = existingCarOptional.get();
            existingCar.setName(car.getName());
            existingCar.setAge(car.getAge());
            existingCar.setPrice(car.getPrice());
            return Optional.of(carRepository.save(existingCar));
        }
        else {
            return Optional.empty();
        }
    }

The above code uses some chain operations.

These chain operations are provided by Optional type: map, filter, flatMap. etc.

map

Lambda

list.stream().map(element -> element.transform());
//change String to uppercase
list.stream().map(s -> s.toUpperCase());
//change Number to double
list.stream().map(n -> n*2)

Method Reference

list.stream().map(String::toUpperCase); // Equivalent to s -> s.toUpperCase()
list.stream().map(Integer::valueOf); // Equivalent to s -> Integer.valueOf(s)