본문 바로가기
Spring/DB 2편

데이터 접근 기술 - 활용 방안

by JHyun0302 2023. 8. 11.
728x90

스프링 데이터 JPA 예제와 트레이드 오프

 

 

클래스 의존 관계

 

 

고민

  • 구조를 맞추기 위해서, 중간에 어댑터가 들어가면서 전체 구조가 너무 복잡해지고 사용하는 클래스도 많아지는 단점이 생겼다.
  • 실제 이 코드를 구현해야하는 개발자 입장에서 보면 중간에 어댑터도 만들고, 실제 코드까지 만들어야 하는 불편함이 생긴다.
  •  DI, OCP 원칙을 지킬 수 있다는 좋은 점이 분명히 있다.
  • 하지만 구조가 복잡해지면서 어댑터 코드와 실제 코드까지 함께 유지보수 해야 하는 어려움도 발생한다.

 

 

 

 

다른 선택

  • ItemService 코드를 일부 고쳐서 직접 스프링 데이터 JPA를 사용하는 방법이다.
  • DI, OCP 원칙을 포기하는 대신에, 복잡한 어댑터를 제거하고, 구조를 단순하게 가져갈 수 있는 장점이 있다.

 

 

 

클래스 의존 관계

 

 

 

트레이드 오프

  • DI, OCP를 지키기 위해 어댑터를 도입하고, 더 많은 코드를 유지(구조의 안전성)
  • 어댑터를 제거하고 구조를 단순하게 가져가지만, DI, OCP를 포기하고, ItemService 코드를 직접 변경(단순한 구조&개발의 편리성)

 

  • 개발을 할 때는 항상 자원이 무한한 것이 아니다.
  • 어설픈 추상화는 오히려 독이 되는 경우도 많다. 추상화도 비용이 든다! 인터페이스도 비용이 든다!
  • 비용이란 유지보수 관점에서 비용을 뜻한다. 이 추상화 비용을 넘어설 만큼 효과가 있을 때 추상화를 도입하는 것이 실용적

 

 

 

 

 

 


실용적인 구조

 

 

복잡한 쿼리 분리

 

  • 기본 CRUD와 단순 조회는 스프링 데이터 JPA가 담당
  •  복잡한 조회 쿼리는 Querydsl이 담당

 

 

 

ItemRepository (Spring Data JPA)

public interface ItemRepositoryV2 extends JpaRepository<Item, Long> {
}

 

 

 

ItemQueryRepository(Querydsl)

@Repository
public class ItemQueryRepositoryV2 {
    
    private final JPAQueryFactory query;
    
    public ItemQueryRepositoryV2(EntityManager em) {
    	this.query = new JPAQueryFactory(em);
    }
    
    public List<Item> findAll(ItemSearchCond cond) {
    	return query.select(item)
                    .from(item)
                    .where(
                        maxPrice(cond.getMaxPrice()),
                        likeItemName(cond.getItemName()))
                    .fetch();
    }
    
    private BooleanExpression likeItemName(String itemName) {
        if (StringUtils.hasText(itemName)) {
        	return item.itemName.like("%" + itemName + "%");
        }
    	return null;
    }
    
    private BooleanExpression maxPrice(Integer maxPrice) {
        if (maxPrice != null) {
        	return item.price.loe(maxPrice);
        }
        return null;
    }
}

 

 

 

 

 

 

 

 

 

 


다양한 데이터 접근 기술 조합

 

 

  • JPA, 스프링 데이터 JPA, Querydsl을 기본으로 사용
  • 만약 복잡한 쿼리를 써야 하는데, 해결이 잘 안되면 해당 부분에는 JdbcTemplate이나 MyBatis를 함께 사용

 

 

 

 

 트랜잭션 매니저 선택

  • JPA, 스프링 데이터 JPA, Querydsl은 JPA 기술을 사용하므로 트랜잭션 매니저로 JpaTransactionManager 를 선택
  • JdbcTemplate , MyBatis JDBC를 직접 사용하기 때문에 DataSourceTransactionManager 를 사용
  • JpaTransactionManager 는 놀랍게도 DataSourceTransactionManager 가 제공하는 기능도 대부분 제공
  • JpaTransactionManager 를 하나만 스프링 빈에 등록하면, JPA, JdbcTemplate, MyBatis 모두를 하나의 트랜잭션으로 묶어서 사용 가능하다.

 

 

 

※ 주의점

☆ JPAJdbcTemplate을 함께 사용할 경우 JPA의 플러시 타이밍에 주의

JPA는 데이터를 변경하면 변경 사항을 즉시 데이터베이스에 반영하지 않는다.

 

 

 

반응형

'Spring > DB 2편' 카테고리의 다른 글

스프링 트랜잭션 전파1 - 기본  (0) 2023.08.11
스프링 트랜잭션 이해  (0) 2023.08.11
데이터 접근 기술 - Querydsl  (0) 2023.08.11
데이터 접근 기술 - 스프링 데이터 JPA  (0) 2023.08.11
데이터 접근 기술 - JPA  (0) 2023.08.10