티스토리 뷰
TIL 20220722 (Builder 수정 불가, @Repository, python manage.py migrate --run-syncdb)
바랄 희 2022. 7. 23. 11:55Builder 패턴의 단점, 수정 불가
Builder 패턴을 이용하면 setter보다 안전하고 불변성을 보장한다는 단점이 있다. 그러나 이는 실제 개발에 있어서 오히려 장애물이 될 수 있다는 피드백을 받았다. 이와 관련해서 찾아보니, 실제 개발에서는 빌더패턴을 적용하는 일이 흔치 않다고 한다.
객체를 생성한 후 수정해야 하는 경우가 있다면 어차피 setter 와 builder 를 모두 사용하게 되기 때문에 builder 패턴이 의미가 없어질 수도 있다. 따라서 상황에 맞게 알맞는 패턴을 사용하는 것이 답이라는 결론을 얻었다.
자바 빌더 패턴 (Java Builder Pattern) 장단점
우선, 빌더 패턴과 비교되는 패턴이 두 가지가 있어요. 두 가지 패턴은 용어만 거창하지 이미 알고 계실거에요. 점층적 생성자 패턴 : 생성자로 필드를 세팅, ex) new UserInfo(userId, password); 자바빈
gofnrk.tistory.com
@Repository
엔티티의 CRUD 를 위해서 JpaRepository 인터페이스가 존재한다. 이에 대한 상속만으로도 save(), findOne(), findAll(), count(), delete() 기능을 제공할 수 있게 된다.
@Repository
public interface ItemRepository extends JpaRepository<Item,Long> {
List<Item> findByName(String name);
}
extends JpaRepository<엔티티클래스, ID의 값> 의 형태이다.
기본적으로 제공되는 기능 외의 기능을 원한다면 규칙에 맞게 메서드를 추가하면 된다.
규칙은 다음과 같다.
1. findBy로 시작 -> 쿼리를 요청하는 메서드임을 알림
2. countBy로 시작 -> 쿼리 결과 레코드 수를 요청하는 메서드임을 알림
@Repository를 찾아보던 중, save 메서드가 어떻게 동작하는지도 궁금해서 찾아봤다.
@Transactional
@Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null.");
if (entityInformation.isNew(entity)) { // 1
em.persist(entity); // 2
return entity; // 3
} else { // 4
return em.merge(entity); // 5
}
}
출처: https://wangtak.tistory.com/2 [봄을 그리다:티스토리]
Jpa에서의 save 메서드 구현체 코드는 위와 같다.
isNew 메서드를 이용해서 엔티티가 중복인지 아닌지 확인을 하고, 중복이 아니라면 새로 저장을 하고 중복이라면 merge 를 한다. 새로운 엔티티인지 아닌지 확인하는 방식은 em.persist 를 하기 전까지는 id 가 null 이기 때문에 (자동으로 저장해주기 때문) 해당 값이 null / 0 인지를 확인하는 것이다.
그러나 @GeneratedValue 가 아닌 경우에는 위와 같은 방법을 사용할 수 없다.
예를 들어서, pk가 email 이라면 위와 같은 방식으로는 새로운 엔티티인지 아닌지 확인이 불가하다.
따라서 pk 값이 null인지 아닌지 확인한 뒤에 select 쿼리 한번을 보내서 해당 값이 이미 존재하는지 아닌지 확인을 해야 한다. 이럴 경우에는 불필요한 select 쿼리가 한번 생기는 것이기 때문에 비효율적이고 잘못 설계된 것이다.
이를 해결하기 위해서는 Persistable <Id의 Type> 인터페이스를 상속하게 되면 isNew() 를 개발자가 직접 오버라이딩하여 비교대상을 지정할 수 있다.
참고한 글들
JPA 사용법 (JpaRepository)
JPA에 대한 개념은 이해가 갔지만 처음 코드를 접했을 땐 이해 안가는 부분이 많았다. 그래서 잘 정리된 블로그를 참고해 다시 한번 사용법을 알기 쉽게 정리해보고자 한다. Entity 먼저 데이터베
jobc.tistory.com
Spring Data JPA - Save Method 동작 방식
Spring Data JPA에서 제공하는 JpaRepository.save(T); [T는 Entity]의 내부 동작 방식에 대해서 정리하려고 합니다. JPA에서의 save 메서드 구현체 코드는 다음과 같습니다. // SimpleJpaRepository.java [JPA 구..
wangtak.tistory.com
python manage.py migrate --run-syncdb
장고를 이용해서 User 모델을 개발하는데 아래와 같은 오류가 떴다.
django.db.utils.OperationalError : no such table : users_user
테이블이 없다는 소리였다.
migration 을 여러번 해줘도 같은 오류를 뱉어서 찾아보니 아래와 같은 명령어로 마이그레이션 없이 테이블을 만드는 방법이라고 한다.
python manage.py migrate --run-syncdb