Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

회원 도메인 개발 본문

Project/블로그 게시판 만들기

회원 도메인 개발

Seung__ 2021. 10. 3. 16:50

1. Member.Class


import lombok.Getter;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity @Getter
public class Member {

    @Id
    @GeneratedValue
    private Long id;

    private String name;

    private String memberId; //회원이 로그인 시 사용하는 id

    private String password;

    private String email;

    public Member(String name, String memberId, String password, String email) {
        this.name = name;
        this.memberId = memberId;
        this.password = password;
        this.email = email;
    }

    public Member() {
    }

    public void changeName(String newName){
        this.name = newName;
    }

    public void changePassword(String newPassword){
        this.password=newPassword;
    }

    public void changeEmail(String newEmail){
        this.email = newEmail;
    }
}
  • 의도치 않은 data변경을 피하기 위해 @Setter를 사용하지 않고 각 필드를 변경하는 메서드를 추가함.

 

 

 

2. MemberJpaRepository


  • 순수 JPA 활용
  • 추후 SpringDataJPA로 변경 다형성 활용.
  • 회원 정보 수정은 merge를 활용하지 않고, Service계층에서 영속상태 entity를 변경하여 변경감지 활용.
  • @PersistenceContext를 사용하면 EntityManager 주입을 받을 수 있음.
/**
 * 순수Jpa 사용.
 */
@Repository
@RequiredArgsConstructor
public class MemberJpaRepository implements MemberRepository {

    @PersistenceContext
    private final EntityManager em;

    public Member save(Member member){
        em.persist(member);
        return member;
    }

    public Optional<Member> findMemberById(Long id){
        return Optional.ofNullable(em.find(Member.class, id));
    }

    public Optional<List<Member>> findMembersByName(String name){
        List<Member> results = em.createQuery("select m from Member m where m.name = :name", Member.class)
                .setParameter("name", name)
                .getResultList();
        return Optional.ofNullable(results);
    }

    public List<Member> findAll(){
        return em.createQuery("select m from Member m", Member.class)
                .getResultList();
    }

    /**
     * update는 변경감지를 활용함.
     * 영속 상태인 entity는 Transaction안에서 변경이 일어나면 Transaction종료 시
     * 변경 내용 commit됨.
     */

    public void removeMember(Member member){
        em.remove(member);
    }

    public void removeById(Long id){
        em.remove(findMemberById(id));
    }

    public void clear(){
        em.clear();
    }
}

 

3. MemberSeriveImpl


  • @Transactional : 모든 data변경은 Transaction 안에서 이루어 져야 한다.
  • readOnly=true : 기본적으로 읽기 설정으로 하고, save 등 조회 기능이 아닌 메서드만 별도 지정.
  • 추후 다형성 활용을 위해 Service계층에서 Repository interface를 참조함.
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberServiceImpl implements MemberService{

    private final MemberRepository memberRepository;

    @Autowired
    public MemberServiceImpl(MemberJpaRepository memberJpaRepository) {
        this.memberRepository = memberJpaRepository;
    }

    @Override
    @Transactional
    public Member joinMember(Member member) {
       return memberRepository.save(member);
    }

    @Transactional
    public void saveMember(Member member){
        memberRepository.save(member);
    }

    @Override
    public Member findMemberById(Long memberId) {
        Member findMember = memberRepository.findMemberById(memberId).orElse(new Member());
        return findMember;
    }

    @Override
    public Member findMemberByName(String memberName) {
        return memberRepository.findMemberByName(memberName).orElse(new Member());
    }

    @Override
    public void updateMember(Long id, Member memberParam) {
        Member findMember = findMemberById(id);
        updateFindMember(memberParam, findMember);
        saveMember(findMember);
    }

    @Override
    public void removeMember(Long memberId) {
        memberRepository.removeById(memberId);
    }

    @Override
    public void clearRepository() {
        memberRepository.clear();
    }

    private void updateFindMember(Member memberParam, Member findMember) {
        findMember.changeName(memberParam.getName());
        findMember.changePassword(memberParam.getPassword());
        findMember.changeEmail(memberParam.getEmail());
    }
}

 

 

4. MemberRepository Test


  • repository 각 기능을 test
  • @Transactional을 적용하면 각 테스트 종료 후 data rollback이 된다.
  • 각 테스트는 독립적이어야 한다. 따라서 각 테스트 전/후에 사용할 data 입력, clear를 해준다.
@Transactional
@SpringBootTest
class MemberJpaRepositoryTest {

    @Autowired MemberJpaRepository jpaRepository;

    @Test
    void saveTest(){
        //given
        Member member = createMember();
        
        //when
        Member savedMember = jpaRepository.save(member);

        //then
        assertThat(savedMember.getId()).isEqualTo(member.getId());
        assertThat(savedMember.getMemberId()).isEqualTo(member.getMemberId());
        assertThat(savedMember.getPassword()).isEqualTo(member.getPassword());
        assertThat(savedMember.getName()).isEqualTo(member.getName());
        assertThat(savedMember.getEmail()).isEqualTo(member.getEmail());
    }

    @Test
    void findByNameTest(){
        //given, when
        Member member = jpaRepository.findMemberByName("testMember2").orElse(new Member());
        
        //then
        assertThat(member.getName()).isEqualTo("testMember2");
    }

    @Test
    @Rollback(value = false)
    void findByIdTest() {
        //given
        Long id = jpaRepository.findMemberByName("testMember2").orElse(new Member()).getId();
        
        //when
        Member findMember = jpaRepository.findMemberById(id).orElse(new Member());
        
        //then
        assertThat(findMember.getId()).isEqualTo(id);
    }

    @Test
    void findByNameNoResult(){
        assertThrows(NoSuchElementException.class, () ->jpaRepository.findMemberByName("noName").get());
    }

    @Test
    void findAllTest(){
        //given, when
        List<Member> all = jpaRepository.findAll();
        
        //then
        assertThat(all.size()).isEqualTo(4);
    }

    @Test
    void dirtyCheckingTest(){
        
        //givem
        Long id = jpaRepository.findMemberByName("testMember2").orElse(new Member()).getId();
        Member member = jpaRepository.findMemberById(id).orElse(new Member());
        
        //when
        member.changeName("changedName");
        jpaRepository.save(member);
        Member findMember = jpaRepository.findMemberById(id).orElse(new Member());
        
        //then
        assertThat(findMember.getName()).isEqualTo("changedName");

    }

    
    @BeforeEach
    public void beforeTest(){
        jpaRepository.save(new Member("testMember1", "abc1", "123456!", "123@naver.com"));
        jpaRepository.save(new Member("testMember2", "abc2", "123456!", "123@naver.com"));
        jpaRepository.save(new Member("testMember2", "abc3", "123456!", "123@naver.com"));
        jpaRepository.save(new Member("testMember3", "abc4", "123456!", "123@naver.com"));
    }

    @AfterEach
    public void clear(){
        jpaRepository.clear();
    }

    public Member createMember(){
        return new Member("testMember", "abc123", "123456!", "123@naver.com");
    }
}

 

 

5. GitHub : 211003 MemberDomain


 

GitHub - bsh6463/blog

Contribute to bsh6463/blog development by creating an account on GitHub.

github.com

 

'Project > 블로그 게시판 만들기' 카테고리의 다른 글

게시글 도메인 개발  (0) 2021.10.03
게시글 도메인 설계  (0) 2021.10.03
회원 도메인 설계  (0) 2021.10.03
도메인 분석 설계  (0) 2021.10.03
프로젝트 세팅  (0) 2021.10.03
Comments