본문 바로가기
개발/Spring

[Spring] Repository와 Service 구현하기

by tempus 2021. 10. 6.
반응형

이번에는 단순한 API를 만드는 것이 아닌 기기별 업데이트 버전을 관리할 수 있는 기능을 작업하게 되었습니다. DB를 새롭게 생성하고 필요한 Service와 Repository를 만들면서 추가적으로 공부했던 내용을 정리하려고 합니다.

 

기본적으로 Spring MVC에서 Repository와 Service의 역할은 다음과 같습니다.

  • Repository : DB에 접근하는 모든 코드들이 모여있습니다. (쿼리문들)
  • Service : 비즈니스 로직과 관련된 모든 코드가 모여있습니다.

 

Model 생성

Serivce와 Repository에서 사용할 모델을 미리 만들어줍니다. 모델은 여타 다른 프레임워크와 비슷한 구조를 갖고 있었습니다.

@Data
@Entity
@Table(name="User", schema = "default$default")
public class User {

    @Id
    String id;

    String name;
    String type;
    Integer year;
    
    @UpdateTimestamp
    Date updatedAt;

    @CreationTimestamp
    Date createdAt;
    
}

@Data 어노테이션을 통해서 @toString, @getter, @setter, @RequiredArgsConstructor, @EqualsAndHashCode을 한 번에 설정해줍니다.


@Entity, @Table을 통해서 DB 테이블과 클래스를 맵핑해줍니다. @Table의 name은 매핑할 테이블 이름을 지정해주고 schema는 DB 스키마와 맵핑을 해줍니다. 이때 @Id를 지정해주지 않으면 오류가 납니다.

 

  • @CreationTimestamp : INSERT시에 현재시간을 읽어서 저장하는 어노테이션
  • @UpdateTimestamp : UPDATE시에 현재시간을 읽어서 저장하는 어노테이션

 

JPA Repository 생성 및 Serivce 사용

JPA Repository를 만들 때는 JpaRepository<T, ID>를 상속받는 인터페이스를 만들어 주면 됩니다.


UserRepository.java

@Repository
public interface UserRepository extends JpaRepository<User, String> {
    @Query(value="SELECT " +
            "\"U\".* " +
            "FROM " +
            "\"default$default\".\"User\" AS \"U\" " +
            "WHERE \"U\".\"type\" = ?1 ", nativeQuery = true)
    List<User> findAllUserByType(String userType);
}

@Repository 어노테이션은 해당 클래스를 루트 컨테이너에 빈(Bean) 객체로 생성해주는 어노테이션입니다. 보통은 명시적으로 구분해주기 위해서 사용한다고 합니다.

 

그러면 해당 Repository는 Service에서 다음과 같이 사용하면 됩니다.


UserService.java

@Service
public class UserService {

    @Autowired
    UserRepository userRepository;
    
    @Transactional(readOnly = true)
    public List<User> getUserListByType(String type) {
		List<User> users = userRepository.findAllUserByType(type)
        
        /***
        	비즈니스 로직 구현 
        ***/
            
        return users
    }
    
}

readOnly = true로 설정하면 트랜잭션을 읽기 전용 모드로 설정할 수 있습니다. 이렇게 하면 읽기 전용 쿼리의 성능을 최적화할 수 있다고 하는데 찾아보니 readOnly = true를 사용하면 Spring 프레임워크가 Hibernate 세션 flush 모드를 MANUAL로 설정한다고 합니다.


이를 통해 flush를 호출하지 않게 되고 Dirty Checking을 하지 않기 때문에 성능상 이점을 얻을 수 있다고 합니다.

 

 

반응형

댓글


loading