Skip to content

[JPA study 6주차 이해림]

Haerim Lee edited this page May 17, 2024 · 1 revision

SECTION 7

(1) 홈 화면과 레이아웃

return 'home'; -> home.html로 찾아가서 타임 리프 파일을 찾아가게 됨.

home.html
<head th:replace="fragments/header :: header">
//인클루하는 것. 실제 렌더링될 때 바꿔치기 하는 것.

thymeleaf의 layout에 방문을 하게 되면 더 많은 방법을 알 수 있음 인클루드 스타일, 계층형 스타일 등등 우리는 지금 인클루드 스타일의 방법을 쓰고 있음 이는 무식하다고 할 수 있음 계속 인클루드를 해줘야 하기에 (코드의 중복) 강사님이 추천하는 방법은 코드의 중복을 없애기 위해 실무에선 Hierarchical(계층형) 스타일 layout 원하는 부분의 데이터만 파일로 만들면 되는 스타일임.

build.gradle

implementation 'org.springframework.boot:spring-boot-devtools' // 기본적으로 띄우면 started 메인으로 띄게 됨. 개발할 때 기본적으로 다 cache을 안 해서 변경하고 리컴파일하면 바로 바뀌는 것을 알 수 있음.

get.bootstrap

(2) 회원 등록

    @NotEmpty(message = "")
    private String name;
//이름은 필수로 받는 다는 것, 그 외는 필수가 아님.
    public String createForm(Model model) {
        model.addAttribute("memberForm", new MemberForm());
    }
//데이터를 옮길 때 모델이 실어서 옮김.

createMemberForm.html th -> thymeleaf 문법

    public String create (MemberForm memberForm) {
        
    }
//MemberForm.java를 Validation 가능 @Valid도 추가해주면 JAVAX의 어노테이션을 바로 쓸 수 있음

@Valid BindingResult result // 오류가 담겨서 다음 코드가 실행이 됨.

만약 다른 도시, 거리, 우편번호는 적고 이름만 없다면 다른 것들은 데이터베이스로 이동함. 이유는 MemberForm Form으로 이미 받았기 때문. 근데 바로 member 엔티티를 넣지 왜 form을 넣지? 라는 의문을 가질 수 있는데 화면의 벨리데이션과 도메인의 벨리데이션이 보기와는 다를 수 있기에 안 맞을 경우가 있음 그래서 form을 만들고 하는 것임. (실무에서도 이럼. 바로 member 엔티티를 넣는 경우는 없음)

(3) 회원 목록 조회

    @GetMapping("/members")
    public String list(Model model) {
        List<Member> members = memberService.findMembers();
        model.addAttribute("members", members);
        return "members/memberList";
    }
//모델로 받아 넘김. 명확하게 담기는 객체를 잘 참조할 수 있도록 변수를 받아 넘기는 스타일.

실무에선 엔티티는 핵심 비즈니스 로직만 가지고 있고 화면 로직은 없어야 함. 그런 건 dto에서 사용해야 함. controller를 보면 등록은 form인데 엔티티를 뿌릴 땐 멤버임 이거는 강사님이 엔티티를 손 안 댈려고 한 것이지 실무에선 dto를 꼭 사용할 것!

주의 API를 만들 떄는 절대 엔티티를 외부로 반환해서는 안됨, 엔티티는 스펙임 만약 외부로 나가면 노출이 됨. 즉 두 가지의 큰 문제가 생기는데

  1. 패스워드가 그대로 노출
  2. 스펙이 변함 (불안정한 api)

(4) 상품 등록

private Long id; //상품 수정도 만들 것이기에 id값을 받을 거임.

(5) 상품 목록

    @GetMapping("/items")
    public String list(Model model) {
        List<Item> items = itemService.findItems();
        model.addAttribute("items", items);
        return "items/itemList";
    }
//model에 담아놓고 담아놓은 items를 그대로 뿌림.

(6) 상품 수정

상품 목록 페이지에서 수정 버튼을 누르면 상품 수정 창으로 이동

데이터 수정이 꽤나 중요! 본인들 만의 스타일로 머지를 쓰는 사람들이 많은데 jpa 스타일은 변경감지를 쓰는 것!

@GetMapping("/items/{itemId}/edit")
주소가 변경될  있기에 PathVariable

    public String updateItemForm(@PathVariable("itemId") Long itemId, Model model) {
        Book item = (Book) itemService.findOne(itemId);
//업데이트 된 상품을 수정할 것이고 하나 씩 수정 할 것임.
    @PostMapping("/items/{itemId}/edit")
    public String updateItem(@ModelAttribute("form") BookForm form)
//오브젝트에서 잡은 이름을 그대로 넘어오게 해줌.

폼에서 넘어올 때 아이디가 조작되어서 넘어오는지 취약점을 보완할 것이 있어야 함 예를 들어 유저가 아이템에 대한 권한이 있는 지에 대한 로직 또는 업데이터를 섹션 객체에 담아두는 방법도 있는데 이것은 별로 안 씀.

아이템 서비스에서 세이브하면 북 엔티티가 넘어감 세이브 호출하면 또 아이템 리포지토리를 호출하는데 아이템의 아이디가 null이 아닌 상황에서는 디비에서 수정할 목적을 가지고 불러 온 것이기에 머지가 호출이 되는데 다음 시간에 설명,,,

Clone this wiki locally