티스토리 뷰

 

 

 

그리드간 형태  드래그 기능 예시

 

Sort 5를 Sort 2로 드래그를 하여 Sort 1과 Sort 2사이에 삽입이 되었다.

그래서  Sort 2이후의 순번들은 하나씩 밀리게 된다. 

드래그 기능 예시

 

 

 

 

나의 문제 상황

 

나는 이 그리드간 드래그 앤 드랍기능을 구현하면서 성능을 하나도 고려하지 않고 그냥 기능 구현에 급급했다.

구현은 되었고 코드 리뷰와 테스트를 할 때 몇가지의 문제 상황을 발견하였다.

 

 

  1. 드래그를 하여 순번이 바뀌면 전체의 순번을 재정렬을 하는 코드로 구현하였다.
  2. 중간에 삭제를 하면 전체의 순번을 재정렬하는 코드로 구현하였다.
  3. JPA를 사용하여 저장을 하였는데 전체의 순번을 재정렬하는데 반복문을 돌리면서 커넥션을 막 찌르고 있었다.

 

지금 생각해보면 진짜 개발도 못 하였고 개발자가 아닌 공부하는 것처럼, 학생처럼 개발하게 되었다는 것에 너무 부끄러웠다...

 

 

 

 

구현 할 때 고려할 상황이면서 해결 방법

 

1) 드래그 할 때 순번 정렬 Solution1

드래그 순번 정렬

그림과 같이 Sort 5를 Sort 1과 Sort 2에 사이에 뒀을 때 전체를 정렬을 해주었다.

하지만 내가 바꾼 요소의 이전 Sort 값과 바꿔서 들어간 새로운 Sort 값 사이만 정렬해주면 되는거 였다.

 

  1. Sort 2, Sort 3, Sort 4들은 각각 Sort + 1 을 해준다.
  2. Sort 5값은 Sort 2로 변경해준다. (현행화)

 

 

그럼 꼭 필요한 값들은 무엇일까? 

드래그한 요소(Sort 5)의 ID값, 드래그 하기전에 이전 Sort 값 , 드래그 후 이동한 Sort값이 필요할 것이다.

서비스 로직이 아닌 DB에 있는 데이터를 어떻게 변경해야하는지 보겠다.

 

-- 드래그 하기전에 이전 Sort 값 = 5
-- 드래그 후 이동한 Sort값 = 2
UPDATE yourTable
SET sort = sort + 1
WHERE 2 <= sort AND sort < 5
-- 드래그한 요소(Sort 5)의 ID값 = 5
UPDATE yourTable
SET sort = 2
WHERE id = 5

이렇게 UPDATE 쿼리문 하나로 DB의 커넥션 영향도는 2번으로 줄였다.

 

 

 

 

2) 드래그할 때 순번정렬 Solution2

드래그 순번 정렬2

 

  1. Sort 3, Sort 4, Sort 5들은 각각 Sort - 1 을 해준다.
  2. Sort 2값은 Sort 5로 변경해준다. (현행화)

그럼 꼭 필요한 값들은 무엇일까? 

드래그한 요소(Sort 2)의 ID값, 드래그 하기전에 이전 Sort 값 , 드래그 후 이동한 Sort값이 필요할 것이다.

 

-- 드래그 하기전에 이전 Sort 값 = 2
-- 드래그 후 이동한 Sort값 = 5
UPDATE yourTable
SET sort = sort - 1
WHERE 2 < sort AND sort <= 5
-- 드래그한 요소(Sort 2)의 ID값 = 2
UPDATE yourTable
SET sort = 5
WHERE id = 2

이렇게 UPDATE 쿼리문 하나로 DB의 커넥션 영향도는 2번으로 줄였다.

 

 

 

 

3) 중간에 삭제하면 정렬

드래그 정렬 삭제

그림과 같이 Sort 3을 삭제하게 된다면 그 이후에 있는 요소들만 Sort -1 를 해주면 된다.

그러곤 이후에 Sort 3에 있는 것을  use_Yn 칼럼이 있거나 Del_Yn 칼럼이 있으면 값을 변경해주거나

해당 칼럼이 없다면 아예 DELETE 처리해주면 드래그 했을 때 순서가 DB 상에서와 UI상에서 맞게 된다.

-- 삭제한 요소 Sort = 3
-- 삭제한 요소 ID = 3

-- 이후에 있는 Sort값을 하나씩 줄여서 값 현행화
UPDATE yourTable
SET sort = sort -1
WHERE 3 < sort

 

 

4) DB 커넥션 막 찌르지 않기!

아래는 절대 하지 말아야할 코드입니다.

설명을 조금하자면 그리드에 있는 데이터를 List로 조회 한 후 반복문을 돌리고 Sort값을 변경하여 새롭게 저장하는 방법이였습니다.

@Service
@Requiredargsconstructor
public class YourServiceImpl implements YourService {
    
    @Autowired
    private final YourRepository yourRepository;
    
    
    public logic(Long oldSort, Long newSort, Long Id, Long groupId) {
        // 드래그하는 그리그 그룹별로 있기 때문에 그룹을 통해 리스트로 가져오기
        List<BoardEntity > list = yourRepository.findByGroupId(groupId);
        
        // 반복문 돌리면서 Sort값 새롭게 해주고 저장
        for(BoardEntity board : list) {
            Long sort = board.getSort();
            board.setSort(sort + 1);
            yourRepository.save(board);
        }
    }
}

 

이렇게 되면 데이터가 1만건 10만건일 경우 DB를 막 찌를 뿐만 아니라 여러명에서 이 로직을 요청하게 된다면 너무 큰일 날 수 도 있습니다.

그래서 DB저장할 때는 한번에 저장할 수 있는 방법을 찾으시고 반복문도 조금 지양해주면 깔끔한 코드가 완성될 것같습니다.

그래서 저는 UPDATE를 사용하는 방법으로 하게 되었습니다.

 

 

 

감사합니다.

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함