본문 바로가기

전체 글

매핑정보 상속 매핑정보 상속(@MappedSuperClass) 객체에 공통매핑 정보가 필요할떄 사용된다. 상속관계를 매핑할수 없다. 직접 생성해서 사용할일이 없으므로 추상클래스(abstract class)를 사용한다. @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public abstract class TimeStamped { @CreatedDate //Entity가 생성되어 저장될 때 시간이 자동 저장 private LocalDateTime createdAt; @LastModifiedDate //조회한 Entity의 값을 변경할 때 시간이 자동 저장 private LocalDateTime modifiedAt; } 더보기
상속관계 매핑 상속관계 매핑 관계형 데이터베이스의 슈퍼타입 서브타입 관계 모델링 기법이 객체상속과 유사하다. 상속관계 매핑은 객체의 상속과 구조와 DB의 슈퍼타입 서브타입 관계를 매핑한다. 어노테이션 @Inheritance(strategy=InheritanceType.XXX) JOINED:조인전략 SINGLE_TABLE:단일 테이블 전략 TABLE_PER_CLASS:구현 클래스마다 테이블 전략 @DiscriminatorColumn(name=“DTYPE”) 부모클래스에 선언하고 하위 클래스를 구분하는 용도의 컬럼인 DTYPE을 추가한다. @DiscriminatorValue(“XXX”) 하위클래스에 선언하고 엔티티를 저장할 때 슈퍼타입의 DTYPE에 저장할 값을 지정한다. default:클래스 이름 방법 (1)각각 테이블.. 더보기
연관관계 매핑 연관관계의 주인(mapped by) (1) 연관관계의 주인만이 외래키를 관리(등록, 수정 등) (2) 주인이 아닌 쪽은 읽기만 가능 (3) 주인 mapped by 속성을 사용하지 않고 주인이 아니면 mapped by 속성으로 지정 (4) 외래 키가 있는 곳을 주인으로 정함 (5) 연관관계의 주인에다가 값을 넣지 않고 주인이 아닌 쪽에 값을 넣으면 DB에 반영되지 않는 실수 주의 (6) toString(), lombok, Json 생성 라이브러리를 쓸 경우 무한루프 고려 (7) 양방향으로 매핑 시 순수한 객체 관계를 고려하면 항상 양쪽 다 값을 입력해야 한다 -> 연관관계 편의 메서드 ex) team과 teamMember가 양방향 매핑 돼있을 시 다대일(N:1) 단방향 양방향 외래키가 있는 쪽이 주인이 된.. 더보기
Entity Mapping 객체와 테이블 매핑(@Entity,@Table) @Entity JPA를 사용해서 테이블과 매핑할 클래스는 @Entity 필수 기본 생성자 필수(파라미터가 없는 public or protected) 속성 name은 JPA에서 사용할 Entity이름을 지정할 수 있다.(기본값: 클래스 이름) @Table Entity와 매핑할 테이블을 지정한다. 속성 필드와 컬럼 매핑 매핑 어노테이션 @Column 속성 unique를 사용하여 제약조건을 걸 시 제약조건 이름이 랜덤값으로 나와 사용하지 않는 것이 좋다. @Table의 uniqueConstraints로 이름을 설정하는 것이 오류시 잡아내기 쉬움 @Enumerated ORDINAL 사용 시 Enum 클래스에 새로운 요소를 추가할 때 버그가 생길 수 있으니 STRI.. 더보기
영속성 컨텍스트의 이점 1차 캐시 private static void cache(EntityManagerFactory emf){ EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); try{ Member member = new Member("member1","1"); em.persist(member); // 1차 캐쉬에서 저장됨 Member findMember = em.find(Member.class, "member1"); // 1차캐쉬에서 조회 tx.commit(); }catch (Exception e){ tx.rollback(); }finally { em.close(); } } 영속성 콘텍스트의 .. 더보기
타임리프 문법 타임리프 사용 선언 속성 변경 th:href href="value1" 을 th:href="value2"의 값으로 변경한다. HTML을 그냥 볼때는 value1으로 뷰 템플릿을 거치게 되면 th의 href로 대체되면서 동적으로 변경 할 수 있다. URL 링크식 @{...} th:href="@{/basic/items/{itemId}(itemId=${item.id}, query='test')}" .타임리프에서 URL 링크를 사용하는 경우 @{...}를 사용한다. 경로 변수{item.id}뿐만 아니라 쿼리파라미터인 query도 쉽게 가능하다. 리터럴 대체문법 |...| 타임리프에서 문자와 표현식 등은 분리되어 있기 때문에 더해서 사용해야 한다. (1)리터럴 대체문법을 사용하지 않았을 때 th:onclick="'.. 더보기
RedirectAttributes RedirectAttributes @PostMapping("/add") public String addItemV6(Item item, RedirectAttributes redirectAttributes) { Item savedItem = itemRepository.save(item); redirectAttributes.addAttribute("itemId",savedItem.getId()); redirectAttributes.addAttribute("status",true); return "redirect:/basic/items/{itemId}"; } redirectAttributes에 Attribute를 추가하면 리다이렉트 주소에 PathVariable바인딩을 할 수 있다. 그리고 PathVariabl.. 더보기
PRG PRG 웹 브라우저의 새로고침은 마지막에 서버에 전송한 데이터를 다시 전송한다. 상품등록 폼에서 POST /add로 상품을 등록한 후 상품상세의 뷰 템플릿으로 이동하게 한 후 새로고침을 하게 되면 POST /add로 보냈던 상품 데이터가 한번 더 전송하게 되어 불 필요한 상품등록이 이루어진다. 위의 문제를 해결하기 위해서는 상품등록 폼에서 POST /add로 상품을 등록 한 후 뷰 템플릿으로 이동하는 것이 아니라 상품 상세화면으로 리다이렉트를 호출해 주면 된다. 이후 새로고침을 하면 마지막에 호출한 내용인 GET /items/{id}가 호출되어 위의 문제를 해결할 수 있다. 더보기