Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- spring
- JPQL
- transaction
- Android
- AOP
- jpa
- QueryDSL
- Thymeleaf
- Servlet
- kotlin
- http
- java
- db
- Exception
- 그리디
- Greedy
- SpringBoot
- 자바
- 인프런
- springdatajpa
- 김영한
- pointcut
- Spring Boot
- 스프링
- 스프링 핵심 원리
- JDBC
- Proxy
- 백준
- 스프링 핵심 기능
- 알고리즘
Archives
- Today
- Total
개발자되기 프로젝트
회원 도메인 개발 본문
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
'Project > 블로그 게시판 만들기' 카테고리의 다른 글
게시글 도메인 개발 (0) | 2021.10.03 |
---|---|
게시글 도메인 설계 (0) | 2021.10.03 |
회원 도메인 설계 (0) | 2021.10.03 |
도메인 분석 설계 (0) | 2021.10.03 |
프로젝트 세팅 (0) | 2021.10.03 |
Comments