@Transactional(readOnly=true)
읽기전용모드 => 속도up
문제:쓰기가안됨
해결:쓰기해야되는 메소드위에 @Transactional(readOnly=false)
package jpabook.jpashop.service;
import jpabook.jpashop.domain.Member;
import jpabook.jpashop.repository.MemberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service //component scan => 자동으로 스프링빈으로 등록해줘
@Transactional(readOnly = true) //JPA 데이터변경은 트랜잭션안에서해야. public Method에 적용됨. 읽기전용모드=>성능향상
public class MemberService {
@Autowired //자동주입해줘
private MemberRepository memberRepository;
//회원가입
@Transactional(readOnly = false) // 얘는 읽기전용아님.(기본값)
public Long join(Member member){
validateDuplicateMember(member); //중복회원검사
memberRepository.save(member);
return member.getId();
}
private void validateDuplicateMember(Member member) {
List<Member> findMembers = memberRepository.findByName(member.getName());
if(!findMembers.isEmpty()){
throw new IllegalStateException("이미 존재하는 회원입니다");
}
}
//회원 전체 조회
public List<Member> findMembers(){
return memberRepository.findAll();
}
public Member findOne(Long memberId){
return memberRepository.findOne(memberId);
}
}
*중복이름 검증
문제 : 멀티쓰레드에서 A, A 2명이 동시에 table등록함. -> 그시간에 검증통과함. -> ??
해결 : DB에 멤버이름에 unique 제약조건달아라.
* @Autowired
1. 필드주입
@Autowired //자동주입해줘
private MemberRepository memberRepository;
단점: 테스트시 변경불가, 접근불가
해결:Setter 인젝션
2.Setter 인젝션
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
단점 : app 동작후에는 이미 조립이 끝나기 때문에 바꿀일이 잘 없음.
3. 생성자 주입
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
장점 : main에서 new MemberService(파라미터 빠뜨리면) 하면 값넣어주라고 빨간줄 뜸.
팁 : 생성자1개 -> @Autowired 없어도 자동으로 달아줌.
4. 생성자 주입 + final field
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
장점 : 생성자 빠뜨리면(this.~~~) 빨간줄뜸
5. +
@RequiredArgsConstructor
장점 : final field 만 가지고 생성자 만들어줌.
기존코드:
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
최종코드 :
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
6. MemberRepository도 적용
@RequiredArgsConstructor
public class MemberRepository {
//@PersistenceContext //EntityManager만들어서 주입해줘
private final EntityManager em;
※ @Autowired field -> @PersistenceContext 자동 달아줌.
* 최종 MemberRepository
package jpabook.jpashop.repository;
import jpabook.jpashop.domain.Member;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
@Repository //component scan => 자동으로 스프링빈으로 등록해줘
@RequiredArgsConstructor
public class MemberRepository {
//@PersistenceContext //EntityManager만들어서 주입해줘
private final EntityManager em;
public void save(Member member){
em.persist(member); //JPA야 저장해줘.
}
public Member findOne(Long id){
Member member = em.find(Member.class, id); //(클래스, id(키))주면 알아서 JPA가 찾아줌
return member;
}
public List<Member> findAll(){
return em.createQuery("select m from Member m",Member.class).getResultList();
//(쿼리,반환타입)를 리스트로만들어줘
}
public List<Member> findByName(String name){
return em.createQuery("select m from Member m where m.name= :name",Member.class) //:name 은 파라미터바인딩
.setParameter("name",name)
.getResultList();
}
}
* 최종 MemberService
package jpabook.jpashop.service;
import jpabook.jpashop.domain.Member;
import jpabook.jpashop.repository.MemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service //component scan => 자동으로 스프링빈으로 등록해줘
@Transactional(readOnly = true) //JPA 데이터변경은 트랜잭션안에서해야. public Method에 적용됨. 읽기전용모드=>성능향상
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
//회원가입
@Transactional(readOnly = false) // 얘는 읽기전용아님.(기본값)
public Long join(Member member){
validateDuplicateMember(member); //중복회원검사
memberRepository.save(member);
return member.getId();
}
private void validateDuplicateMember(Member member) {
List<Member> findMembers = memberRepository.findByName(member.getName());
if(!findMembers.isEmpty()){
throw new IllegalStateException("이미 존재하는 회원입니다");
}
}
//회원 전체 조회
public List<Member> findMembers(){
return memberRepository.findAll();
}
public Member findOne(Long memberId){
return memberRepository.findOne(memberId);
}
}
'Java > Spring-app' 카테고리의 다른 글
상품 엔티티 개발 // setter없이 수정하는법 (0) | 2023.06.08 |
---|---|
회원 기능 테스트 (0) | 2023.06.07 |
회원 리포지토리 개발 (0) | 2023.06.06 |
엔티티 설계시 주의점 // Setter제거 (0) | 2023.06.06 |
엔티티 클래스 개발1 // JPA 어노테이션 (1) | 2023.06.06 |