13. 상세보기 ,게시글 설정

박선규's avatar
Jan 29, 2024
13. 상세보기 ,게시글 설정
📌
웹 서버의 겟 요청(select)
where절에서도 내가 어떤 컬럼을 정할 수 있는데 이때 unique한게 있음 (Pk나 Unique)
이럴 때 는 쿼리 스트링을 하지 않고 테이블/뒤에 바로 입력함
ex)/board/1 순으로 출력 됨
 
유니크한 페이지 클라이언트가 직접 db에게 질의하지 못하니 서버를 통해서 간다.
이게 웹 서버다.
스프링은 x-form만 파싱하는 법을 배움
 
 

@pathvariable

📌
@pathvariable:스트링타입을 int로 바꾸는 어노테이션 경로 변수를 표시하기 위해 메서드에 매개 변수에 사용된다. 경로 변수는 중괄호{id}로 둘러싸인 값을 나타낸다. URL 경로에서 변수 값을 추출하여 매개변수에 할당한다. 기본적으로 경로 변수는 반드시 값을 가져야 하며, 값이 없는 경우 404 오류가 발생한다. 주로 상세 조회, 수정, 삭제와 같은 작업에서 리소스 식별자로 사용된다. 결론:요청의 URL 경로에서 특정 부분을 추출하여 컨트롤러 메소드의 파라미터로 전달할 때 사용
pathvariavble 사용전
notion image
→ pathvariavble 사용 후
notion image
이렇게 1자리에 숫자 대신 id를 넣게되면 모든 받을 수 있는데

QLRM

notion image
notion image
gradel 돌릴때는 서버 끄고 하기
📌
QLRM= Query Language Result Mapping
  • 특정 쿼리 언어로 작성된 결과를 객체에 매핑하는 과정이다.
  • 사용하는 상황은 주로 복잡한 쿼리 혹은 특정한 데이터베이스 함수를 사용해야 할 때 발생한다.
  • QLRM 을 사용 할 때는 생성자(Constructor)가 필요하다.
  • Query문에 작성한 순서에 맞게 생성자를 만들어야 한다.
  • Entity의 경우 자동 파싱이 가능한데 join할 경우 Entity가 아니여서 object가아니다.
 
☝🏻
QLRM을 사용하기 위해서는 아래의 조건을 지켜야 한다!
  1. 쿼리문 순서대로 한다.
  1. DTO의 순서를 쿼리문에 맞춘다.
  1. 풀 생성자를 만든다.
→ 프로그램이 실행될 때 순서에 맞추기 위해서 조건을 지키는 것이다.
  • 사용 코드
notion image
 
Entity 의 역할을 jpaResultMAPPER가 대신해줌
jpaResultMAPPER를 사용하면
notion image
//쿼리를 적을 때 * 안하고 필요한 칼럼 직접 적기
package shop.mtcoding.blog.board; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; import lombok.RequiredArgsConstructor; import org.qlrm.mapper.JpaResultMapper; import org.springframework.stereotype.Repository; import java.math.BigInteger; import java.util.List; @RequiredArgsConstructor @Repository public class BoardRepository { private final EntityManager em; public List<Board> findAll(int page){ final int COUNT = 3; int value = page*3; Query query = em.createNativeQuery("select * from board_tb order by id desc limit ?,?", Board.class); query.setParameter(1, value); query.setParameter(2, COUNT); List<Board> boardList = query.getResultList(); return boardList; } public int count(){ Query query = em.createNativeQuery("select count(*) from board_tb"); Long count = (Long) query.getSingleResult(); return count.intValue(); } public BoardResponse.DetailDTO finById(int id) { //Entity가 아닌것은 JPA가 파싱안해준다.(Entity가 아닌 이유는? Join) //쿼리를 적을 때 * 안하고 필요한 칼럼 직접 적기 Query query = em.createNativeQuery("select bt.id, bt.title, bt.content, bt.created_at, bt.user_id , ut.username from board_tb bt inner join user_tb ut on bt.user_id = ut.id where bt.id = ?"); query.setParameter(1, id); JpaResultMapper rm= new JpaResultMapper(); // 조인하면 담을 클래스가 없을 때 BoardResponse.DetailDTO responseDTO = rm.uniqueResult(query, BoardResponse.DetailDTO.class); return responseDTO; } }
notion image
package shop.mtcoding.blog.board; import lombok.AllArgsConstructor; import lombok.Data; import java.sql.Timestamp; public class BoardResponse { //bt.id, bt.content, bt.title, bt.created_at, ut.id uid, ut.username @AllArgsConstructor @Data //쿼리 순서랑 똑같이 해야된다. public static class DetailDTO{ private Integer id; private String title; private String content; private Timestamp createdAt; private Integer userId; private String username; } }
 
 

로그인 안 했으면 수정 삭제 버튼 안 보이게
내가 쓴 글이 아니면 안 보이게
notion image
세션 id 가
게시물아이디=user.id
 

Mustache를 활용하여 게시물별 작성자 이름 출력

  • Mustache에 존재하는 문법을 활용 하였으니 꼭 참고하자! (index)
    • <div class="d-flex justify-content-end mt-2"> <!--키 값까지 같이 적어줘야 뭔지 찾을 수 있다. 키를 통해서 값을 찾는 법--> <b>작성자</b> : {{board.username}} </div>

게시글 수정 삭제 버튼 사용자에 맞춰 출력

  • Mustache에 boolen을 사용하여 하면 간단하게 가능하다.
  • 사용한 코드
    • BoardController
      • @GetMapping("/board/{id}") public String detail(@PathVariable int id, HttpServletRequest request) { BoardResponse.DetailDTO responseDTO = boardRepository.findById(id); request.setAttribute("board", responseDTO); // 1 ~ 3. 권한 체크 -> 권한 실패 시 403을 터트림 (다른건 인증체크도 존재한다) // 1. 해당 페이지의 주인 여부 boolean owner = false; // 2. 작성자 userId 확인하기 -> Request에 저장된 데이터가 Response에 저장 되니깐 가져온다. int boardUserId = responseDTO.getUserId(); // 3. 로그인 여부 체크 -> session 에서 가져오기 User sessionUserId = (User) session.getAttribute("sessionUser"); if (sessionUserId != null) { // null이 아니면 로그인 된 것 if (boardUserId == sessionUserId.getId()) { // 작성자와 로그인된 아이디가 동일한지 확인 owner = true; } } request.setAttribute("owner", owner); return "board/detail"; }
    • index
      • {{#owner}} <!-- 수정삭제버튼 --> <div class="d-flex justify-content-end"> <button class="btn btn-warning me-1">수정</button> <button class="btn btn-danger">삭제</button> </div> {{/owner}}
 
머스테치는 문법 지원 안하는 이유가 머스테치 페이지에서 코드가 복잡하는 걸 방지하기 위해서
그래서 코드는 외부에서 짜서 와야됨.
 
권한 체크에서 실패하면 (403)
인증체크와 권한체크
 
 
 
 
Share article
RSSPowered by inblog