User 엔티티 수정 - 자신만에 정보를 참조 할 수 있다
package com.tenco.blog_v2.user;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import java.sql.Timestamp;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "user_tb")
@Builder
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(unique = true) // 유니크 제약 조건 설정
private String username;
private String password;
private String email;
// "USER", "ADMIN";
@Column(nullable = false)
private String role;
@CreationTimestamp // 엔티티 생성시 자동으로 현재 시간 입력
private Timestamp createdAt;
}
-- 사용자 데이터 삽입
INSERT INTO user_tb(username, password, email, role, created_at) VALUES('길동', '1234', 'a@nate.com', 'USER', NOW());
INSERT INTO user_tb(username, password, email, role, created_at) VALUES('둘리', '1234', 'b@nate.com', 'USER', NOW());
INSERT INTO user_tb(username, password, email, role, created_at) VALUES('마이콜', '1234', 'c@nate.com', 'ADMIN', 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', 2, NOW());
INSERT INTO board_tb(title, content, user_id, created_at) VALUES('제목4', '내용4', 3, NOW());
// "USER", "ADMIN"; @Column(nullable = true) private String role;
수정
package com.tenco.blog_v2.user;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import java.sql.Timestamp;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "user_tb")
@Builder
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(unique = true) // 유니크 제약 조건 설정
private String username;
private String password;
private String email;
// "USER", "ADMIN";
@Column(nullable = true)
private String role;
@CreationTimestamp // 엔티티 생성시 자동으로 현재 시간 입력
private Timestamp createdAt;
}
Board 수정
package com.tenco.blog_v2.board;
import com.tenco.blog_v2.user.User;
import jakarta.persistence.*;
import lombok.*;
import java.sql.Timestamp;
@NoArgsConstructor
@Entity
@Table(name = "board_tb")
@Getter
@Setter
public class Board {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // 기본키 전략 db 위임
private Integer id;
private String title;
private String content;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id")
private User user; // 게시글 작성자 정보
// created_at 컬럼과 매핑하며, 이 필드는 데이터 저장시 자동으로 설정 됨
@Column(name = "created_at", insertable = false, updatable = false)
private Timestamp createdAt;
@Builder
public Board(Integer id, String title, String content, User user, Timestamp createdAt) {
this.id = id;
this.title = title;
this.content = content;
this.user = user;
this.createdAt = createdAt;
}
}
수정
package com.tenco.blog_v2.board;
import com.tenco.blog_v2.common.errors.Exception403;
import com.tenco.blog_v2.user.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Slf4j
@RequiredArgsConstructor
@Controller
public class BoardController {
// 네이티브 쿼리 연습
private final BoardNativeRepository boardNativeRepository;
// JPA API , JPQL
private final BoardRepository boardRepository;
private final HttpSession session;
// 게시글 수정 요청 기능
// board/{id}/update
@PostMapping("/board/{id}/update")
public String update(@PathVariable(name = "id") Integer id, @ModelAttribute BoardDTO.UpdateDTO reqDto) {
// 1. 데이터 바인딩 방식 수정
// 2. 인증 검사 - 로그은 여부 판단
User sessionUser = (User) session.getAttribute("sessionUser");
if(sessionUser == null) {
return "redirect:/login-form";
}
// 3. 권한 체크 - 내 글이 맞니?
Board board = boardRepository.findById(id);
if(board == null) {
return "redirect:/"; // 게시글이 없다면 에러 페이지 추후 수정
}
if (!board.getUser().getId().equals(sessionUser.getId())) {
throw new Exception403("게시글을 수정할 권한이 없습니다.");
}
// 4. 유효성 검사 - 생략
// 5. 서비스 측 위임 (직접 구현) - 레파지토리 사용
boardRepository.updateByIdJPA(id, reqDto.getTitle(), reqDto.getContent());
// 6. 리다이렉트 처리
return "redirect:/board/" + id;
}
// 게시글 수정 화면 요청
// board/id/update
@GetMapping("/board/{id}/update-form")
public String updateForm(@PathVariable(name = "id") Integer id, HttpServletRequest request) {
// 1. 게시글 조회
Board board = boardRepository.findById(id);
// 2. 요청 속성에 조회한 게시글 속성 및 값 추가
request.setAttribute("board", board);
// 뷰 리졸브 - 템플릿 반환
return "board/update-form"; // src/main/resources/templates/board/update-form.mustache
}
// 주소설계 - http://localhost:8080/board/10/delete ( form 활용이기 때문에 delete 선언)
// form 태크에서는 GET, POST 방식만 지원하기 때문이다.
@PostMapping("/board/{id}/delete")
public String delete(@PathVariable(name = "id") Integer id) {
// 유효성, 인증검사
// 세션에서 로그인 사용자 정보 가져오기 -> 인증(로그인 여부) , 인가(권한 - 내글?)
User sessionUser = (User) session.getAttribute("sessionUser");
if (sessionUser == null) {
return "redirect:/login-form";
}
// 권한 체크 - 조회
Board board = boardRepository.findById(id);
if(board == null) {
return "redirect:/error-404";
}
if( ! board.getUser().getId().equals(sessionUser.getId())) {
throw new Exception403("게시글을 삭제할 권한이 없습니다.");
}
// 게시글 삭제
boardRepository.deleteById(id);
// boardNativeRepository.deleteById(id);
return "redirect:/";
}
// 특정 게시글 요청 화면
// 주소설계 - http://localhost:8080/board/1
@GetMapping("/board/{id}")
public String detail(@PathVariable(name = "id") Integer id, HttpServletRequest request) {
// JPA API 사용
//Board board = boardRepository.findById(id);
// JPQL FETCH join 사용
Board board = boardRepository.findByIdJoinUser(id);
User sessionUser = (User)session.getAttribute("sessionUser");
// 현재 로그인한 유저와 == 게시글 작성한 유저가 같아면
// isOwner = true, !isOwner = false
boolean isOwner = false;
if(sessionUser != null ) {
if(sessionUser.getId().equals(board.getUser().getId())) {
isOwner = true;
}
}
request.setAttribute("board", board);
request.setAttribute("isOwner", isOwner);
return "board/detail";
}
@GetMapping("/")
public String index(Model model) {
//List<Board> boardList = boardNativeRepository.findAll();
// 코드 수정
List<Board> boardList = boardRepository.findAll();
model.addAttribute("boardList", boardList);
return "index";
}
// 주소설계 - http://localhost:8080/board/save-form
// 게시글 작성 화면
@GetMapping("/board/save-form")
public String saveForm() {
return "board/save-form";
}
// 게시글 저장
// 주소설계 - http://localhost:8080/board/save
@PostMapping("/board/save")
public String save(@ModelAttribute BoardDTO.SaveDTO reqDto) {
User sessionUser = (User) session.getAttribute("sessionUser");
if(sessionUser == null) {
return "redirect:/login-form";
}
// 파라미터가 올바르게 전달 되었는지 확인
log.warn("save 실행: 제목={}, 내용={}", reqDto.getTitle(), reqDto.getContent());
// boardNativeRepository.save(title, content);
// SaveDTO 에서 toEntity 사용해서 Board 엔티로 변환하고 인수 값으로 User 정보 정보를 넣었다.
// 결국 Board 엔티티로 반환이 된다.
boardRepository.save(reqDto.toEntity(sessionUser));
return "redirect:/";
}
}
'Spring boot > 개념 공부' 카테고리의 다른 글
Service 레이어 만들기 (0) | 2024.11.08 |
---|---|
JPARepository란? (1) | 2024.10.20 |
인터셉터 만들어 보기 (0) | 2024.10.20 |
에러 컨트롤러 및 커스텀 익셉션 만들기 (0) | 2024.10.20 |
여러 페이지 만들기 (0) | 2024.10.20 |