본문 바로가기
공부/SQL & JPQL

JPQL 콘솔로 쿼리문 작성해보기 - 1

by 고구밍 2022. 5. 24.

내가 하고있는 업무

코드 성능 높이기 -> FOR문을 줄이자 -> 파싱을 조회쿼리에서 한번에 받아오자

 

1. 마이페이지 

 

이미지가 여러장이 저장되는데,

문자열 "," 을 기준으로 나눠서 [0] 번째 (첫번 째)에 있는대표 이미지 문자열을 받아오기

for (ItemUserResponseDto eachItem : ItemList) {
            ItemUserResponseDto Item = new ItemUserResponseDto(
                    eachItem.getItemId(),
                    eachItem.getImage().split(",")[0],
                    eachItem.getStatus()
            );
            myItemList.add(Item);
        }

 

 

2. 거래내역조회하기 (가장 느림)

거래내역 (Baret) 엔티티에서

1. barter(파싱되어있는 거래아이템 ID들)를 ";"와 ","를 통해서 문자열로 분리

2. 문자열들을 for문을 이용하여

3. 하나씩 Long타입으로 변환

4. 변환된 Id값을 하나씩 itemRepository에서 조회하여

5. dto에 정보를 넣고

6. dto를 상황에 맞게 분배해준다.

 

for (Barter barters : mybarterList) {
            Long barterId = barters.getId();
            LocalDateTime date = barters.getModifiedAt();

            String barter = barters.getBarter();
            //barter 거래내역 id split하기 -> 파싱하여 거래항 물품의 Id값을 찾기
            String[] barterIds = barter.split(";");
            String[] buyerItemIdList = barterIds[0].split(",");
            String[] sellerItemIdList = barterIds[1].split(",");


            // 거래상태 정보 1 : 신청중 / 2 : 거래중 / 3 : 거래완료 / 4 : 평가완료
            int status = barters.getStatus();
            Long opponentId;
            String myPosition;
            //내포지션이 바이어라면 거래내역의 상태 확인하기
            if (barters.getBuyerId().equals(userId)) {
                myTradeCheck = barters.getIsBuyerTrade();
                myScoreCheck = barters.getIsBuyerScore();
                opponentTradeCheck = barters.getIsSellerTrade();
                myPosition = "buyer";
                opponentId = barters.getSellerId();
                //내포지션이 셀러라면 거래내역의 상태 확인하기
            } else {
                myTradeCheck = barters.getIsSellerTrade();
                myScoreCheck = barters.getIsSellerScore();
                opponentTradeCheck = barters.getIsBuyerTrade();
                myPosition = "seller";
                opponentId = barters.getBuyerId();
            }
            // 상대 유저 정보
            User opponentUser = userRepository.findById(opponentId).orElseThrow(() -> new CustomException(NOT_FOUND_USER));


// 거래 물품리스트를 담을 Dto -> 내것과 상대것을 담는다
            List<OpponentBarterDto> myBarterList = new ArrayList<>();
            List<OpponentBarterDto> barterList = new ArrayList<>();
            // 바이어(유저)의 물품을 찾아서 정보를 넣기
            for (String buyerItemId : buyerItemIdList) {
                Long itemId = Long.parseLong(buyerItemId);
                BarterItemListDto buyerItem = itemRepository.findByBarterItems(itemId);
                // 각 아이템의 정보를 리스트에 담기
                OpponentBarterDto buyerItemList = getMyBarterDto(buyerItem);
                //상대와 나의 바터리스트에 각각 아이템을 넣기
                BarterCheckAddList(barters, userId, myBarterList, buyerItemList, barterList);
            }

            //셀러(유저)의 물품을 찾아서 정보를 넣기
            for (String sellerItemId : sellerItemIdList) {
                Long itemId = Long.parseLong(sellerItemId);
                BarterItemListDto sellerItem = itemRepository.findByBarterItems(itemId);
                // 각 아이템의 정보를 리스트에 담기
                OpponentBarterDto sellerItemList = getMyBarterDto(sellerItem);
                //상대와 나의 바터리스트에 각각 아이템을 담기
                BarterCheckAddList(barters, opponentId, myBarterList, sellerItemList, barterList);
            }

 

현재 봉착한 문제

MySQL의 콘솔로 로직이 구현이 가능한지 테스트를 해 보았습니다.

 

저희가 정한 규칙으로는 한 유저당 Bag에 Item을 9개까지 보관할 수 있습니다.

따라서 거래신청을 할 경우 buyerItem의 갯수는 최대 9개까지 파싱되어 있는 경우가 있는데,

 

DB에 저장되는 buyerItem의 갯수는 정해져 있지않고, 상황에 따라서 변하기 때문에

select를 통해서 원하는 부분까지 유동적으로 자료를 받을 수 없다는 점을 알게되었습니다.

 

-> 따라서 우선적으로, sellerItem은 바로 dto를 통해서 정보를 받고

-> buyerItem은 파싱된 정보를 받아서 for문으로 조회하는 방법으로 접근할 예정입니다.

 

 

 

연습으로 작성한 MySQL콘솔 코드

#  불안정, 첫번째 인덱스 값을 유동적으로 받을 수 없을까?
# buyerItem이 파싱되어있는 갯수는 다른데, db에서 select 조회할 때 유동적으로 변하기 때문?
select SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',1)as'1번',
       SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',2), CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',1), ','), -1)as'2번',
       SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',3), CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',2), ','), -1)as'3번',
       SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',4), CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',3), ','), -1)as'4번',
       SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',5), CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',4), ','), -1)as'5번',
       SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',6), CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',5), ','), -1)as'6번',
       SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',7), CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',6), ','), -1)as'7번',
       SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',8), CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',7), ','), -1)as'8번',
       SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',9), CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(br.barter , ';', 1),',',8), ','), -1)as'9번'
from barter br

# 셀러아이템 파싱
# select SUBSTRING_INDEX(br.barter , ';', -1) as'sellerItem'
# from barter br

# select SUBSTRING_INDEX(br.barter , ';', 1), SUBSTRING_INDEX(br.barter , ';', -1)
# from barter br

# select *
# from barter;

 

 

참고링크

더보기

JPQL - 기본 문법과 기능

https://iseunghan.tistory.com/258

 

10-2) JPQL - 기본 문법과 기능

자바 ORM 표준 JPA 프로그래밍 - 기본편을 공부하며 정리한 내용입니다. 자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들

iseunghan.tistory.com

[MySQL] 문자열 자르기 SUBSTRING, SUBSTRING_INDEX & 활용

https://beagle-dev.tistory.com/270

 

[MySQL] 문자열 자르기 SUBSTRING, SUBSTRING_INDEX & 활용

MySql, Mariadb의 SUBSTRING, SUBSTRING_INDEX 문자열 자르기 함수에 대해 알아보겠습니다. 추가로 SUBSTRING_INDEX를 활용하여 JAVA의 split처럼 문장열로 자르고 Index에 맞게 가져오는 방법을 설명하겠습..

beagle-dev.tistory.com

Mysql 문자열 자르기와 나누기 함수

https://abbo.tistory.com/232

 

Mysql 문자열 자르기와 나누기 함수

1. 왼쪽에서 문자열 자르기 left(컬럼명 또는 문자열, 왼쪽에서 잘라낼 문자열의 길이) 사용예 : SELECT left("https://abbo.tistory.com", 5) 결과 : https 사용예 : SELECT left("https://abbo.tistory.com", 8)..

abbo.tistory.com

MySQL 문자열 자르기 SUBSTRING, SUBSTRING_INDEX

https://leeys.tistory.com/23

 

MySQL 문자열 자르기 SUBSTRING, SUBSTRING_INDEX

MySql, Mariadb의 SUBSTRING, SUBSTRING_INDEX 문자열 자르기 함수에 대해 알아보겠습니다. 추가로 SUBSTRING_INDEX를 활용하여 JAVA의 split처럼 문장열로 자르고 Index에 맞게 가져오는 방법을 설명하겠습니다...

leeys.tistory.com

 

https://iseunghan.tistory.com/258

 

10-2) JPQL - 기본 문법과 기능

자바 ORM 표준 JPA 프로그래밍 - 기본편을 공부하며 정리한 내용입니다. 자바 ORM 표준 JPA 프로그래밍 - 기본편 - 인프런 JPA를 처음 접하거나, 실무에서 JPA를 사용하지만 기본 이론이 부족하신 분들

iseunghan.tistory.com

[MySQL] 문자열 자르기 SUBSTRING, SUBSTRING_INDEX & 활용

https://beagle-dev.tistory.com/270

 

[MySQL] 문자열 자르기 SUBSTRING, SUBSTRING_INDEX & 활용

MySql, Mariadb의 SUBSTRING, SUBSTRING_INDEX 문자열 자르기 함수에 대해 알아보겠습니다. 추가로 SUBSTRING_INDEX를 활용하여 JAVA의 split처럼 문장열로 자르고 Index에 맞게 가져오는 방법을 설명하겠습..

beagle-dev.tistory.com

Mysql 문자열 자르기와 나누기 함수

https://abbo.tistory.com/232

 

Mysql 문자열 자르기와 나누기 함수

1. 왼쪽에서 문자열 자르기 left(컬럼명 또는 문자열, 왼쪽에서 잘라낼 문자열의 길이) 사용예 : SELECT left("https://abbo.tistory.com", 5) 결과 : https 사용예 : SELECT left("https://abbo.tistory.com", 8)..

abbo.tistory.com

MySQL 문자열 자르기 SUBSTRING, SUBSTRING_INDEX

https://leeys.tistory.com/23

 

MySQL 문자열 자르기 SUBSTRING, SUBSTRING_INDEX

MySql, Mariadb의 SUBSTRING, SUBSTRING_INDEX 문자열 자르기 함수에 대해 알아보겠습니다. 추가로 SUBSTRING_INDEX를 활용하여 JAVA의 split처럼 문장열로 자르고 Index에 맞게 가져오는 방법을 설명하겠습니다...

leeys.tistory.com

 

 

'공부 > SQL & JPQL' 카테고리의 다른 글

SQL 공부하기 - 4  (0) 2022.05.02
SQL공부하기 - 3  (0) 2022.05.02
SQL 공부하기 - 2  (0) 2022.05.02
SQL 공부하기 - 1  (0) 2022.05.01