타임리프 관련은 강의 내용에 있으니, 컨트롤러 부분만 정리해보았다. 홈 컨트롤러 등록 @Controller @Slf4j public class HomeController { @RequestMapping("/") public String home() { log.info("home controller"); return "home"; } } 회원 등록, 조회 회원 등록 폼 객체 폼 객체를 사용해서 화면 계층과 서비스 계층을 명확하게 분리하자. @Getter @Setter public class MemberForm { @NotEmpty(message = "회원 이름은 필수 입니다") private String name; private String city; private String street; private..
상품 도메인 기능 : 상품 등록, 목록 조회, 상품 수정 상품 도메인은 간단하니 생략하고 주문 도메인으로 넘어가보자. 주문 도메인 구현 기능 : 상품 주문, 주문 내역 조회, 주문 취소 주문 엔티티 @Entity @Getter @Setter @Table(name = "orders") public class Order { @Id @GeneratedValue @Column(name = "order_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) privat..
애플리케이션 아키텍처 계층형 구조 사용 controller, web: 웹 계층 service: 비즈니스 로직, 트랜잭션 처리 repository: JPA를 직접 사용하는 계층, 엔티티 매니저 사용 domain: 엔티티가 모여 있는 계층, 모든 계층에서 사용 패키지 구조 jpabook.jpashop domain exception repository service web 개발 순서: 서비스, 리포지토리 계층을 개발하고, 테스트 케이스를 작성해서 검증, 마지막에 웹 계층 적용 회원 리포지토리 @Repository @RequiredArgsConstructor public class MemberRepository { private final EntityManager em; public void save(Membe..
실제 동작하는 화면은 다음과 같다. 기능 목록 회원 - 등록, 조회 상품 - 등록, 수정, 조회 주문 - 주문, 주문 내역 조회, 주문 취소 기타 요구사항 상품은 재고 관리가 필요하다. 상품의 종류는 도서, 음반, 영화가 있다. 상품을 카테고리로 구분할 수 있다. 상품 주문시 배송 정보를 입력할 수 있다. 도메인 분석 설계 도메인 모델과 테이블 설계 도메인 모델 회원, 주문, 상품의 관계 : 회원은 여러 상품을 주문할 수 있다. 그리고 한 번 주문할 때 여러 상품을 선택할 수 있으므로 주문과 상품은 다대다 관계다. 따라서 그림처럼 주문상품이라는 엔티티를 추가해서 다대다 관계를 일대 다, 다대일 관계로 풀어냈다. 다만, 카테고리와 상품은 경험을 위해 다대다로 두었다. 상품 분류 : 도서, 음반, 영화는 상..
프로젝트 환경설정 https://start.spring.io/ Dependencies spring-boot-starter-web 톰캣, 스프링 웹 MVC 등 지원 spring-boot-starter-thymeleaf 뷰 단을 SSR로 제공하는 타임리프 템플릿 엔진 Spring-boot-starter-data-jpa aop, jdbc (HikariCP 커넥션 풀), 하이버네이트 , 스프링 데이터 jpa 등 지원 spring-boot-starter(공통) 스프링 부트 + 스프링 코어 + 로깅 등 지원 테스트 라이브러리 spring-boot-starter-test junit, mockito, assertj, spring-test 핵심 라이브러리 스프링 MVC 스프링 ORM JPA, 하이버네이트 스프링 데이터 ..
경로 표현식 .을 찍어 객체 그래프를 탐색하는 것을 경로 표현식이라고 한다. select m.username //상태 필드 from Member m join m.team t //단일 값 연관 필드 join m.orders o //컬렉션 값 연관 필드 where t.name = '팀A' 경로 표현식 용어 정리 상태 필드 : 단순히 값을 저장하기 위한 필드 (ex : m.username) 연관 필드 : 연관관계를 위한 필드 (단일 값, 컬렉션 값) 단일 값 연관 필드 : @ManyToOne, @OneToOne, 대상이 엔티티 (ex: m.team) 컬렉션 값 연관 필드 : @OneToMany, @ManyToMany, 대상이 컬렉션 (ex: m.orders) 경로 표현식 특징 상태 필드 경로 탐색의 끝으로 탐..
JPQL 소개 JPQL은 객체지향 쿼리 언어다. → 테이블을 대상으로 쿼리하는 것이 아닌, 엔티티 객체를 대상으로 쿼리 한다. 예시 비교 모델 Member 엔티티 @Entity public class Member { @Id @GeneratedValue private Long id; private String userName; private int age; @ManyToOne @JoinColumn(name = "TEAM_ID") private Team team; } Team 엔티티 @Entity public class Team { @Id @GeneratedValue private Long id; private String name; @OneToMany(mappedBy = "team") private..
JPA는 다양한 쿼리 방법을 지원한다. JPQL JPA Criteria QueryDSL 네이티브 SQL JDBC API 직접 사용, MyBatis, SpringJdbcTemplate 함께 사용 다양한 쿼리 방법 맛보기 우리가 배운 것 중에 가장 간단한 조회 방법은 EnfifyManager.find() 를 한 뒤, 객체 그래프를 탐색하는 방법이었다. (a.getB().getC()) 이때, 만약 나이가 18살 이상인 회원을 모두 검색하고 싶다면? JPQL을 사용해보자. JPA의 문제점 JPA를 사용하면 엔티티 객체를 중심으로 개발 문제는 검색 쿼리 : 검색을 할 때도 테이블이 아닌 엔티티 객체를 대상으로 검색해야 한다. 모든 DB 데이터를 객체로 변환해서 검색하는 것은 불가능하다. → 애플리케이션이 필요한 ..
1. 기본 값 타입 JPA의 데이터 타입 분류 엔티티 타입 @Entity로 정의하는 객체 데이터가 변해도 식별자로 지속해서 추적 가능. 예) 회원 entity의 키 값을 변경해도 식별자로 인식 가능 값 타입 int, Integer, String 처럼 단순히 값으로 사용하는 자바 기본 타입이나 객체 식별자 X → 변경시 추적 불가 값 타입 분류 기본 값 타입 : 자바 기본 타입, 래퍼 클래스(Integer, Long), String 임베디드 타입 : 복합 값 타입 컬렉션 값 타입 기본 값 타입 생명주기를 엔티티에 의존 : 회원 삭제 -> 그 안의 필드도 같이 삭제 값 타입은 공유 ❌ 📌Note : 자바의 기본 타입은 절대 공유 불가능 int, double 같은 primitive type은 공유가 불가능하다..
프록시 ❓Member를 조회할 때 Team도 함께 조회해야 할까? package hellojpa; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.EntityTransaction; import javax.persistence.Persistence; public class JpaMain { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em = emf.createEntit..