[Spring] memory db 로직

yoon·2024년 1월 12일

spring-boot

목록 보기
10/41
post-thumbnail

✅ memory db 사용하기

memory db는 프로젝트가 끝나면 저장된 데이터가 모두 사라진다.
db 프로그램을 사용하기 전 memory db를 이용해보자

✔ 프로젝트 구조

프로젝트는 다음의 과정을 통해 실행된다.

controller ↔ service ↔ DB

1. controller : api 구성
2. service : 비즈니스 로직처리
→ db에 접근하기 위해서는 무조건 service에서 처리
3. DB : repository

✔ 코드 구성

◾ entity

각 패키지의 model이 상속받을 클래스를 담고있다.

Primary key가 들어있는 인터페이스를 생성하고, 이 인터페이스를 받아 전체적인 모델링을 한다.

//PrimaryKey.class
public interface PrimaryKey {

    void setId(Long id);
    Long getId();
}

//Entity.class
import lombok.Getter;
import lombok.Setter;

public abstract class Entity implements PrimaryKey {
    @Getter
    @Setter
    private Long id;
}

◾ db

  1. 각 패키지의 db가 상속받을 클래스를 담고있다.
    필요한 기능을 담은 인터페이스를 생성한다.
//DataRepository.class
import java.util.List;
import java.util.Optional;

public interface DataRepository<T,ID> extends Repository<T,ID>  {
    //create, update
    T save(T data); // 없으면 만들고, 있으면 업데이트
    
    //read
    Optional<T> findById(ID id); //id로 데이터 찾기 > 데이터가 없다면 Optional 타입 반환
    List<T>  findAll();
    
    //delete
    void delete(ID id);
}
  1. 인터페이스를 받아 클래스를 생성한다.
abstract public class SimpleDataRepository<T extends Entity,ID extends Long> implements DataRepository<T,ID> {
    private List<T> dataList = new ArrayList<T>();
    private static long index = 0;

    private Comparator<T> sort = new Comparator<T>() {
        @Override
        public int compare(T o1, T o2) {
            return Long.compare(o1.getId(), o2.getId());
        }
    };

    //create
    @Override
    public T save(T data) {
        if(Objects.isNull(data)){
            throw new RuntimeException("Data is null!");
        }
        var prevData = dataList.stream()
                .filter(it -> {
                    return it.getId().equals(data.getId());
                }).findFirst();

        if(prevData.isPresent()){
            //Optional<UserEntity> 가 들어있어서 삭제되지 않음
//            dataList.remove(prevData);
            dataList.remove(prevData.get());
            dataList.add(data);

        }else{
            index++;
            data.setId(index);
            dataList.add(data);
        }

        return data;
    }

    //read
    @Override
    public Optional<T> findById(ID id) {

        return dataList.stream()
                .filter(it->{
                    return id.equals(it.getId());
                }).findFirst();
    }

    @Override
    public List<T> findAll() {
        return dataList.stream()
                .sorted(sort)
                .collect(Collectors.toList());
    }

    //delete
    @Override
    public void delete(ID id) {
        var deleteEntity = dataList.stream()
                .filter(it->{
                    return id.equals(it.getId());
                }).findFirst();
        if(deleteEntity.isPresent()){
            dataList.remove(deleteEntity.get());
        }
    }
}
  1. user.db 패키지에는 따로 UserRepository 클래스를 생성한다.
    위에서 생성한 DataRepository를 상속받고, User에서만 사용하는 기능을 작성한다.
import com.example.memorydb.db.SimpleDataRepository;
import com.example.memorydb.user.model.UserEntity;
import org.springframework.stereotype.Service;

import java.util.List;
@Service
public class UserRepository  extends SimpleDataRepository<UserEntity, Long> {
    public List<UserEntity> findByScore(Integer score){
        List<UserEntity> results = this.findAll().stream()
                .filter(it->{
                    return it.getScore()>=score;
                }).toList();
        return results;
    }
}

◾ controller

UserApi를 작성한다.

import com.example.memorydb.user.model.UserEntity;
import com.example.memorydb.user.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

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

@RestController
@RequestMapping("/api/user")
@RequiredArgsConstructor
public class UserApiController {

    private final UserService userService;
    @PutMapping("")
    public UserEntity create(
            @RequestBody UserEntity user
    ){
        return userService.save(user);
    }

    @GetMapping("/all")
    public List<UserEntity> findAll(){
        return userService.findAll();
    }

    @GetMapping("/{userId}")
    public Optional<UserEntity> findById(
            @PathVariable Long userId
    ){
        return userService.findById(userId);
    }


    @DeleteMapping("/{userId}")
    public void delete(
            @PathVariable Long userId
    ){
        userService.delete(userId);
    }

    @GetMapping("/score/{score}")
    public List<UserEntity> findByScore(
            @PathVariable Integer score
    ){
        return userService.findByScore(score);
    }
}

◾ service

db에 직접적으로 접근하는 역할을 한다.
@Service 어노테이션으로 service 역할이라고 정의한 후,
userRepository 객체를 이용하여 controller에서 사용될 코드를 작성한다.

import com.example.memorydb.user.db.UserRepository;
import com.example.memorydb.user.model.UserEntity;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

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

@Service //서비스 로직이 들어가는 bean의 영역이다
@RequiredArgsConstructor
public class UserService {

    private final UserRepository userRepository; //자동으로 인식하기 위해 bin으로 등록시켜줘야함
    public UserEntity save(UserEntity user){
        //save
        return userRepository.save(user);
    }

    public List<UserEntity> findAll(){
        return userRepository.findAll();
    }

    public Optional<UserEntity> findById(Long userId){
        return userRepository.findById(userId);
    }

    public void delete(Long userId){
        userRepository.delete(userId);
    }

    public List<UserEntity> findByScore(Integer score){
        return userRepository.findByScore(score);
    }
}
profile
하루하루 차근차근🌱

0개의 댓글