Java/Spring

JPA 기초

태감새 2023. 2. 4. 09:25

어플이 데이터베이스를 직접 다룰 때의 문제점


  1. 번거롭다
  2. SQL에 의존적이라 변경에 취약하다.
  3. 패러다임 불일치

패러다임 불일치

  • 관계 문제
    객체는 생성한 객체에서는 호출이 가능하지만 생성당한 객체는 생성한 객체를 호출하는 것이 불가능하다. 하지만 관계형 데이터베이스에서는 외래키를 이용해서 양방향으로 호출이 가능하다.

패러다임 불일치 참고


JPA

Java Persistence API : 자바 ORM 기술에 대한 표준 명세

(Object Relational Mapping) : 객체-관계 매핑

하는 일

  1. 쿼리를 자동으로 만들어줌
  2. sql 의존성을 줄여줌
  3. 패러다임 불일치 해결
  4. 특정 상황을 제외한 성능도 향상
  5. 방언 지원

더 이해하고 싶으면 영속성 컨텍스트를 공부해보자.

JPA sample

Member

@Entity // DB 테이블 역할을 합니다.
public class Member {     // H2는 User라는 엔티티명이 생성안됨.
        // ID가 자동으로 생성 및 증가합니다.
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    // nullable: null 허용 여부
    // unique: 중복 허용 여부 (false 일때 중복 허용)
    @Column(nullable = false, unique = true)
    private String username;

    @Column(nullable = false)
    private String password;

    @Column(nullable = false, unique = true)
    private String email;

    @Column(nullable = false)
    @Enumerated(value = EnumType.STRING)
    private UserRoleEnum role;

    @Column(unique = true)
    private Long kakaoId;

    // Food클래스의 메서드지만 이 내용이 없어서 추가 입력한 내용
    @OneToMany(mappedBy = "food", fetch = FetchType.EAGER)       
    // join에 사용한 food_id의 주인이 누구인지 지정.  
    private List<Orders> orders = new ArrayList<>();            
    // FetchType은 나중에 알려줌.
}

Orders

@Getter  // 자동으로 getter 메서드를 만들어줌. 개꿀이네 이거
@Entity  
@NoArgsConstructor  // 파라미터가 없는 기본 생성자를 생성해줌
public class Orders {  
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    private Long Id;  

    @ManyToOne  
    @JoinColumn(name = "food_id")       // Food 엔티티와 관계 설정
    private Food food;                  // food_id를 FK로

    @ManyToOne  
    @JoinColumn(name = "member_id")  
    private  Member member;  

    public Orders(Food food, Member member) {  
        this.food = food;  
        this.member = member;  
    }  
}

@Id : DB의 기본 키(PK)를 객체의 필드에 연결시켜주는 애너테이션
@GeneratedValue : @Id만 사용하면 기본 키를 직접 할당해야 하지만 @GeneratedValue를 사용하면 데이터베이스가 생성해주는 값을 사용한다. ()의 값은 다양한데 나중에 보는걸로.


DB 연관관계 이해

JPA는 결국 DB의 연관관계를 자바의 언어로 구성해주는 역할을 한다. DB의 연관관계를 이해해야지 JPA도 잘 작성할 수 있다.

음식 주문 테이블

회원 : 주문 = 1 : N
음식 : 주문 = 1 : N
회원 : 주문 = N : N

주문 테이블에는 여러 회원이 입력되고 음식도 입력된다. 이런 관계를 파악하는 것이 중요하다.

JPA에서의 표현

  • @OneToMany
  • @ManyToOne
  • @OneToOne
  • @ManyToMany

이름이 곧 내용이므로 설명은 생략한다.


의문점

결과적으로 Restaurant 클래스에서 FoodRepository, MemberRepository, OrderRepository 인터페이스를 이용해서 데이터를 저장한다.

  1. Repository들은 인터페이스인데 어떻게 객체를 생성해서 메서드를 사용하는가?
  2. 상속 받고있는 JpaRepository도 인터페이스인데 메서드의 구현부는 어디에 있는가?

위의 내용을 파고들려고 했으나 아직 스프링에 대한 지식이 부족해서 명쾌한 해답을 얻기는 힘들거라고 판단했다. 일단은 의문을 품고 넘어가자. 나중에 다시 보고 답을 찾자.

정리

관계 정리

DB에 엔티티를 만들려면 클래스를 하나 생성해서 @Entity 애너테이션을 붙여준다.
그리고 @Id로 DB에 기본 키값을 지정해주고 컬럼을 생성한다.
다른 엔티티와 관계(외래키)를 맺는 경우 @JoinColumn을 사용해서 관계를 형성한다.
1:1, M:1 같은 관계는 마찬가지로 애너테이션을 사용해서 설정한다.
완성된 엔티티 클래스를 담을 Repository 인터페이스를 만들고 JpaRepository<클래스,Id type>을 상속받아서 저장과 불러오기 기능을 활성화한다.
실제 사용 시 각 객체의 Repository 인터페이스를 구현해서 사용한다?

 

 

GitHub - gkstmdgus/study: 개인 공부 저장소

개인 공부 저장소. Contribute to gkstmdgus/study development by creating an account on GitHub.

github.com

 

'Java > Spring' 카테고리의 다른 글

SpringMVC (1) - WAS와 WebServer  (0) 2023.04.19
스프링 배치 이해하기  (0) 2023.04.18
애너테이션  (0) 2023.02.05
스프링 컨테이너  (0) 2023.02.05
Spring MVC  (0) 2023.02.04