게시판 목록보기

Feb 01, 2024
게시판 목록보기

1. index.mustache 화면보기

  • 필요한 정보 : 제목, 내용
  • PK키, 외래키 : 작성자 확인 → 후에 상세 보기에 필요
notion image
 

2. Board 클래스에 board_tb 만들기

  • 데이터가 여러 건이라 스칼라로 테이블로 쪼개야함
💡
데이터베이스의 컬럼은 스칼라만 표현할 수 있기 때문
package shop.mtcoding.blog.board; import jakarta.persistence.*; import lombok.Data; import org.hibernate.annotations.CreationTimestamp; import java.time.LocalDateTime; @Data // getter, setter, toString 포함되어 있음 @Entity // 붙여야 테이블이 만들어지고 조회된게 해당객체로 파싱됨 @Table(name = "board_tb") public class Board { @Id //primary key @GeneratedValue(strategy = GenerationType.IDENTITY)// auto private int id; private String title; private String content; // 데이터가 여러건이라 테이블로 쪼개야함 private int userId; //카멜을 쓰면 언더스코어로 만들어줌 -> 외래키 @CreationTimestamp private LocalDateTime createdAt; }
notion image
notion image

3. GerationType

  • 아이덴티티(Identity)
: 기본 키의 값을 자동으로 생성하는 방식. 주로 MySQL, SQL Server, PostgreSQL 등에서 사용 아이덴티티 컬럼에 값을 삽입하지 않으면 데이터베이스가 자동으로 값을 생성
  • 오토(자동)
: 자동으로 값을 생성하는 의미
주로 Hibernate와 같은 ORM 프레임워크에서 사용
  • 시퀀스(Sequence): : 일련번호를 생성하는 객체
주로 Oracle에서 사용
각 시퀀스는 고유한 값을 가짐
시퀀스를 사용하려면 먼저 시퀀스를 생성
특정 테이블의 기본 키 컬럼에 이 시퀀스를 연결
  • 테이블(Table)
: 기본 키 값을 생성하는 방식
테이블에는 시퀀스 값을 저장하고 이를 사용하여 기본 키를 생성
주로 PostgreSQL에서 사용
 

4. 외래키에 제약 조건은 안 넣는게 좋음

ex) 쌀이라는 user 1번 게시글 두 개 작성
쌀이 회원 탈퇴할 때 row를 삭제하진 않음
스테이터스 같은 값을 만들어서 true) 활동 회원
false) 탈퇴 회원으로 관리해서 업데이트됨
→ 이때는 문제가 없음
5년이 지나서 진짜 데이터를 없앨 때
남아있는 두 개 데이터는 외래키가 걸려있어서 삭제가 안됨
  • 삭제 시) 케스케이드 (Cascade)옵션
연관 관계 설정을 해서 삭제되면 같이 삭제되게 만들기
  • 삭제 시) 외래키를 null로 만드는 설정을 해야 함
 

5. 더미 데이터 넣기

insert into user_tb(username, password, email, created_at) values('ssar', '1234', 'ssar@nate.com', now()); insert into user_tb(username, password, email, created_at) values('cos', '1234', 'cos@nate.com', now()); insert into board_tb(title, content, user_id, created_at) values('제목1','내용1', 1, now()); insert into board_tb(title, content, user_id, created_at) values('제목2','내용2', 1, now()); insert into board_tb(title, content, user_id, created_at) values('제목3','내용3', 1, now()); insert into board_tb(title, content, user_id, created_at) values('제목4','내용4', 2, now());
notion image
notion image
💡
화면에 안보여도 id는 반드시 가지고 가야 함
 
notion image
(1) 8080요청하면 ‘/’로 갈거임
(2) get 요청이라 유효 검사할 게 없음 / body가 없으니까
(3) DB가서 select로 보드 데이터 조회해서 가방(request)에 데이터를 담음
(4) 인덱스 페이지로 포워드해서 알아서 갈거임
포워드 : 서버가 클라이언트에게 응답을 전달하는 개념
(5) 가방을 들고 인덱스 mustache 로 가서
가방에 있는 데이터를 꺼내서 화면에 뿌리기만 하면 됨
 

5. DAO = Repository?

  • DAO (Data Access Object):
    • 역할 : 데이터 액세스 계층에서 데이터베이스와의 상호 작용을 담당
      특정 DB 테이블이나 엔터티에 대한 CRUD연산을 수행
      목적 : 데이터베이스와의 통신 및 데이터 액세스 로직을 캡슐화
      비즈니스 로직과 데이터 액세스 로직을 분리하여 유지보수성을 향상
  • 레포지토리 (Repository):
    • 역할 : 도메인 객체 또는 엔터티에 대한 데이터 액세스를 추상화하고 캡슐화
      도메인 레이어에서 데이터베이스와 직접 상호 작용하지 않도록 함
      목적 : 도메인 레이어를 데이터베이스와 분리
      도메인 레이어의 코드가 데이터베이스와 결합되지 않도록 함
      도메인 객체를 저장, 검색, 업데이트, 삭제하는 인터페이스를 제공
⇒ 스프링 프레임워크 등에서는 주로 레포지토리라는 용어를 사용
도메인 레이어와 데이터 액세스 계층 간의 인터페이스를 통일, 추상화하는 역할
예쁘게 화면에 뿌리려면 데이터를 잘 만드는 방법 : 조회를 잘하는것
package shop.mtcoding.blog.board; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; import java.util.List; @RequiredArgsConstructor @Repository public class BoardRepository { private final EntityManager em; // jpa가 제공해줌 // 조회니까 트랜잭션 필요없음 public List<Board> findAll() { // 보드 테이블의 모든 것 가지고 오기 Query query = em.createNativeQuery("select * from board_tb order by id desc", Board.class); System.out.println("BoardRepository에 findAll 메서드 호출됨"); return query.getResultList(); // 여러건 } // 이 결과를 리퀘스트에 담고 뷰 화면 가서 뿌리기 }
 

6. BoardController 에서 findAll() 실행하기

  • 쿼리 스트링 : 구체적 조회
package shop.mtcoding.blog.board; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpSession; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import shop.mtcoding.blog.user.User; import java.util.List; @RequiredArgsConstructor @Controller public class BoardController { // HttpSession 객체를 참조 private final HttpSession session; private final BoardRepository boardRepository; // DI @GetMapping({"/", "/board"}) public String index(HttpServletRequest request) { User sessionUser = (User) session.getAttribute("sessionUser"); if (sessionUser == null) { System.out.println("로그인 안된 상태입니다"); } else { System.out.println("로그인 된 상태입니다"); } List<Board> boardList = boardRepository.findAll(); request.setAttribute("boardList", boardList); // ("key", value) return "index"; } @GetMapping("/board/saveForm") public String saveForm() { return "board/saveForm"; } @GetMapping("/board/1") public String detail() { return "board/detail"; } }
notion image
notion image
  • 주소에 페이지를 안 넣으면 파싱이 안되서 터짐!
notion image
notion image
@RequestParam(defaultValue = "0") // 안 적으면 디폴트값 0으로 설정
notion image
expose-session-attributes: true expose-request-attributes: true // 머스테치에서 세션에 접근 허용

6. index.mustache에 가서 반복문으로 반복되게 만들기

  • title과 id는 그 데이터에 따라 동적으로 변하게 만들기
notion image
{{> layout/header}} <div class="container p-5"> {{#boardList}} <div class="card mb-3"> <div class="card-body"> <h4 class="card-title mb-3">{{title}}</h4> <a href="/board/{{id}}" class="btn btn-primary">상세보기</a> </div> </div> {{/boardList}} <ul class="pagination d-flex justify-content-center"> <li class="page-item disabled"><a class="page-link" href="#">Previous</a></li> <li class="page-item"><a class="page-link" href="#">Next</a></li> </ul> </div> {{> layout/footer}}
notion image
notion image
notion image
Share article
RSSPowered by inblog