개발 일지/주간 개발 일지

[05월 3주차] querydsl JOIN 방법

계란💕 2023. 5. 15. 10:36

에러 해결


axios 요청 응답이 null인 경우

 

  • 오류 
    • get 요청을 보낸 응답에서 데이터가 없는 경우, 오류가 발생했다. 
    • if 문을 만족하지 않으니까 <template> 태그 안 코드가 실행되지 않는 게 정상인데 계속해서 들어갔다. 
  • 원인
    • get 요청을 보낸 응답 데이터에 리스트가 비어 있는 경우, res.data 는 null 이 아니고 res.data.data가 null이다. 
    • 보통 axios로 요청을 보내면 응답 객체는 data, status, statusText, headers, ...와 같은 구조가 있다. 
    • 따라서, 뒤에 ".data"를 붙여야 실제로 필요한 데이터에 접근할 수 있다. 
  • 해결
    • 다음과 같이 수정한다.
<hide/>
<template v-if="state.modelList !== null">
             
========== script ==========             
$axios
.get(
  util.format($apiUrls.model.getModelList)
)
.then((res) => {
      if (res.data.data === null) {
        state.modelList = null;
        return;
      }
      state.modelList = res.data;
    })
.catch(){
}

 

 

   cf) axios 요청에 대한 응답 response 의 요소

  • response.data: 서버가 제공한 응답 (데이터), 실제로 필요한 값이 있다. 
  • response.status: HTTP 상태코드로 200같은 값이 들어가있다. 
  • response.statusText: HTTP 상태 메시지
  • response.headers
  • response.config: 요청에 대해 axios 에 설정된 구성
  • response.request: 응답을 생성한 요청

 

 

 

Note


async와 await

  • JavaScript의 키워드인 async / await를 사용하면 비동기 함수동기적으로 실행할 수 있다. 
  • ES8에 해당하는 문법으로 Promise를 더욱 쉽게 사용할 수 있도록 해준다. 
  • 동기적으로 실행되는 코드: 순차적으로 코드가 실행되며, 이전 코드가 실행 완료되어야 다음 코드가 실행된다. 
  • 비동기로 실행되는 코드: 비동기 함수가 호출되면 해당 함수가 실행되는 동안 다른 코드가 실행된다. 그리고 비동기 함수 처리가 완료되면 결괏값을 롤백하거나 콜백 함수를 호출한다. 
  • 함수를 선언할 때, async 키워드를 붙인다. 그리고 Promise의 앞부분에 await를 넣어주면 해당 프로미스가 끝날 때까지 기다렸다가 다음 작업을 수행한다. 
  • Promise.all([ 여러 메서드 ]): 등록한 프로미스 중에서 하나라도 실패하면 모든 게 실패한 걸로 간주한다. 
  • Promise.race(): all()과는 다르게 여러 개의 프로미스를 등록해서 실행했을 떄 가장 빨리 끝난 한 개의 결과만을 가져온다. 

 

 참고) https://learnjs.vlpt.us/async/02-async-await.html


param key 중복 체크 

  • key- value 형태의 paramList에 대해 key가 중복되지 않도록 설정하려고 한다. 
  • JavaScript에서 배열은 .push()를 이용해서 데이터를 넣을 수 있다. 
  • 중복되는 key가 있을 경우, true를 반환한다. 
  • Set은 중복을 허용하지 않기 때문에 이러한 Set의 특성을 활용하면  param 중에서 중복된 key가 있는지 확인 가능하다. 
<hide/>
const isDuplicated = (data) => {
  let arrKey = [];
  for (let param of data) {
    arrKey.push(param.paramKey);
  }
  const set = new Set(arrKey);  
  if (set.size == data.length) {
    return false;
  }
  return true;
};

 


Vuye.js 3기준 화면 이동 방법과 컴포넌트 간 데이터 전달

  • 1) routerPush()
    • routerPush(pltform, "이동하려는 컴포넌트의 라우터명?", query): 새로운 페이지로 이동한다. 
    • 라우트 이름은 router 폴더 안에 index 파일에 정의한 name과 동일해야한다?( 회사 규칙인지, 뷰 규칙인지 모르겠음)

 

  • 2) 라우터 파일에 해당 경로를 등록한다. 
    • 여기서 name은 router에 push한다.

 

  • 3) 뷰 파일에 컴포넌트 삽입
    • ModelEdit라는 부모 컴포넌트에 ModeEdit, ModeParamEdit 두 개의 자식 컴포넌트를 넣는다면?
    • <template> 태그 안에 <ModelEdit/>, <ModelParamEdit/> 같은 형태로 넣을 수 있다. 
    • 자식 컴포넌트 ModelParamEdit로 어떤 데이터를 전달하고 싶다면?
    • <ModelParamEdit :listB="listA"> : 부모 컴포넌트에서 선언한 listA라는 데이터를 ModelParamEdit  컴포넌트로 전달할 수 있다. 

 

  • 그러면 자식 컴포넌트 ModelParamEdit에서는 다음과 같이 데이터를 받을 수 있다.  
<hide/>
const props = defineProps({
  listB: {
    type: Array,
    required: true,
  }
})

 


 querydsl JOIN 방법 

  • codeId: COD_00001 - codeName: "생성" 과 같은 내용의 테이블이 DB에 저장이 되어 있다.
  • 모델 목록에 대해서 엔티티 Model의 상태 코드를 의미하는 statusCode (ex) COD_00001)라는 필드가 있다. 
  • 그런데 이 부분은 "COD_xxxxx" 와 같은 형태라서 어떤 상태(시작, 요청, 종료, 등)를 의미하는지 파악이 힘들다. 
  • 그래서 Model 엔티티에 @Transient 필드(statusCodeName)를 하나 추가해서 codeName을 나타내려고 한다. 
  • Model의 쿼리 클래스에 대해서도  목록 조회, projection() 메서드에 com_table과 join() 하는 부분을 추가해서 실질적인 역할을 나타내는 이름을 가져오도록 수정할 수 있다. 

 

 

  • 백엔드
    • 1) 엔티티 추가: codeId, codeName두 개를 칼럼으로 가지는 엔티티를 추가하고 나고 querydsl을 compile 해주면 자동으로 target 폴더 (gradle 기준으로는 build 폴더)안에 Q클래스가 추가된다. 
    • 2) Model 엔티티에@Transient 필드를 하나 추가한다. (statusCodeName)
    • 3) 쿼리 클래스 join 을 추가한다. 
    • 테이블명: commomCode
<hide/>
@Data
@Entity
@Table(name = "common_code", schema = "스키마명")
public class CommonCode {
    @Id
    private String codeId;
    private String codeNm;
}

 

 

  • 기존 쿼리 클래스에서 다음과 같이 
    • projection() 안에 다음과 같이 JOIN을 적용한다. 
<hide/>
private QBean<Model> projection() {
    return Projections.bean(Model.class,
             model.modelId,
             model.statusCode,
             commomCode.codeNm.as("statusCodeName"),
            ...;
}

// Model 목록 조회 코드 일부
public List<Model> getModelList(Model searchModelVO){
    return queryFactory
            .select((projection()))
            .from(model)
            .leftJoin(commomCode)
            .on(model.statusCd.eq(commomCode.codeId))
            ...;
    ...;
}

 

 

  • 프론트
    • statusCode, statusCodeName 두 데이터를 모두 받아서 codeName을 사용하면 된다. 
    • defineProps()를 이용한다. 

@Table(name = "", schema="")

  • name "테이블명"
  • schema = "스키마이름"
  • 해당 스키마 안에서 테이블을 찾는다. 
  • 스키마(Schema)는 데이터베이스에서 테이블을 그룹화하는데 사용한다. 스키마는 데이터베이스에서 테이블 구조를 정의하기 위해 사용되는 개념이다. 
  • 복잡한 실무에서 많은 테이블을 그룹을 나눠서 관리하는 경우, 테이블의 특성에 따라 나눠서 schema를 지정해주면 편리하다. 

title

  • content

찾아 보기

  •