프로그래밍과 잡담

개인적인 공부로 Vue.js + Spring boot + PostgreSQL 을 써보고 있다. 본문

잡담

개인적인 공부로 Vue.js + Spring boot + PostgreSQL 을 써보고 있다.

크레온 2021. 4. 23. 13:53

뭐 공부 삼아서 해보고 있는 중인데..

 

일단  프로젝트 구조는 아래와 같음.

 

Frontend : Vue.js, Node.js, VSCODE

Backend : java 11, Spring boot, jpa

DB: PostgreSQL  (사용한 이유는 그냥 기존의 mysql이나 오라클이 아닌걸로 해보고 싶었음 )

로그인은 JWT 토큰 인증 방식

 

목표는 답변형 게시판을 만드는 것이다. 웹하면 역시 답변 게시판 만들기가 제일 좋지 않겠음?

 

요즘에는 백앤드와 프론트앤드를 나눠서 개발을 한다고 하더라.. 그래서 공부삼아 해보는 중임..

 

Vue.js 를 쓴 이유는 별거 없음.. 그냥 최신거라 해보는거. 전 프로젝트때 vue를 잠깐 써봤는 괜찮은거 같더군.. 물론 그때는 프론트를 따로 한게 아니라 스크립트를 가져와서 처리한거라.

 

이번에는 다 나눠서 해봄.

 

일단 기존의 방식은 eclipse 내에서 다 하는 방식이었지.  서버 로직하며 화면 단도 다 한프로젝트 안에 들어가서 처리되는 방식이었는데.. 지금 방식은 뷰와 서버로직이 분리되니까 확실히 낫긴함.  java 는 오로지 서버 로직만 처리하면 되니까.  데이터는 API 만들어서 json 으로 던져주면 프론트에서 알아서 처리하면 되니까 말이지.

 

백와 프론트를 분리하는게 생기는 문제점이 CORS 같은 문제점이 있었다.

이게 뭐냐면 프론트는 localhost:8081을 사용하는 백앤드에게  localhost:8080/board/list 를 요청 할 경우에 브라우저에서 막아버림 ㅋ  물론 이 문제는 셋팅만 하면 금방 해결되는 문제라 크게 어렵지 않았음. 해결법은 쉬웠으나 해결법을 찾는건 쉽지 않았음.

 

백과 프론트가 따로 노니까 로그인과 같은 문제가 발생하게된다.  API는 말그대로 그냥 호출하고 데이터 받으면 서버와 연결이 끊어지니까.

 

그래서 인터넷에서 주워들은걸 활용해서 jwt 토큰이라는 걸 이용해서 로그인을 처리했다.

JWT 이 부분은 그냥 인테넷에서 복붙해서 만들음. ㅋ

이해를 못할 때는 그냥 복붙을 해서 쓰다보면 어느 순간 이해가 된다 ㅋ

 

이것도 단점이 있다고 함.  사용자가 로그아웃을 해도 생성된 토큰이 삭제되지 않는 다고 함. 그래서 듣기로는 db를 만들어 집어 놓고 그 토큰이 접근하면 접근 못하게 처리한다고 함.. 뭐 귀찮아서 구현은 안했는데 기억을 해둬야 겠음.

 

어찌어찌 해서 토큰 연동해서 쿠키에 저장하고 등등, 로그인이나 로그아웃 기능을 만들고 했음.

 

그리고 게시판 기능인데 뭐 사실 글쓰기, 글 삭제, 목록 보기, 페이징 처리는 다 쉽게 쉽게 됬음..  기존하고 크게 다를게 없거든.

 

이제 문제는 답변을 달았을 때 게시판 목록을 가져오는 데에서 문제가 발생함.

 

게시판이라는게 최근에 쓴 글이 맨위로 올라오는게 일반적이다.

 

문제는 PostgreSQL에 오라클 처럼 start with 나 connect by prior 같은 기능이 없다는데에 있음.

찾아보니 mysql도 없다고 함.

 

첫번째 시도는 With Recursive 를 이용해서 계층 구조를 만들 수 있다고 해서 시도 했는데..

 

계층으로 나오고 다 좋은데 말이야.. 순서가 옛날 글이 첫번째로 나옴 ㅋ

 

아래의 쿼리에 보다시피 order by 만 되면 바로 될거 같은데 안먹힘 ㅋ  존나 짜증.

 

WITH RECURSIVE getBoard(idx, parentIdx, title) as 
(
    select idx, parentIdx, title from board   -- 여기서 order by 가 안 먹힘 ㅅㅂ
    union all 
    ...
    ..
)

 

계속 구글을 찾아 봐도 딱히 해결법은 없고 함수를 써라 이런게 있어서 결국 함수로 처리함.

근데 이게 과연 맞는건지 모르겠다.

뭐 성능이야 페이징 처리가 되니까 크게 문제가 될거 같지는 않지만

나야 테스트 삼아서 하나의 게시판만 만든건데, 실제 서비스에서 게시판이 한두개가 아닐 거란 말이지.

답변형 게시판을 여러개 만들 경우에는 해당 함수를 여러 개를 만들어야 하는 불상사가 나올거 같은데 말이야.

 

 

답변형 게시판 목록을 가져오는 방식은 아래 처럼 만들었음.

 

1. 게시판과 구조가 같은 임시 게시판을 만들음.

  -  create temp table  temp_table as select * from board limit 0;

  - 이렇게 하면 데이터는 없고 구조만 같은 테이블 만들어짐 ㅋ

2. for문을 돌면서 답변글이 아닌 글을 가져와서 임시 테이블에 넣음

3. 해당 글의 답변이 있는지 찾음

  - 이건 재귀호출을 해야해서 따로 함수 만들음.

3.1 답변글 찾으면 그 데이터를 임시 테이블에 넣음

3.2 답변의 답변이 달릴수 있으므로 재귀호출함

4.  2~3 을 반복 하면 끝.

 

위와 같이 처리하면 우리가 보던 게시판 목록이 나오됨.

내가 만든 테스트 페이지 스크린샷 찍어봄..

 

어찌됬든 목표를 달성했음.  물론 세부적으로 다듬을 건 있겠지만 그건 나중에 해도 될 일이니까

 

만들면서 가장 골치 아픈 것들

  1. CORS

     - 처음해보는거라 셋팅을 이상하게 해서 그런지 상당히 많이 해맸음.

  2. 게시판 목록을 계층형으로 표시하기

    - 목록 표시 할려고 PostgreSQL 함수 만드는 방법 공부

    - 만든 함수를 Java spring jpa에서 호출하는 방법 찾는것

 

 

PostgreSQL 함수 만들면서 알아낸것들..

create or replace function boardlist() 
	returns setof RECORD AS
$$
	declare
  		r RECORD;
	begin
    	  cretea tmp table temp_table as select * from board limit 0;
          
		  for r in select * from board 
          	
          loop 
          	insert into temp_table values (r.*);  -- 이렇게 호출 하면 실행시 오류남.
            
          end loop;
    end;
$$

 

 

-- 해결법

create or replace function boardlist() 
	returns setof RECORD AS
$$
	declare
  		r board@rowtype;  -- 타입을 선언해줘야 row를 바로 입력 할 수 있음.
	begin
    	  cretea tmp table temp_table as select * from board limit 0;
		  for r in select * from board 
          	
          loop 
          	insert into temp_table values (r.*);  -- 이렇게 한 목적은 읽어 들인 row를 바로 테이블에 넣고 싶은거임.
            
          end loop;
    end;
$$
반응형
Comments