3 분 소요



현재 글은 User Entity_(User) 개발 글의 뒷 내용을 이어갑니다.


👨‍💻 User CRUD 개발과정 순서

  1. Repository :

    데이터베이스에 접근하여 데이터를 다루는 기능을 담당하는 Repository를 먼저 구현.

  • JpaRepository를 추가함으로써 USER CRUD 기능을 쉽게 사용하게 함.
  • email로 user찾기 / username으로 user찾기 / id값에 해당하는 user찾기 메서드 추가.
  1. Entity :

데이터베이스의 테이블과 매핑되는 객체로, 테이블의 컬럼들과 매핑되는 필드를 가지고있음.

  • User
  • Reputation
  1. DTO :

데이터를 전송하기 위한 객체로, Entity와 비슷하지만 HTTP 요청과 응답에서 사용하는 데이터를 가지고 있음.

  1. Service :

비즈니스 로직을 처리하는 컴포넌트로, Repository를 사용하여 데이터를 조작하고, 비즈니스 로직에 맞게 데이터를 가공한다.

  1. Controller :

HTTP 요청을 처리하는 컴포넌트로, 클라이언트로부터 요청을 받아 Servcie에게 전달하고, Service가 처리한 결과를 다시 클라이언트에게 반환한다.

  1. Mapper :

Entity와 DTO 간의 변환을 담당하는 컴포넌트로, Entity를 DTO로 변환하거나, DTO를 Entity로 변환하는 등의 작업을 함




⭐ User Entity - Reputation 코드

@Entity
@Getter
@Setter
@NoArgsConstructor
@Table(name = "REPUTATIONS")
public class Reputation {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long reputationId;

    @OneToOne(mappedBy = "reputation")
    private User user; // 둘의 연관관계를 매핑함.

    @Column(nullable = false)
    private int amount = 1;  // 첫 시작시에 평판량 1로 초기화.


    public void setUser(User user){  // User 객체와 Reputation 객체의 양방향 참조하기 위한 메서드
        this.user = user;
        if (user.getReputation() != this){
            user.setReputation(this);
        }
    }

}


🔑 아래 코드에서 GenerationType는 어떤게 있을까?

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long reputationId;


JPA에서 ID값을 자동으로 생성하기 위해 사용하는 방법 중 하나인 GenerationType에는 다음과 같은 종류가 있습니다.

  1. GenerationType.IDENTITY: 데이터베이스의 Identity 컬럼을 이용하여 키를 생성합니다. MySQL, SQL Server, PostgreSQL 등에서 사용됩니다.
  2. GenerationType.SEQUENCE: 데이터베이스 시퀀스 오브젝트를 이용하여 키를 생성합니다. Oracle, PostgreSQL 등에서 사용됩니다.
  3. GenerationType.TABLE: 데이터베이스에 키 생성 전용 테이블을 만들어 키를 생성합니다.
  4. GenerationType.AUTO: 데이터베이스 방언에 따라 자동으로 IDENTITY, SEQUENCE, TABLE 중 하나를 선택합니다.

일반적으로 GenerationType.IDENTITY를 사용하는 경우가 많습니다. 위 예시에서는 GenerationType.IDENTITY를 사용하여 데이터베이스의 Identity 컬럼을 이용하여 reputationId를 생성하고 있습니다.




🔑 User과 연결

    @OneToOne(mappedBy = "reputation")
    private User user;

@OneToOne(mappedBy = "reputation")는 JPA에서 양방향 관계를 설정하기 위한 어노테이션 중 하나입니다.

여기서 UserReputation은 일대일 관계를 가지고 있습니다. UserReputation을 참조하고 있기 때문에 User쪽에서도 관계를 설정해야 합니다. 이때 mappedBy 속성을 사용하여 User 엔티티에서는 Reputation 엔티티에 대한 매핑 정보를 가지고 있지 않고, Reputation 엔티티에서 해당 관계가 어떤 필드에 의해 매핑되는지 지정합니다.

즉, 위 코드에서는 User 엔티티에서는 reputation 필드로 Reputation 엔티티와 매핑되어 있고, Reputation 엔티티에서는 user 필드로 User 엔티티와 매핑되어 있는 것입니다.




**+ 추가로 **

🔑 User 객체와 User객체가 참조하는 Reputation 객체 일치시키는 메서드 작성이 필요하다.

 public void setUser(User user) {
        this.user = user;
        if (user.getReputation() != this) {
            user.setReputation(this); }


위 메서드는 Reputation 엔티티 클래스의 user 필드를 세팅하는 역할을 합니다.

이때, user 필드와 Reputation 엔티티의 관계는 양방향 매핑이므로, user 필드가 변경될 때 Reputation 엔티티도 함께 업데이트 되어야 합니다. 따라서, setUser() 메소드에서는 먼저 user 필드를 받아와서 해당 필드를 세팅하고, user 필드의 reputation 필드가 현재 객체(this)와 같은지 확인합니다.

reputation 필드가 같은 경우에는 추가적인 작업이 필요하지 않습니다. 하지만 reputation 필드가 다른 경우, user 객체의 setReputation() 메소드를 호출하여 현재 객체(this)를 전달하여 두 객체 간의 관계를 매핑합니다. 이를 통해 양방향 매핑 관계가 유지됩니다.


그러면 해당 메서드는 언제 호출이 될까?

setUser() 메소드는 Reputation 객체가 생성되고 나서, 해당 객체의 user 필드에 대한 setter 메소드로서, 해당 객체가 생성된 후 언제든지 호출될 수 있습니다.

예를 들어, User 객체를 생성하고 그 객체에 대한 Reputation 객체를 생성한 후, setUser() 메소드를 호출하여 Reputation 객체의 user 필드를 설정할 수 있습니다. 또한, 이미 Reputation 객체의 user 필드가 설정되어 있는 경우에도 setUser() 메소드를 호출하여 해당 필드를 업데이트할 수 있습니다.

그리고 setUser() 메소드에서는, 입력받은 User 객체가 현재 Reputation 객체의 user 필드와 연관되어 있는지 검사하고, 만약 연관되어 있지 않다면 user 객체의 setReputation() 메소드를 호출하여 양방향 참조를 설정합니다. 이렇게 함으로써 Reputation 객체와 User 객체 간의 양방향 참조가 유지됩니다.


일반적으로 setUser 메소드는 개발자가 명시적으로 호출하는 것입니다. 이 메소드는 User 객체를 해당 Reputation 객체에 연결하기 위해 사용됩니다. 이를테면, 다음과 같은 상황에서 setUser 메소드가 호출될 수 있습니다:

  • 새로운 사용자가 등록될 때 Reputation 객체를 생성하고, 이 객체의 setUser 메소드를 호출하여 사용자와 연결합니다.
  • 기존 사용자의 평판 정보가 변경될 때 해당 사용자 객체의 setReputation 메소드를 호출하고, 이 메소드에서 setUser 메소드를 호출하여 새로운 평판 정보와 사용자를 연결합니다.

즉, setUser 메소드는 개발자가 필요에 따라 호출하는 메소드이며, 연결된 사용자 객체가 변경될 때 자동으로 호출되지는 않습니다.




🌟 Today I Learn

  • Reputation의 매핑시에 메서드가 필요한 이유:
User 객체와 Reputation 객체의 양방향 참조하기 위해서
  • Generation Type에는 어떤것이 있을까?

    GenerationType.IDENTITY:

    GenerationType.SEQUENCE

    GenerationType.TABLE

    GenerationType.AUTO


😚 오늘의 민이 수고했어 ^^ 🥰

댓글남기기