반응형

 

시작하며

 

개인적으로 진행한 프로젝트이므로 틀린 정보가 있을 수 있습니다
언제든지 댓글 달아주세요 :)


1. AWS 프리티어 계정 생성

사이트 URL : https://aws.amazon.com

AWS 프리티어 계정 생성을 위하여 사이트에 방문하고 가입합니다

 

AWS 프리티어 계정이란?
아마존 웹 서비스에서 지원하는 무료로 서버를 사용할 수 있는 권한입니다

 

인스턴스란?
서버 라고 생각하면 됩니다

 

EC2 인스턴스란?
AWS 에서 사용하는 인스턴스를 EC2 인스턴스라고 합니다

 

2. EC2 인스턴스 생성

콘솔 홈 화면 하단의 위젯 ->가상머신 시작 클릭

1) 인스턴스 설정

 

 

이름 : 프로젝트명 입력
Quick Start : Ubuntu - Ubuntu Server 22.04 LTS(HVM) SSD Volume Type

프리티어 사용 가능이라고 적혀진 옵션을 선택

 

인스턴스 유형 : t2.micro
키페어 : 새 키페어 생성 (키페어 있을경우 콤보박스에서 기존 키페어 쓰거나 새로 생성)

키페어란 ?
putty, fileZilla 등으로 서버접속이 가능한 .ppk .pem 파일
키페어 이름은 단순 ppk/pem 파일명이므로 큰 의미를 갖지않으니 적당히 정하기

 

네트워크 설정 : 보안그룹생성 - ssh 트래픽허용 (기존 보안그룹이 있다면 콤보박스에서 선택)

 

스토리지 구성 : 20g (20g가 프리미어 최대 제공 스토리지)
IAM 생성 : 필요에 따라 생성

 

IAM 이란 ?
관리자 접근권한을 관리하는 서비스이며 다수의 관리자가 모든 데이터에 접근하면 위험하므로, 관리자 접근 및 행동을 제어하기위한 설정

 

탄력적 IP 생성 : 유료서비스. 한달에 1000원이내. 인스턴스에 특정 IP를 고정해서 사용할 수 있다.

유료서비스이므로 나는 하지않았지만, 발급방법은 아래와같다

 

2) 탄력적 IP 생성

  1. IP 주소 할당

 

   2. IP 주소 생성완료

   

   3. 인스턴스 - IP 연결

3. 서버 접속

만들어두었던 EC2 서버에 접속한다

 

만약 아래의 방법으로 접속이 안된다면, aws 설정으로 22번 포트가 안뚫려있을수도있다


AWS 웹페이지 -> 콘솔 -> EC2 -> 보안그룹 -> 인스턴스명 선택 -> 인바운드 규칙 편집
여기서 22번 포트를 추가해보자

1) window 접속방법

  • 접속 툴 : putty
  • 접속 키 : ppk
    AWS에서 발급받은 키페어파일이 pem 파일이라면, ppk 파일로 변환해야한다
    ppk 파일변환하려면 puttygen 실행 -> key 변환해준다
  1. ppk 파일연결
    putty -> Connection -> SSH -> Auth -> Credentials -> private key file for auentication 여기에 ppk 파일 첨부

      save 버튼은 따로없다 바로 session 탭으로 이동한다

 

    2. 서버접속
      aws콘솔 인스턴스에서 확인되는 퍼블릭 IPv4 주소 를 Host Name 에 넣고 open 하면 아래와 같이 접속된다
      login as : 라고 나올텐데 당황하지않고 ubuntu 라고 입력해주자

2. mac 접속방법

  • 접속 툴 : terminal
  • 접속 키 : pem
    AWS에서 발급받은 키페어파일이 ppk 파일이라면, pem 파일로 변환해야한다
  1. ppk to pem
    mac에서 변환하려면 아래 커맨드로 putty 를 설치하고
$ brew install putty


        아래 커맨드로 변환한다

$ puttygen [원본.ppk] -O private-openssh -o [사본.pem]

 

    2. 서버접속
        pem 파일이 있는 위치에서 terminal 실행한다
        AWS 웹페이지 -> 인스턴스명 우클릭 -> 연결 -> SSH클라이언트 탭 클릭하여 예) 부분에 나와있는 명령어를 그대로 입력한다

4. 서버 time zone 세팅

새로발급받은 서버는 보통 US 미국기준으로 타임존 세팅이 되어있다.
아래 커맨드로 타임존을 확인한다

$ sudo date

 

타임존이 우리나라가 아니며, 우리나라로 세팅을 해야한다면 아래와 같은 커맨드를 입력한다

 

$ sudo timedatectl set-timezone 'Asia/Seoul'

 

타임존을 다시 조회해본다면 서울로 바뀌어있을것이다

 

서버세팅 완료~

 

728x90
반응형

 

1. dependency thymeleaf 추가

implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

 

2. dependency thymeleaf 레이아웃 가능하게하도록 추가

implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'

 

이제 환경설정이 끝났으니, 레이아웃 제작

이런 루트로 생될 예정임.

 

3. footer.html 생성

<html lagn="ko" xmlns:th="http://www.thymeleaf.org">
<!--footerFragment 선언-->
<div th:fragment="footerFragment">

  <style>
    .admin-footer {
      background-color: aliceblue;
      padding-left: 10%;
      min-height: 150px;
    }
  </style>

  <div class="admin-footer">
    <h3>footer area</h3>
  </div>
</div>
</html>

th:fragment 설정으로 fooerFragment 매핑시켜줌

 

 

4.header.html 생성

<html lagn="ko" xmlns:th="http://www.thymeleaf.org">
  <!--headerFragment 선언-->
  <div th:fragment="headerFragment">

    <style>
      ul {
        list-style-type: none;
        margin: -19px -9px -9px -7px;
        width: 10%;
        padding:50px 0 0 0;
        background-color: #f1f1f1;
        position: fixed;
        height: 100%;
        overflow: auto;
      }
      li a {
        display: block;
        color: #000;
        padding: 8px 16px;
        text-decoration: none;
      }

      li a.active {
        background-color: #555;
        color: white;
      }

      li a:hover:not(.active) {
        background-color: #555;
        color: white;
      }

    </style>

    <ul>
      <li><a href="/admin">대시보드</a></li>
      <li><a href="/admin/statistics/list">방문 통계</a></li>
      <li><a href="/admin/user/list">회원 관리</a></li>
      <li><a href="/admin/menu/list">메뉴 관리</a></li>
      <li><a href="/admin/expo/list">일정 관리</a></li>
      <li><a href="/admin/tag/list">태그 관리</a></li>
      <li><a href="/admin/event/list">이벤트 관리</a></li>
    </ul>

  </div>
</html>

th:fragment 설정으로 headerFragment매핑시켜줌

 

5. default_layout.html 생성

<!DOCTYPE html>
<html lagn="ko"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
  <meta charset="UTF-8" />
  <title>타이틀/title>
  <meta name="viewport" content="width=device-width, maximum-scale=1.0, minimum-scale=1, user-scalable=yes,initial-scale=1.0" />

  <!-- 공통 css -->
  <link rel="stylesheet" th:href="@{/content/css/common.css}" >
  <th:block layout:fragment="css"></th:block>

  <!-- 공통 script -->
  <th:block layout:fragment="script"></th:block>
</head>

<body>
<!-- header -->
<th:block th:replace="~{fragments/header :: headerFragment}"></th:block>

<!-- content -->
<th:block layout:fragment="content"></th:block>

<!-- footer -->
<th:block th:replace="~{fragments/footer :: footerFragment}"></th:block>

</body>
</html>

만약!!

~{flagments 이게 활성화되어있지않고 녹색으로 죽어있다면(인텔리제이 기준)

gradle 새로고침 해줘야함

 

6.index.html 생성

 

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" <!-- 레이아웃을 쓴다는 설정-->
      layout:decorate="~{layouts/default_layout}"> <!-- 레이아웃을 쓴다는 설정-->

<!-- index.html에서만 사용할 CSS -->
<th:block layout:fragment="css">
    <!--<link rel="stylesheet" th:href="@{/css/common.css}" >-->
</th:block>
<!-- index.html 에서만 사용할 스크립트 -->
<th:block layout:fragment="script">
    <!--    <script th:src="@{/js/page/home.js}"></script>-->
</th:block>

<!-- Content -->
<div layout:fragment="content">
    <div class="container">
        <h3>대시보드</h3>
        <img th:src="@{/content/image/dash1.PNG}"/>
        <img th:src="@{/content/image/dash2.PNG}"/>
    </div>
</div>
</html>

 

이제 빌드하면 레이아웃 정상적으로 보일것임!!!

 

그리고.. 만약 안된다면 build.gradle 새로고침~~

728x90
반응형

 

1. 페이지 이동

 

1) 이동할 페이지 생성

<template>
  <div>board List</div>
</template>

<script>
export default {
  name : 'boardList'
}
</script>

?궁금증 export default name 은 왜 하는걸까? 없어도 페이지이동 되던데..

 

나는 pages 에 새 폴더 만들어서 페이지를 만들어줬다.

 

2) 이동

<nuxt-link to="/board/boardList">ttt</nuxt-link>

<nuxt-link> 태그를 이용해서 페이지이동한다.

to 속성에 이동할 페이지의 디렉토리 정보를 넣어준다.

 

nuxt 특징은 pages에 페이지 만들어주면 .nuxt -> router.js 에 자동으로 라우터가 생성된다.

vue를 쓰면 항상 라우터설정을 해줘야되는데 자동으로 생성되기때문에 좋은듯!

 

2. 레이아웃

 

1) header.vue 생성

<template>
  <header>
    <div id="nav">
      <nuxt-link to="/">Home</nuxt-link> |
      <nuxt-link to="/about">About</nuxt-link> |
      <nuxt-link to="/board/list">게시판</nuxt-link>
    </div>
  </header>
</template>

2) footer.vue 생성

<template>
  <footer>
    <h3>footer 입니다.</h3>
  </footer>
</template>

3)index.vue에 추가

<template>
    <page-header/>
    <nuxt-link to="/board/boardList">게시판 이동</nuxt-link>
    <page-footer/>
</template>

-> 이렇게 하면 에러남!

<template>
  <div>
    <page-header/>
    <nuxt-link to="/board/boardList">게시판 이동</nuxt-link>
    <page-footer/>
  </div>
</template>

template 아래 div 혹은 selection 도 좋으니.. 최상위태그 하나 만들어서 씌워줘야한다.

 

 

 

 

728x90

'FrontEnd > Nuxt' 카테고리의 다른 글

nuxt + spring boot + jpa + h2 게시판 만들기  (0) 2023.05.09
반응형

npm 설치 되어있다는 가정 하에,

 

 

1. nuxt 프로젝트 생성

 

1) nuxt 프로젝트 시작할 폴더하나 만들기

2) cmd창 혹은 터미널에서 해당 폴더 경로로 이동하여 아래 명령어 실행

 

1. Vue-CLI, Vue-CLI-init설치

$ npm i -g @vue/cli
$ npm i -g @vue/cli-init

# 설치 후 버전 확인
$ vue --version

2. nuxt 프로젝트 생성

$ npm init nuxt-app <project-name>

#혹시 위 커맨드가 안된다면 아래 커맨드사용
$ vue init nuxt-community/starter-template myvueapp

<project-name> 대신에 본인이 원하는 프로젝트명으로 이름 넣어주면 된다

 

nuxt 프로젝트 생성완료

 

2. 프로젝트 실행

 

생성된 nuxt 프로젝트로 이동

cd <project-name>

프로젝트 실행

npm run dev

 

3. spring boot 프로젝트 생성

sts, intellij 에서 바로 만들어도되지만, 나는 https://start.spring.io/  여기를 이용했다.

jdk 17로 설정하고 디펜던시는 적당히 꾸려줬다

h2 안쓰면 추가할필요없음. 본인이 추가하고싶은 db 추가하면됨

 

1)기초 controller 생성

mainController 하나 생성해준다.

@RestController
@RequestMapping("/api")
public class MainController {

    @GetMapping(value="/helloWorld")
    public String helloWorld() {
        return "Hello World!";
    }

}

꼭... @RestController로 어노테이션 달아야한다.. @Controller로 달았다가 3시간동안 삽질함.

 

2) h2 연결

application.yml 수정해준다

server:
  port: 8081

spring:
  jackson:
    property-naming-strategy: SNAKE_CASE

  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true
    generate-ddl: true
    defer-datasource-initialization: true

  h2:
    console:
      enabled: true  # H2 Console을 사용할지 여부 (H2 Console은 H2 Database를 UI로 제공해주는 기능)
      path: /h2-console  # H2 Console의 Path
  # Database Setting Info (Database를 H2로 사용하기 위해 H2연결 정보 입력)
  datasource:
    driver-class-name: org.h2.Driver  # Database를 H2로 사용하겠다.
    url: jdbc:h2:~/test  # H2 접속 정보
    username: sa  # H2 접속 시 입력할 username 정보 (원하는 것으로 입력)
    password:  # H2 접속 시 입력할 password 정보 (원하는 것으로 입력)

포트설정 어쩌고저쩌고 하고 실습용으로 h2를 달아놓음

 

 

4. nuxt - spring proxy 연결

  - jsp로 만들지않는이상, html이나 vue로 만들게되면 프론트, 백단 서버를 따로따로 띄워야한다. 

   프론트서버 포트 3000, 백단 서버 8080 이런식으로 뜨게되는데, 프론트 포트3000에서 백단 8080을 호출해서 통신하는데 서로 포트가 다르면 cors error 발생하므로 연결해주는 작업이 필요하다

 

1) axios, proxy install

 

 axios : get/post 통신장치

$ npm install @nuxtjs/axios

 

proxy : 포트 간 통신을 위한 설정장치

$ npm install @nuxtjs/proxy

 

2) nuxt.config.js 수정

module.exports = {
telemetry:true,
...
modules: [
    '@nuxtjs/axios',
    '@nuxtjs/proxy'
  ],
  axios: {
    proxy: true
  },
  proxy: {
    '/api': {
      target: 'http://localhost:8443/', //spring port 입력
      changeOrigin: true // cross origin 허용
    }
  }
}

/api 로 시작되는 요청은 모두 8443 포트로 넘겨버리겠다는 설정이다.

 

 

3) 연결확인

- spring boot 프로젝트, nuxt 프로젝트 둘다 run 시킴

- nuxt프로젝트 localhost:3000 뜨면 localhost:3000/api/helloWorld 주소창에 적고 엔터!

- 프론트 화면에 백단에서 보낸 Hello World 글자 보이는지 확인

 

5. jpa 연결

1) 데이터 바인딩

 데이터 바인딩 되어야될 페이지에 mounted로 걸어준다

<template>
...
 	<tr v-for="(row, idx) in list" :key="idx">
          <td>{{ row.idx }}</td>
          <td><a v-on:click="fnView(`${row.idx}`)">{{ row.title }}</a></td>
          <td>{{ row.author }}</td>
          <td>{{ row.created_at }}</td>
	</tr>
</template>

<script>
export default {
    data() { //변수생성
        return {
            requestBody: {}, //리스트 페이지 데이터전송
            list: {}, //리스트 데이터
        }
    },
    mounted() {
        this.getBoardList()
    },
    methods: {
        getBoardList() {
            this.requestBody = { // 데이터 전송
                keyword: this.keyword,
                page: this.page,
                size: this.size
            }

            this.$axios.get(this.$serverUrl + "/board/list", {
                params: this.requestBody,
                headers: {}
            }).then((res) => {
                this.list = res.data  //서버에서 데이터를 목록으로 보내므로 바로 할당하여 사용할 수 있다.
            }).catch((err) => {
                alert(err.message);
            })
        }
    }
}
</script>

 

 

2) back 서비스 만듦

@Override
    public List<BoardDto> getBoardList() {
        List<BoardDto> result = new ArrayList<>();
        List<Board> boardEntities = boardRepository.findAll();

        for (Board entity : boardEntities) {
            BoardDto dto = BoardDto.builder()
                    .idx(entity.getIdx())
                    .author(entity.getAuthor())
                    .title(entity.getTitle())
                    .contents(entity.getContents())
                    .createdAt(entity.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")))
                    .build();

            result.add(dto);
        }

        return result;
    }

 

3) back api 만듦

@RestController
@RequiredArgsConstructor
public class BoardController {

    private final BoardService boardService;

    @ResponseBody
    @GetMapping("/board/list")
    public List<BoardDto> boardList() {
        return boardService.getBoardList();
    }
 }

 

4) 데이터 연결 확인

nuxt / vue 다른점

 

vue : 만약 vue 였다면 이 상황에서 게시글 상세페이지를 보고싶을때, 새로운 vue 페이지만들고 라우터를 추가해야함

nuxt : 라우터추가안해도됨, pages에 넣어두면 url을 통한 이동은 바로 이동됨

ex)

이런식으로 pages에 index2.vue라는 파일을 생성하고 링크로 이동하면 해당페이지에 바로 접속된다.

별도로 사용할 conponents는 해당폴더에 따로 만들어두고 사용하면됨

 

 

 

 

참고 url : https://onethejay.tistory.com/64, https://minu0807.tistory.com/65

728x90

'FrontEnd > Nuxt' 카테고리의 다른 글

nuxt js 페이지 이동, 레이아웃  (0) 2023.05.09
반응형

아래와 같은 관계도가 있는 테이블이 있다.

 

위에 그림 두개는 DB 관계도, 아래의 이미지는 자바단 부모 @Entity 쪽 @OneToMany 설정이다.

 

원래는 LAZY를 쓰고싶지만 회사 ..사정상 EAGER를 쓰고있다.

 

 

편의상 OP_REGULAR_ROUND => OP_ROUND

OP_USER_REGULAR_ROUND -> OP_ROUND_ORDER 로 바꿔서 설명하겠다.

 

1. JPA N+1 이슈

 

내가원하는 SQL문은 아래와 같다.

SELECT RR.ROUND, OR.*
FROM OP_ROUND OR
         INNER JOIN OP_ROUND_ORDER RR ON OR.CODE = RR.CODE
WHERE OR.CODE = '1111'
ORDER BY RR.ROUND DESC;

조인을 하고 코드를 파라미터로 넘겨준다.

 

1) service와 같은 root 에 repository를 생성 - 나는 일단 impl 생성했다.

public interface RoundCustom {
    /**
     * 설명 ~~~~
     * @return
     */
    Round getDetail(String code);
}
import static saleson.model.QRound.round;
import static saleson.model.QRoundOrder.roundOrder;

@RequiredArgsConstructor
public class RoundCustomImpl implements RoundCustom{
    private final JPAQueryFactory jpaQueryFactory;

    @Override
    public Round getDetail(String roundCode) {
    }
}

querydsl에서 사용할 q클래스와 JPAQeuryFactory 를 선언해줬다.

 

그리고 리포지토리에 extends 추가해준다.

사실 커스텀안하고 별도 리포지토리를 생성하고 거기에 관리해도된다.

public interface RoundRepository extends JpaRepository<Round, Long>, QuerydslPredicateExecutor<Round>, RoundCustom {
    Optional<Round> findByCode(String code);
}

 

 

2) QUERY DSL를 사용 할 메소드 생성

다시 RoundCustomImpl에 돌아와서..

public Round getDetail(String code) {
    
    //builder 를 따로 뺀 이유는, 이후에 where 조건이 추가될수도 있기 때문입니다.
    BooleanBuilder builder = new BooleanBuilder();
    builder.and(round.code.eq(code));

    }

querydsl 생성에 앞서 먼저 builder 를 만들어준다. 

 

where 조건에 들어갈 부분을 넣으면 된다.

 

public Round getDetail(String code) {
    
    //builder 를 따로 뺀 이유는, 이후에 where 조건이 추가될수도 있기 때문입니다.
    BooleanBuilder builder = new BooleanBuilder();
    builder.and(round.code.eq(code));

    return jpaQueryFactory
            .select(round)
            .from(round)
            .innerJoin(round.list,roundOrder) //oneToMany
            .fetchJoin()
            .where(builder)
            .orderBy(roundOrder.round.desc())
            .fetchOne();
    }

이게 완성된 로직인데, innerjoin에 들어가는 파라미터는, 부모@Entity에 @OneToMany로 걸려있는 변수를, 뒤에는 조인할 q클래스명을 입력해줬다.

 

이렇게 돌리면

select regularrou0_.ID                         as id1_47_0_,
       userregula1_.ID                         as id1_60_1_,
       regularrou0_.CREATED                    as created2_47_0_,
       regularrou0_.CREATED_BY                 as created_3_47_0_,
       regularrou0_.UPDATED                    as updated4_47_0_,
       regularrou0_.UPDATED_BY                 as updated_5_47_0_,
       regularrou0_.BUYER_EMAIL                as buyer_em6_47_0_,
       regularrou0_.BUYER_MOBILE               as buyer_mo7_47_0_,
       regularrou0_.BUYER_NAME                 as buyer_na8_47_0_,
       regularrou0_.CARD_NAME                  as card_nam9_47_0_,
       regularrou0_.INDEX_ROUND                as index_r10_47_0_,
       regularrou0_.ITEM_NAME                  as item_na11_47_0_,
       regularrou0_.ITEM_USER_CODE             as item_us12_47_0_,
       regularrou0_.RECEIVE_NAME               as receive13_47_0_,
       regularrou0_.REGULAR_ROUND_END_DATE     as regular14_47_0_,
       regularrou0_.REGULAR_ROUND_START_DATE   as regular15_47_0_,
       regularrou0_.STATUS                     as status16_47_0_,
       regularrou0_.TOTAL_ROUND                as total_r17_47_0_,
       regularrou0_.USER_ID                    as user_id18_47_0_,
       regularrou0_.USER_REGULAR_CARD_ID       as user_re19_47_0_,
       regularrou0_.USER_REGULAR_ROUND_CODE    as user_re20_47_0_,
       userregula1_.CREATED                    as created2_60_1_,
       userregula1_.CREATED_BY                 as created_3_60_1_,
       userregula1_.UPDATED                    as updated4_60_1_,
       userregula1_.UPDATED_BY                 as updated_5_60_1_,
       userregula1_.DISCOUNT_RATE              as discount6_60_1_,
       userregula1_.FAIL_COUNT                 as fail_cou7_60_1_,
       userregula1_.ITEM_ID                    as item_id8_60_1_,
       userregula1_.ITEM_NAME                  as item_nam9_60_1_,
       userregula1_.ITEM_SEQUENCE              as item_se10_60_1_,
       userregula1_.ORDER_CODE                 as order_c11_60_1_,
       userregula1_.ORDER_DATE                 as order_d12_60_1_,
       userregula1_.ORDER_SEQUENCE             as order_s13_60_1_,
       userregula1_.ORDER_STATUS               as order_s14_60_1_,
       userregula1_.PAY_AMOUNT                 as pay_amo15_60_1_,
       userregula1_.PAY_DATE                   as pay_dat16_60_1_,
       userregula1_.PAYMENT_INTERVAL           as payment17_60_1_,
       userregula1_.QUANTITY                   as quantit18_60_1_,
       userregula1_.ROUND                      as round19_60_1_,
       userregula1_.SHIPPING_CANCEL_END_DATE   as shippin20_60_1_,
       userregula1_.SHIPPING_CANCEL_START_DATE as shippin21_60_1_,
       userregula1_.SHIPPING_READY_END_DATE    as shippin22_60_1_,
       userregula1_.SHIPPING_READY_START_DATE  as shippin23_60_1_,
       userregula1_.USE_FLAG                   as use_fla24_60_1_,
       userregula1_.USER_DELIVERY_ID           as user_de25_60_1_,
       userregula1_.USER_ID                    as user_id26_60_1_,
       userregula1_.USER_REGULAR_CARD_ID       as user_re27_60_1_,
       userregula1_.USER_REGULAR_ROUND_CODE    as user_re28_60_1_,
       userregula1_.USER_REGULAR_ROUND_CODE    as user_re28_60_0__,
       userregula1_.ID                         as id1_60_0__
from OP_ROUND regularrou0_
         inner join OP_ROUND_ORDER userregula1_
                    on regularrou0_.CODE = userregula1_.code
where regularrou0_.CODE = '1111'
order by userregula1_.ROUND desc

 

이런식으로 내가원하던 조인문이 나온다.

 

 

이때 fetchJoin을 안쓰면

select regularrou0_.ID                       as id1_47_,
       regularrou0_.CREATED                  as created2_47_,
       regularrou0_.CREATED_BY               as created_3_47_,
       regularrou0_.UPDATED                  as updated4_47_,
       regularrou0_.UPDATED_BY               as updated_5_47_,
       regularrou0_.BUYER_EMAIL              as buyer_em6_47_,
       regularrou0_.BUYER_MOBILE             as buyer_mo7_47_,
       regularrou0_.BUYER_NAME               as buyer_na8_47_,
       regularrou0_.CARD_NAME                as card_nam9_47_,
       regularrou0_.INDEX_ROUND              as index_r10_47_,
       regularrou0_.ITEM_NAME                as item_na11_47_,
       regularrou0_.ITEM_USER_CODE           as item_us12_47_,
       regularrou0_.RECEIVE_NAME             as receive13_47_,
       regularrou0_.REGULAR_ROUND_END_DATE   as regular14_47_,
       regularrou0_.REGULAR_ROUND_START_DATE as regular15_47_,
       regularrou0_.STATUS                   as status16_47_,
       regularrou0_.TOTAL_ROUND              as total_r17_47_,
       regularrou0_.USER_ID                  as user_id18_47_,
       regularrou0_.USER_REGULAR_CARD_ID     as user_re19_47_,
       regularrou0_.USER_REGULAR_ROUND_CODE  as user_re20_47_
from OP_ROUND regularrou0_
         inner join OP_ROUND_ORDER userregula1_
                    on (regularrou0_.CODE = userregula1_.CODE)
where regularrou0_.CODE = '1111'
order by userregula1_.ROUND desc;

select userregula0_.USER_REGULAR_ROUND_CODE    as user_re28_60_0_,
       userregula0_.ID                         as id1_60_0_,
       userregula0_.ID                         as id1_60_1_,
       userregula0_.CREATED                    as created2_60_1_,
       userregula0_.CREATED_BY                 as created_3_60_1_,
       userregula0_.UPDATED                    as updated4_60_1_,
       userregula0_.UPDATED_BY                 as updated_5_60_1_,
       userregula0_.DISCOUNT_RATE              as discount6_60_1_,
       userregula0_.FAIL_COUNT                 as fail_cou7_60_1_,
       userregula0_.ITEM_ID                    as item_id8_60_1_,
       userregula0_.ITEM_NAME                  as item_nam9_60_1_,
       userregula0_.ITEM_SEQUENCE              as item_se10_60_1_,
       userregula0_.ORDER_CODE                 as order_c11_60_1_,
       userregula0_.ORDER_DATE                 as order_d12_60_1_,
       userregula0_.ORDER_SEQUENCE             as order_s13_60_1_,
       userregula0_.ORDER_STATUS               as order_s14_60_1_,
       userregula0_.PAY_AMOUNT                 as pay_amo15_60_1_,
       userregula0_.PAY_DATE                   as pay_dat16_60_1_,
       userregula0_.PAYMENT_INTERVAL           as payment17_60_1_,
       userregula0_.QUANTITY                   as quantit18_60_1_,
       userregula0_.ROUND                      as round19_60_1_,
       userregula0_.SHIPPING_CANCEL_END_DATE   as shippin20_60_1_,
       userregula0_.SHIPPING_CANCEL_START_DATE as shippin21_60_1_,
       userregula0_.SHIPPING_READY_END_DATE    as shippin22_60_1_,
       userregula0_.SHIPPING_READY_START_DATE  as shippin23_60_1_,
       userregula0_.USE_FLAG                   as use_fla24_60_1_,
       userregula0_.USER_DELIVERY_ID           as user_de25_60_1_,
       userregula0_.USER_ID                    as user_id26_60_1_,
       userregula0_.USER_REGULAR_CARD_ID       as user_re27_60_1_,
       userregula0_.USER_REGULAR_ROUND_CODE    as user_re28_60_1_
from OP_ROUND_ORDER userregula0_
where userregula0_.CODE = 'R20230216100309';

 

이런식으로 두번나온다.

 

하지만 fetchJoin이 만사형통은 아니다.. 페이징은 쓸수없기에....

 

참고로 해당 sql문은 콘솔에서 확인할수있는데

이런식으로 쓱- 보고 지나가기 쉽다. 하지만 꼭 작업할때 긁어서 실제로 sql문을 육안으로 확인해보는 습관을 길러야한다.

 

2. querydsl 결과를 특정 DTO에 리턴, 서브쿼리받는법

 

내가 받고싶은 sql문

select RR.USER_ID,
       RR.USER_REGULAR_ROUND_CODE,
       RR.ITEM_NAME,
       RR.REGULAR_ROUND_START_DATE,
       RR.TOTAL_ROUND,
       RR.BUYER_NAME,
       RR.CREATED,
       min(OURR.PAY_DATE),
       min(OURR.PAYMENT_INTERVAL),
       OURR.SHIPPING_READY_START_DATE
from OP_ROUND RR
inner join OP_ROUND_ORDER OURR
        on RR.CODE = OURR.CODE
where OURR.ORDER_CODE is null
  and RR.CODE = (select CODE
                  from OP_ROUND_ORDER
                  where ORDER_CODE = '2222')

 

특정 결과만 dto에 리턴받고싶을때

 

@Override
    public dtoA method2(String orderCode){

		//서브쿼리에 넣을 where 절
        BooleanBuilder subBuilder = new BooleanBuilder();
        subBuilder.and(roundOrder.orderCode.eq(orderCode));

		//메인쿼리에 넣을 where 절
        BooleanBuilder builder = new BooleanBuilder();
        builder.and(roundOrder.orderCode.isNull());
        builder.and(round.code.eq(
                JPAExpressions.select(roundOrder.code)
                        .from(roundOrder)
                        .where(subBuilder)
        ));

        return jpaQueryFactory
                .select(Projections.constructor(dtoA.class,
                        round.userId,
                        round.userRegularRoundCode,
                        round.itemName,
                        round.regularRoundStartDate,
                        round.totalRound,
                        round.buyerName,
                        round.created,
                        roundOrder.payDate.min(),
                        roundOrder.paymentInterval.min())) //그룹함수는 여기서
                .from(round)
                .join(round.list,roundOrder)
                .where(builder)
                .fetchOne();
    }

서브쿼리는 JPAExpressions 를 사용해서 조인시킨다.

역시 이때도 where 조건이 많아지면 너무 산만하기때문에 상단에 따로 선언하고 사용하였다.

 

Projections.contructor 사용하면 dto로 받을수있다.

첫 파라미터에 리턴받고싶은 dto 클래스를 추가하고 뒤에는 전부 내가받고싶은 컬럼명 나열한다.

 

이때 해당 dto에 해당 컬럼을 받는 생성자가 선언되어있어야한다.

그룹함수는 select할때 바로 쓰면된다.

 

728x90

+ Recent posts