본문 바로가기

국비과정/Spring

20230724 _[36일차]_01. Spring 게시판 글쓰기제한 (로그인)

* 재귀함수 - 내가 내 자신을 호출 

 

 

board 테이블 다시 생성해주자

회원가입한 사람의 번호 bwrite 를 나중에 int로 변경해줄예정, 일단 지금은 VARCHAR 타입

 

이제 board 게시판 클릭하면 연결된다

근데 글이 없어서 테이블헤드 (th) 만 뜸


글이 없으면 깔끔하게 '게시글이 없습니다' 멘트가 뜨도록 만들어보자

 

board.jsp 에 있는  list에 대해서

만약 list가 0이라면 table부분이 뜨지 않도록 해보자

 

아래 jstl functions 태그 추가 _ 코어태그 c 처럼 함수 사용가능 < c : ~~>

${ fn:length(list)  }  => list의 길이가 (0) 아래처럼 브라우저에 출력됨

 

 

choose, when, otherwise (코어태그의 if문) 사용해보자

조건식에는 부등호(>) 대신 gt (grater than) 사용

${fn:length(list) > 0 }    =>   ${fn:length(list) gt 0 }   

 

 

이제 다시 데이터를 입력해서

길이검사 : 1, '출력할 데이터가 있습니다' 를 출력시켜보자

 

아래 쿼리문 실행

INSERT INTO board (btitle, bcontent, bwrite)
VALUES ('첫번쨰 제목', '첫번째 내용입니다', 'PYO')

아래처럼 데이터생성됨

이제 list의 길이가 1이 되었으니

브라우저 확인해보면 아래처럼 출력 

 

 

이제 조건식에서 참일 때 테이블이 출력되도록 테이블 전체를 문구 대신 넣어줌!

아래처럼 글이 있다면 출력

 

데이터를 삭제해보면 (list 길이가 다시 0이 되면서) 아래처럼 데이터가 없다는 문구 출력

 

게시판에서 글쓰기 하고 저장해보면 오류가 뜬다 (db에 bip가 없음)

 

db에 데이터에 bip 필드추가 

 

이제 글을 쓰면 된다 (다른사람 게시판에도 글쓰기 됨)

 


이제 로그인한 사용자만 글쓰기 가능하게 만들어보자

다른사람 게시판에는 글을 못쓴다 (다른사람들 db에 내 id&pw가 없으니)

 

또, 지금까지는 글쓴이가 정해져있었는데 이제 회원번호가 글쓴이가 되도록 만들어주자

 

member 테이블의 기본키(m_no)를 board 테이블로 가져와서 writer 대신 m_no로 저장시켜줌

m_no는 외래키

 

board 테이블의 m_no와 member 테이블의 m_no를 맞춰준다는 의미


'UPDATE 될 때' 탭 설정에서 CASCADE 는?

예를 들어 board의 글이 삭제되었을 때 댓글들도 다 지워지게 하는 경우 사용

 


일단 지금은 NO ACTION으로 설정

외래키 설정 성공

 

board.jsp 에서도 

bwrite  =>  m_no로 바꿔주기

 

join으로 board 테이블과 members 테이블을 연결해주자

 

확인을 위해 데이터에 값 넣어줌.

 

 

아래 쿼리문 실행해보면 데이터 불러옴

 

SELECT board.bno, board.btitle, 
             members.m_name, board.bdate, board.blike,
             board.bip 
FROM board JOIN members 
ON board.m_no = members.m_no

쿼리문이 너무 길어. 줄여서 아래처럼 작성해도 잘 불러와짐 

 

SELECT b.bno, b.btitle, 
m.m_name, b.bdate, b.blike,
b.bip 
FROM board b JOIN members m 
ON b.m_no = m.m_no


이제 이 테이블들을 활용하기 위해 boardview 생성하자

 

CREATE VIEW boardview as
SELECT b.bno, b.btitle, 
             m.m_name, b.bdate, b.blike,
             b.bip 
FROM board b JOIN members m 
ON b.m_no = m.m_no
ORDER BY bno DESC LIMIT 10

그럼 이제 board-mapper 에서 쿼리문 수정

( view에서 이미  LIMIT 10개 설정되어 있으니 board-mapper 에서는 view의 데이터를 불러오기만 하면 됨)

resultType도 Map => boardDTO 로 변경해줌

 

boardController 에서는 수정할게 없으니 아래 boardList() 클릭해서 서비스로 이동


boardService 에서 list 타입을 dto로 바꿔줌


위에서 밑줄 클릭해서 BoardDAO에서의 list 타입도 dto로 바꿔줌


boardDTO에 있는 bwrite 라는 변수를 m_no수정해야되는데

다른 곳들의 모든 bwrite 를 m_no 로 바꾸려면 => alt + shift + R

위의 방법으로 바꿔줘도 되는데 그냥 getter/setter 를 다 지우고 다시 생성하는게 편함

 

 

일단 변수 m_no =>  m_name으로 바꿔주고 getter/setter 다시 생성

 

 

보드컨트롤러에서를 bwrite 변수 사용하던 부분을  bwrite => M_name 으로 변경해줌

 


근데 아직은 에러남

마지막으로 board.jsp에서 수정해줘야함

여기에서도 m_no로 불러오는데 이제 m_no 라는 변수가 없음

bwrite => m_name으로 변경

 

아직 에러뜬다

 

 

board-mapper 에서

이제 board 테이블에는 m_name 이 없으니

board => boardview 로 바꿔줌

 

detail.jsp에서도 bwrite => m_name으로 바꿔줌

 

boardview에는 bcontent 변수가 없어서 안뜸 => 추가해주자

 

컬럼명 찍어져 있는건 따옴표가 아니라 백틱(`) 임

일단 아래처럼 b.bcontent 원하는 위치에 써주고 저장 눌러주면 알아서 백틱(`) 달아줌

저장하면

 

이제 잘 불러와짐


이제 로그인 했을때만 글을 쓸 수 있도록 버튼을 숨겨주자

한번 테스트 해보자

 

로그인 전에는 글쓰기 버튼이 안보인다

로그인 성공하고 게시판 클릭해보면 아래처럼 출력된다 (로그인계정의 이름이 잘 불러와진다)


 

로그인 성공했다면 글쓰기 버튼보인다.

조건식 => (해당 계정정보가 세션에 담겨있을테니) 세션에서의 name값이 null이 아님

 


출력문 빼고 다시 정리해보면

로그인 성공했을때 게시판에 들어가보면 글쓰기 버튼 짜잔


로그인 안한 상태면 애초에 글쓰기 버튼이 없으니 글을 쓸수 없지만

주소창에서 write ~로 글쓰기 페이지 접근 가능

요 부분도 막아보자 (GetMapping 부분에서 수정필요)

 

BoardController 에서

 

@GetMapping("/write")
public String write(HttpSession session

요렇게 세션을 매개변수로 넣어줘도 되지만

 

일단은 매개변수로 request로 값을 넣고 session을 만들어주자

근데 아래처럼 메소드명이 겹치니까 두번째 write()메소드에는 2를 붙여주자

 

session에서 mname 뽑아왔을 때 

null이 아니면 로그인한상태 => 글쓰기 가능

null이면 로그인 안한 상태 => 로그인해 (로그인페이지로 이동) 

 

로그인 안한 상태면 애초에 글쓰기 버튼이 없으니 글을 쓸수 없지만

주소창에 /wrtie~ 입력해서 들어가면 가능.

위의 과정으로 로그인 안한 상태에서는 글을 쓸 수 없도록 확실하게 막아줬다

 

아래처럼 로그아웃한 상태에서(session의 mname값이 null인 상태) 주소창으로 접속해보면

 

로그인 페이지가 뜬다


로그인 하고 게시판에서 글쓰기 해보면 오류뜬다

 

boardController 에서 

요렇게 넣어주고 "홍길동2" 로 설정해줬던 글쓴이 부분도 아래처럼 세션의 mname을 가져오기

 

 

* 서브쿼리 : 쿼리문 속 쿼리 

SELECT *
FROM board 
WHERE M_no=
(SELECT m_no FROM members WHERE m_name='pororo');

 

> 괄호 먼저 실행하고 그 값은 M_no 에 넣어서 다시 쿼리문 실행

 

 

board-mapper에 쿼리문 수정해줌. (서브쿼리로 작동)

 

 

그런데 name은 중복일 수 있으니 유니크로 설정되어있는 id를 가져와보자 

컨트롤러에서부터 name을 id로 변경

 

mname => mid 로 변경

 

 

board-mapper 에서도

mname => mid 로 변경

위의 과정으로 로그인 안한 상태에서는 글을 쓸 수 없도록 확실하게 막아줬다


너무 헷갈리니까 그냥 boardDTO에 m_id 변수를 만들어서 사용하자

 

boardController 에서 name => id로 변경

border-mapper 에서도 name => id 로 변경

어쨋든 id는 유니크 설정된 값으로 중복될 일이 없어서 좀 더 안전!


이제 자기가 쓴 글만 수정 가능하게 만들어보자

로그인 성공했다면 (mid가 null이 아니라면)

로그아웃 된 상태에서는 (세션의 id값이 null이라면) 수정/삭제 버튼이 안뜨게 해줌

 

+ 로그인한 id와 글쓴이의 id가 다르다면 수정/삭제 버튼 안뜸

 

근데 일치해도 안뜬다 

뜨게 해주자

 

sessionScope.mid eq dto.m_id  => 요부분때문에

boardview에 m_id를 추가해줘야함

 

아래처럼 추가해주고 저장

그럼 이제 로그인한 id와 글쓴 사람 id가 같을때는 수정/삭제 버튼이 뜬다

 


컨트롤러에서 

요부분에서 잘못된 점은 이미 서비스에게 일을 시켰는데 

그 뒤에 mid라는 값을 dto에 붙여줘서 실행자체가 안됨

 

* 형변환 해주는 이유는 getAttribute() 메소드가 타입이 Object => String으로 형변환필요 

 

 

board-mapper 에서도 쿼리문 수정해주기 (아래부분 추가)

이제 내 글만 수정가능

 

 

아니야.....

컨트롤러에서부터 싹 갈아엎자.

 

BoardController 에서 

일단 dto 객체 만들자

bno값(수정 원하는 글번호)을 dto에 담아서 서비스에게 일을 시켜

서비스가 일를 해서 가져온 값은 result에 담아

위에서 dto 객체 타입에 오타남 

 

result로 받아올 detail메소드에 오류남 (서비스에서 detail() 메소드의 매개변수를 int로 설정해줬었음)

서비스에서 매개변수의 타입을 int => BoardDTO 로 바꿔주자

DAO에서도 int => BoardDTO 로 바꿔주자

 

(위에서 한 과정에서는 내 게시글을 나만 볼수 있음)

detail에서도 수정필요

edit 과정과 똑같지만 위에서는 id를 가져올 필요가 없으니 안가져온거.

 

아직 아래 오류가 뜨는데

mid가 없다고 뜬다..

 

board-mapper에서 

parameterType= "Integer" => "boardDTO"  로 변경해주기

 

지금 게시글 클릭해서 열어보면 오류가 나는건 맞음

현재 로그인된 id가 쓴 글을 (주소창에 입력해서)  들어가보면 바로 해당 글의 edit 페이지로 이동해야 하는데

언더바가 없어서 오류났었음...

아래처럼 입력해서 들어가면 edit 페이지로 들어가짐

m_id가 null이 아니라면 id를 가져와

null이면 id를 가져오지마 

다시말해서 detail에서 그냥 글만 열때는 m_id 값이 안오니까 실행이 안됨 

수정하기는 세개 다(id, no, content) 들어와야 하니까 if조건문 실행