🚩 1. 리포지토리 인터페이스(Repository Interface)로 데이터 베이스 액세스 재사용 실현하기
📌 1-1. 인터페이스 정의
- 공통 리포지토리 인터페이스를 정의
- 이 인터페이스는 애플리케이션의 데이터 액세스 로직을 추상화하며, 메소드 시그니처를 제공
public interface MemberRepository {
Member save(Member member);
Optional<Member> findById(Long id);
// ... 기타 메소드들
}
📌 1-2. JDBC 구현
- MemberRepository 인터페이스를 확장하여 JDBC를 사용하는 구현체를 작성
public class JdbcMemberRepository implements MemberRepository {
// ... JDBC를 사용하여 MemberRepository 인터페이스의 메소드들을 구현
}
📌 1-3. JdbcTemplate 구현
- MemberRepository 인터페이스를 확장하여 JdbcTemplate를 사용하는 구현체를 작성
public class JdbcTemplateMemberRepository implements MemberRepository {
// ... JdbcTemplate를 사용하여 MemberRepository 인터페이스의 메소드들을 구현
}
📌 1-4. JPA 구현
- MemberRepository 인터페이스를 확장하여 JPA를 사용하는 구현체를 작성
public class JpaMemberRepository implements MemberRepository {
// ... JPA를 사용하여 MemberRepository 인터페이스의 메소드들을 구현
}
📌 1-5. SpringDataJpa 구현
public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository {
// ... Spring Data JPA가 MemberRepository 인터페이스의 메소드들을 자동으로 구현
@Override
Optional<Member> findByName(String name);
}
📌 1-6. 스프링 빈 등록
- 각 구현체를 스프링 빈으로 등록하여 사용하려는 구현체를 선택할 수 있다.
@Configuration
public class SpringConfig {
private final DataSource dataSource;
private final EntityManager = em;
@Autowired
public SpringConfig(DataSource dataSource, EntityManager em) {
this.dataSource = dataSource;
this.em = em;
}
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
// 인터페이스를 통해 구현하여 확장했기 때문에 db엑세스 방법을 쉽게 변경할 수 있다.
// 사용할 인터페이스 구현체를 생성하여 반환하는 메소드를 빈으로 등록해준다.
// SpringDataJpa를 사용할 경우 이 메소드는 사용하지 않는다.
public MemberRepository memberRepository() {
// return new MemoryMemberRepository();
// return new JdbcMemberRepository(dataSource);
// return new JdbcTemplateMemberRepository(dataSource);
return new JpaMemberRepository(em);
}
}
❗SpringDataJpa를 사용할 경우(JpaRepository를 확장한 인터페이스), 자동으로 Bean으로 등록해주기 때문에 직접 구현체를 생성하고 반환하는 메소드를 @Bean으로 등록하는 과정을 생략할 수 있다.
@Configuration
public class SpringConfig {
private final MemberRepository memberRepository;
public SpringConfig(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Bean
public MemberService memberService() {
return new MemberService(memberRepository);
}
}
- MemberRepository 인터페이스를 확장하는 방법은 각기 다른 데이터 액세스 기술을 사용하는 여러 구현체를 제공할 수 있다.
- 또한, 애플리케이션의 데이터 액세스 로직을 유연하게 구성하고, 필요에 따라 다양한 데이터 액세스 기술을 쉽게 교체할 수 있게 해준다.