4 minute read

직원 데이터 관리와 근태 데이터 삭제 처리

deleteStaffAndTimeManagementSystem 메서드:

public void deleteStaffAndTimeManagementSystem(Long empNum) {
    Staff staff = staffRepository.findById(empNum).orElse(null);
    if (staff != null) {
        timeManagementRepository.deleteByStaff(staff);
        staffRepository.deleteById(empNum);
    }
}

메서드 설명:

  • deleteStaffAndTimeManagementSystem 메서드는 특정 직원의 고유 번호 (empNum)를 인자로 받아, 해당 직원과 그에 연결된 근태관리 데이터를 삭제한다.
  • 초기 단계에서는 Staff 엔터티를 직원의 고유 번호를 통해 조회한다.
  • 직원 엔터티가 검색된 경우, 근태관리 데이터를 먼저 삭제한 후 해당 직원 데이터를 삭제한다.

deleteByStaff 메서드:

public void deleteByStaff(Staff staff) {
    timeManagementRepository.deleteByStaff(staff);
}

메서드 설명:

  • deleteByStaff 메서드는 특정 Staff 엔터티를 인자로 받아 해당 직원에 연결된 근태관리 데이터만을 삭제한다.

두 메서드의 기능적 차이점:

  1. deleteStaffAndTimeManagementSystem 메서드:
    • empNum을 사용하여 특정 직원을 조회한다.
    • 직원이 존재하는 경우, 근태 데이터를 timeManagementRepository.deleteByStaff(staff) 메서드를 통해 삭제한다.
    • 이후 staffRepository.deleteById(empNum) 메서드를 사용해 직원 데이터를 삭제한다.
  2. deleteByStaff 메서드:
    • 이 메서드는 근태 데이터만을 삭제하며, 직원 데이터는 삭제하지 않는다.

요약:

  • deleteStaffAndTimeManagementSystem 메서드는 특정 직원과 그에 연결된 모든 근태 데이터를 삭제하는 데 사용된다.
  • deleteByStaff 메서드는 특정 직원에 연결된 근태 데이터만을 삭제하는 데 사용된다.

결론

데이터 구조와 연관관계의 특성상 직원 정보가 삭제될 때, 그에 연결된 근태 데이터도 함께 삭제되어야 하는 경우가 발생하는데, 연관된 데이터의 무결성을 유지하기 위해 deleteStaffAndTimeManagementSystem 메서드의 방식으로 코드가 설계 되었어야 한다.
하지만 처음 코드를 작성할 때 deleteByStaff 메서드 처럼 특정 직원데이터가 삭제 되면 관련된 근태정산 데이터도 삭제 되도록 코드를 작성하다 보니, 직원 추가는 정상적으로 추가가 되지만 삭제할 땐 삭제가 안되는 이슈가 발생했다.. 💦
원인을 찾아보니, 직원데이터가 추가 된 뒤 근태정산 데이터가 생성되는 것 이기 때문에 삭제할 때도 자료 구조 중에서 스택 자료구조에 해당 하는 부분이 이런 부분이 아닐까… ? 싶었다 ..
그래서 배웠던 스택을 더듬 더듬 기억을 꺼내보고 이슈와 스택의 연관성이 있을까 하는 생각을 정보를 찾아보았다.

image

그러나 .. 해당 이슈와 스택 자료구조에 대해서 찾아보니

제시된 deleteStaffAndTimeManagementSystemdeleteByStaff 메서드 자체는 직접적으로 스택 데이터 구조와 관련이 없다고 한다… 😂 두 메서드는 단순히 데이터베이스에서 특정 직원 데이터 및 관련 근태 데이터를 삭제하는 기능을 수행한다고 한다.

하지만, 내가 설명하는 “데이터가 추가된 순서대로 삭제 되어야 하는” 부분을 고려하면 스택의 LIFO (Last-In, First-Out) 특성과 비슷한 부분이 있다고 한다.
즉, 마지막에 추가된 데이터부터 삭제되어야 하는 경우 스택과 같은 특성을 보이게 되는 것이다. . .

그러나 실제 데이터베이스 연산에서 이러한 순서를 따르도록 하는 것은 보통 연관관계나 무결성 제약조건, 트랜잭션 관리 등의 메커니즘을 통해 이루어지는데,
만약 직원 데이터를 삭제하려 할 때 해당 직원과 연결된 근태 데이터가 존재한다면 무결성 제약조건에 의해 삭제가 실패할 수 있게 되는 것이다.
이러한 문제를 해결하기 위해 먼저 근태 데이터를 삭제하고 나서 직원 데이터를 삭제하는 순서를 따르는 것이다.

따라서, 제시된 코드가 직접적으로 스택 데이터 구조를 구현하는 것은 아니며, 단순히 연관된 데이터의 삭제 순서에 관한 로직을 수행하는 코드이기 때문에 스택과는 직접적인 관련은 없다고 할 수 있다.



꼬리에 꼬리를 무는 생각…

그렇다면 스택 자료구조를 살짝 공부해보고 넘어가보자 (뜬금 없음)

스택(Stack)은 LIFO(Last-In, First-Out)의 특징을 가진 데이터 구조이다… 스택의 가장 상위에 있는 요소를 ‘top’ 또는 ‘peak’이라고 한다. 스택에서는 주로 두 가지 연산, 즉 ‘push’ (스택에 요소 추가) 및 ‘pop’ (스택의 가장 상위 요소 제거 및 반환)이 사용된다.

import java.util.EmptyStackException;

public class StackExample<T> {
    private static class StackNode<T> {
        private T data;
        private StackNode<T> next;

        public StackNode(T data) {
            this.data = data;
        }
    }

    private StackNode<T> top;

    public void push(T item) {
        StackNode<T> newNode = new StackNode<>(item);
        newNode.next = top;
        top = newNode;
    }

    public T pop() {
        if (top == null) throw new EmptyStackException();

        T item = top.data;
        top = top.next;
        return item;
    }

    public T peek() {
        if (top == null) throw new EmptyStackException();
        return top.data;
    }

    public boolean isEmpty() {
        return top == null;
    }

    public static void main(String[] args) {
        StackExample<Integer> stack = new StackExample<>();
        stack.push(1);
        stack.push(2);
        stack.push(3);

        System.out.println(stack.peek());  // 출력: 3
        System.out.println(stack.pop());   // 출력: 3
        System.out.println(stack.peek());  // 출력: 2
    }
}
  1. push 메서드를 사용하여 스택에 요소를 추가하고
  2. pop 메서드를 사용하여 스택의 가장 상위 요소를 제거하고 해당 요소를 반환하게 된다.
  3. peek 메서드를 사용하여 스택의 가장 상위 요소를 조회하지만 제거하지는 않는다.
  4. isEmpty 메서드는 스택이 비어있는지 확인한다.

위의 main 메서드에서는 1, 2, 3을 차례대로 스택에 푸시한 후, peekpop 메서드를 사용하여 현재 스택의 상태를 출력한다.



그렇다면 스택은 어떤 프로그램을 개발할 때 사용될까 ?

  1. 함수 호출 및 실행 컨텍스트: 프로그램에서 함수나 메서드를 호출할 때, 호출 스택이 사용된다고 한다. 함수가 호출될 때마다 호출 스택에 프레임이 추가되며, 함수가 완료되면 해당 프레임이 스택에서 제거된다. 이러한 방식으로 프로그램은 어떤 함수가 현재 실행 중이며 어디로 돌아가야 하는지를 알 수 있다.
  2. 백트래킹: 스택은 알고리즘에서 백트래킹 문제를 해결하는 데 사용된다. 예를 들어, 미로 찾기, n-퀸 문제 등에서 스택을 사용하여 가능한 모든 해결책을 탐색한다.
  3. 문자열 및 수식 처리: 프로그램에서 괄호 매칭, 후위 표기법 변환, 계산기 구현 등의 작업을 수행할 때 스택을 사용한다.
  4. 웹 브라우저의 뒤로 가기 기능: 웹 브라우저에서 사용자가 방문한 웹 페이지의 히스토리는 스택에 저장되어, ‘뒤로 가기’ 버튼을 클릭하면 가장 최근에 방문했던 페이지로 돌아갈 수 있다.
  5. 실행 취소 기능 (Undo): 많은 응용 프로그램에서 실행 취소 기능은 스택을 사용하여 수행되는 작업의 히스토리를 추적한다. 사용자가 “실행 취소”를 선택하면 스택의 상단에서 명령을 제거하고 해당 명령을 롤백한다.
  6. 메모리 관리: 몇몇 프로그래밍 언어 및 시스템에서는 임시 데이터를 저장하기 위해 스택 메모리를 사용한다.

이 외에도 스택은 다양한 프로그래밍 문제와 실제 애플리케이션에서 사용되며, 그 중요성 때문에 컴퓨터 과학과 프로그래밍 교육의 핵심 주제 중 하나로 간주된다고 한다.

이렇게 스택 자료구조의 실사용 예시를 비교해보니, 내가 겪은 이슈와의 차이점이 이해가 된다.
개발은 영역이 굉장히 방대하고, 어렵고 공부해야할게 많다는 것을 다시 한번 느낀다.
그래서 자극되고 흥미가 생긴다.
이번 글을 작성하는 계기로 스택과 데이터베이스의 무결성 제약조건에 대해서는 더 딥하게 공부해보고
지식을 쌓을 수 있었던 계기라고 생각한다. 😋

맨 위로 이동하기

Leave a comment