- 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라는 파일을 생성하고 링크로 이동하면 해당페이지에 바로 접속된다.
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 클래스를 추가하고 뒤에는 전부 내가받고싶은 컬럼명 나열한다.