4 분 소요



👨‍💻 User CRUD 개발과정 순서

  1. Repository :

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

    • JpaRepository를 추가함으로써 USER CRUD 기능을 쉽게 사용하게 함.~

    • email로 user찾기 / username으로 user찾기 / id값에 해당하는 user찾기 메서드 추가.

  2. Entity :

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

    • User
    • Reputation
  3. DTO :

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

  4. Service :

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

  5. Controller :

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

  6. Mapper :

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




📃 UserRepository

UserRepository 인터페이스에는 user 엔티티의 CRUD 기능을 수행하는 메소드가 포함되어야 한다.


⭐ User Repository 코드

public interface UserRepository extends JpaRepository <User, Long> {
    Optional<User> findByEmail(String email); //email로 user찾기

    Optional<User> findByUsername(String username); // username으로 user찾기

    Optional<User> findById(Long id); // 데이터에서 id값에 해당하는 사용자를 찾아 그 정보를 optional<user>로 감까서 전달하기.

}



  • 🔑 UserReposioty가 인터페이스인 이유:

User Repository가 인터페이스인 이유는 Spring Data JPA에서 인터페이스를 사용하여 Repository를 정의하는 것이 관례이기 때문입니다.

Spring Data JPA는 JpaRepository 인터페이스를 상속받는 인터페이스를 정의하면, 자동으로 해당 인터페이스에 필요한 구현체를 생성하여 Bean으로 등록해줍니다. 이를 통해 개발자는 구현체를 직접 작성할 필요 없이, 인터페이스의 메서드를 사용하여 데이터베이스에 접근할 수 있습니다.

또한, 인터페이스를 사용함으로써 구현체가 아닌 인터페이스에 의존하도록 설계함으로써, 의존성 역전 원칙(Dependency Inversion Principle)을 따를 수 있습니다. 이는 코드의 유연성을 높이고, 유지보수를 용이하게 할 수 있습니다.

따라서, User Repository도 인터페이스로 정의하여 Spring Data JPA가 제공하는 기능을 활용할 수 있도록 해야합니다.


  • Bean으로 등록 됐을시의 이점 :
  1. 의존성 주입이 가능해집니다.

Bean으로 등록된 객체는 Spring IoC 컨테이너에 등록되어 있기 때문에, 다른 Bean에서 해당 객체를 주입받아 사용할 수 있습니다. 이를 통해 객체 간의 의존성을 줄이고, 코드의 재사용성과 유지보수성을 높일 수 있습니다.

  1. 스프링 프레임워크에서 관리해주는 객체가 됩니다.

Bean으로 등록된 객체는 스프링 프레임워크에서 관리되는 객체가 됩니다. 이는 스프링의 다양한 기능을 활용할 수 있게 해주며, 객체의 생명주기 관리를 자동으로 처리해줍니다. 또한, 스프링의 AOP(Aspect Oriented Programming)를 활용하여 로깅, 보안 등의 공통적인 기능을 쉽게 구현할 수 있습니다.

  1. 스프링이 제공하는 다양한 어노테이션을 활용할 수 있습니다.

Bean으로 등록된 객체는 스프링이 제공하는 다양한 어노테이션을 활용할 수 있습니다. 예를 들어, @Autowired 어노테이션을 사용하여 의존성 주입을 수행하거나, @Transactional 어노테이션을 사용하여 트랜잭션 처리를 수행할 수 있습니다. 이를 통해 개발자는 간단하게 스프링의 다양한 기능을 활용할 수 있습니다.




->

-> 이제는

User Repoisoty에 JpaRepository를 사용하기위해서


Gradle에 의존성을 추가하자.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    // ...
}


이 의존성을 통해서 Spring Data JPA를 사용할 수 있게 된다.

이를 추가 함으로써 JpaRepoisoty에서 제공하는 데이터 조작 기능을 사용할 수 있다.


JpaRepository에서 제공하는 데이터 조작 기능

  1. CRUD 기능

    JpaRepository는 Entity의 CRUD(Create, Read, Update, Delete) 기능을 제공합니다. 즉, 데이터의 생성, 조회, 수정, 삭제를 위한 메소드들을 제공합니다. 예를 들어, save() 메소드를 이용하여 데이터를 생성하고, findById() 메소드를 이용하여 데이터를 조회할 수 있습니다.

  2. Query Method

    Query Method는 메소드 이름만으로 쿼리를 생성할 수 있게 해줍니다. 메소드 이름을 정해놓으면, 해당 이름에 맞게 쿼리가 자동으로 생성됩니다. 이를 이용하여, 보다 쉽게 쿼리를 작성할 수 있습니다.

  3. Paging 및 Sorting

    JpaRepository는 페이징과 소팅 기능을 제공합니다. findAll() 메소드를 이용하여 페이징 및 소팅 기능을 쉽게 적용할 수 있습니다.

  4. Batch 처리

    JpaRepository는 대용량 데이터를 처리하기 위한 Batch 처리 기능을 제공합니다. saveAll() 메소드를 이용하여 여러 개의 데이터를 한 번에 처리할 수 있습니다.

  5. Delete Query

    JpaRepository는 Delete Query를 이용하여 여러 개의 데이터를 한 번에 삭제할 수 있습니다. 이를 이용하여, 복수개의 데이터를 효과적으로 삭제할 수 있습니다.

  6. Named Parameter

    JpaRepository는 Named Parameter 기능을 제공합니다. Named Parameter를 이용하여, 쿼리에 매개 변수를 전달할 수 있습니다. 이를 이용하여, 쿼리를 작성할 때 매개 변수를 사용할 수 있습니다.



JpaRepository를 상속받는 인터페이스는 다음과 같이 제네릭으로 엔티티 타입과 ID 타입을 받아야 합니다.

public interface UserRepository extends JpaRepository<User, Long> {
    // ...
}

여기서 User는 조작할 엔티티 타입이고, Long은 해당 엔티티의 ID 타입입니다. 이렇게 제네릭으로 지정된 인터페이스를 구현하면, UserRepository에서 JpaRepository가 제공하는 메서드들을 사용할 수 있습니다.



  • 🔑 제네릭이 뭐야? :

제네릭(Generic)은 Java에서 클래스 또는 메소드를 정의할 때 타입(type)을 매개변수(parameter)화해서 사용하는 것을 말합니다. 이를 통해 클래스 또는 메소드를 타입에 따라 재사용할 수 있도록 만들어줍니다.

예를들어 ArrayList 클래스를 제네릭으로 정의해 보자. 이때 타입 매개변수로 <E>를 사용합니다. <E>는 Element의 약자로, 실제 사용될 타입으로 대체될 수 있습니다.

public class ArrayList<E> {
    // ...
}

제네릭으로 선언된 ArrayList 클래스는 실제 사용될 때 타입을 지정하여 객체를 생성할 수 있습니다.

ArrayList<String> stringList = new ArrayList<>();
ArrayList<Integer> intList = new ArrayList<>();

이렇게 생성된 객체는 선언된 타입과 일치하는 데이터만을 저장할 수 있습니다. 따라서 코드의 안정성과 가독성이 높아집니다.

즉 제네릭을 사용하면 타입 안정성을 보장할 수 있으며, 컴파일 시점에서 타입 체크가 이루어져서 런타임 오류를 줄일 수 있습니다. 또한, 타입 변환을 줄여서 코드의 가독성과 유지보수성을 높일 수 있습니다.



따라서 결과적으로 UserRepository 인터페이스의 코드는

public interface UserRepository extends JpaRepository<User, Long> {
    // ...
}

이런식으로 작성이 될것이고, Uswer은 조작할 엔티티 타입. Long은 해당 엔티티의 ID 타입을 지정하게 될 것이다. 이렇게 제네릭으로 인터페이스를 구현함으로써, UserRepository는 JpaRepository가 제공하는 메서드들을 사용할 수 있게 된다.



기존 CRUD 기능 외에기능을 메서드 안에 추가할 수도 있다.

  • 특정 사용자 검색 메서드: User findById(Long id), Optional<User> findByEmail(String email)
  • 사용자 목록 검색 메서드: List<User> findAll(), List<User> findByAgeGreaterThan(int age)
  • 사용자 생성 및 수정 메서드: User save(User user)
  • 사용자 삭제 메서드: void delete(User user), void deleteById(Long id)

이와 같이 UserRepository에서 제공하는 메서드들은 JpaRepository에서 이미 구현되어 있으므로, 별도로 구현할 필요가 없습니다. 단지, 필요한 메서드를 선언하기만 하면 됩니다. 이렇게 선언된 메서드들은 Spring Data JPA에서 자동으로 구현되어 사용할 수 있습니다.



// email로 User를 찾는 메소드

Optional<User> findByEmail(String email);

// username으로 User을 찾는 메소드

Optional<User> findByUsername(String username);

// 데이터에서 id값에 해당하는 사용자를 찾아 그 정보를 optional로 감까서 전달하기.

Optional<User> findById(Long id);


이정도를 추가했다.




🌟 What I Learn

  • UserRepository에 JpaRepository를 확장해 User 엔티티가 사용할 수 있는 CRUD기능을 손쉽게 추가할 수 있다.

  • 클래스 안에 개인적으로 추가하고 싶은 기능을 메서드로 추가할 수 있다. ex)

    Optional<User> findByEmail(String email);
    


다음 Entity 클래스 개발은 다음 포스팅으로 이어갑니다.



댓글남기기