프로젝트/selfmade Blog - V2

5-1. 회원 기본 기능 구현 (Repository)

zangsu_ 2023. 9. 22. 20:00

가장 먼저 회원 정보를 DB에 저장해 두고, 회원 정보를 생성/조회/수정/삭제 하는 기능을 구현해 보자.

API 구성

대략적인 API 구성은 다음과 같이 계획했다.

회원 생성 기능은 입력 폼으로 데이터를 입력 받아서 Model로 전달 해 줄 것이기 때문에 path variable은 필요하지 않다.

회원 데이터는 일단 간단하게 이름과 아이디, 비밀번호 정도만 만들어 두자.

Repository

Model

가장 먼저, 앞으로 우리가 사용하게 될 유저 클래스를 만들어 주자.

@Entity  
@Table(name = "USERS")  
@Getter @Setter  
@NoArgsConstructor  
public class User {    
    @Id  
    @GeneratedValue    
    @Column(name = "IDX")  
    private Long idx;  
  
    @Column(name = "NAME")  
    private String userName;  
  
    @Column(name = "ID")  
    private String id;  
    
    @Column(name = "PASSWORD")  
    private String password;  
}


Repository

이어서, 데이터베이스에 직접 접근하는 DAO 객체를 만들어 주자.

@Repository  
public class UserDAO {  
  
    @PersistenceContext  
    private EntityManager em;  

    public long save(User user){  
        em.persist(user);  
        return user.getIdx();  
    }  

    public User find(long idx){  
        return em.find(User.class, idx);  
    }  
  
    //update는 영속성 컨텍스트가 유저를 관리하고 있다면 자동으로 더티체크를 진행해 주니 별도의 함수가 필요하진 않을 듯 하다.  
  
    public void delete(long idx){  
        User removeUser = em.find(User.class, idx);  
        em.remove(removeUser);  
    }  
}


EntityManagerFactory와 EntityManager를 직접 만드는 대신, 스프링이 직접 생성해 주는 EntityManager를 사용할 것이다.
이를 위해 EntityManager 객체에 @PersistenceContext를 사용해 준다.

이는 스프링의 Spring Data JPA 의존성을 추가해 주어야 가능하다.

영속성 컨텍스트가 관리하고 있는 모든 엔티티 객체는 변경사항에 대한 더티 체킹이 이루어 지기 때문에 update() 라는 함수를 DAO 계층에서 구현을 해 줄 필요가 없다.

Test 진행

@ExtendWith(SpringExtension.class)  
@SpringBootTest  
class UserDAOTest {    
    @Autowired  
    UserDAO userDAO;  
  
    User existingUser = new User("existing User", 
    "existing userID", "existing userPW");  
    long existingId;  
  
    @BeforeEach  
    public void prepareBasicUser(){  
        existingId = userDAO.save(existingUser);  
    }  
  
    @Test  
    @Transactional    
    public void saveTest() throws Exception{  
        //given  
        User user = new User("new User", "userID", "userPW");  
  
        //when  
        long savedId = userDAO.save(user);  
  
        //then  
        User findUser = userDAO.find(savedId);  
        checkUserSame(user, findUser);  
    }  
  
    @Test  
    @Transactional    
    public void findTest() throws Exception{  
        //given    
        //when        
        User findUser = userDAO.find(existingId);  
  
        //then  
        checkUserSame(existingUser, findUser);  
    }  
  
    @Test  
    @Transactional    
    public void deleteTeset() throws Exception{  
        //given  
        userDAO.delete(existingId);  
  
        //when  
        User findUser = userDAO.find(existingId);  
  
        //then  
        assertThat(findUser).isNull();  
    }  
      
    private void checkUserSame(User u1, User u2) {  
        assertThat(u1.getUserName())
        .isEqualTo(u2.getUserName());  
        assertThat(u1.getId())
        .isEqualTo(u2.getId());  
        assertThat(u1.getPassword())
        .isEqualTo(u2.getPassword());  
    }  
}

 

JUnit5에서는 @RunWith() 대신 @ExtendWith를 사용한다.
주의해야 할 점은, UserDAO 객체를 직접 new UserDAO() 생성자로 만들어 사용한다면 스프링이 만들어 주는 EntityManager 객체를 사용할 수 없기 때문에 꼭 미리 스프링이 생성해 준 UserDAO 빈을 주입받아 사용해야 한다.

 

테스트 성공!