분류 전체보기

    [스프링 핵심 원리 -고급] 전략패턴

    템플릿 메서드 패턴은 부모 클래스에 변하지 않는 템플릿을 두고 변하는 부분을 자식 클래스에 두어 상속을 사용함 전략 패턴은 변하지 않는 부분을 Context에 두고, 변하는 부분을 Strategy라는 인터페이스를 만들고 해당 인터페이스를 구현하여 문제를 해결. 상속이 아니라 위임으로 문제를 해결한다. @Slf4j public class ContextV1 { private Strategy strategy; public ContextV1(Strategy strategy) { this.strategy = strategy; } public void execute() { long startTime = System.currentTimeMillis(); //비지니스 로직 실행 strategy.call(); //비지니..

    [스프링 핵심 원리-고급] 템플릿 메서드 패턴

    변하는 것과 변하지 않는 것을 분리한다 좋은 설계는 변하는 것과 변하지 않는 것을 분리하는것 템플릿 메서드 패턴은 이런 문제를 해결하는 디자인 패턴이다. 템플릿 메서드 패턴은 이름 그대로 템플릿을 사용하는 방식, 템플릿은 기준이 되는 거대한 틀이다. 템플릿이라는 틀에 변하지 않는 부분은 몰아둔다. 그리고 일부 변하는 부분을 별도로 호출해서 해결한다. 템플릿 메서드 디자인 패턴의 목적 - 작업에서 알고리즘의 골격을 정의하고 일부 단계를 하위 클래스로 연기한다. 템플릿 메서드를 사용하면 하위 클래스가 알고리즘의 구조를 변경하지 않고도 알고리즘의 특정 단계를 정의할 수 있다. 예제 코드 생성 @Slf4j public class TemplateMethodTest { @Test void templateMethod..

    [스프링 핵심 원리-고급] 쓰레드 로컬 주의사항

    기본적으로 WAS는 쓰레드풀에서 쓰레드를 관리하고, 요청이 들어오면 쓰레드 하나를 꺼내서 사용한다. ThreadLocal를 사용하여 특정 데이터를 저장 처리한다.(전용 데이터를 보관중) 해당 작업이 끝나고 thread-A를 쓰레드풀에 반환하지만, 해당 쓰레드를 메모리에서 반환하는게 아닉 때문에, ThreadLocal에는 이전에 사용하던 데이터가 남아있게된다. 그다음 요청이 들어왔을때 하필 그 thread-A가 할당되면, 기존 데이터와 혼선이 발생함 해결방안? - 요청을 받아 처리가 끝나면 ThreadLocal.remove()를 통해 꼭 제거한다.

    [JPA] 객체지향쿼리

    JPQL JPQL은 엔티티 객체를 조회하는 객체지향 쿼리다. JPQL은 SQL을 추상화해서 특정 데이터베이스에 의존하지 않으며, SQL에 비해 간결하다. @Entity(name="MEMBER") public class Member{ @Column(name="name") private String username; } //사용 String jpql = "select m from Member as m where m.username = "kim" List resultList = em.createQuery(jpql, Member.class).getResultList(); 작성한 JPQL을 실행하려면 쿼리 객체를 만들어야 한다. 쿼리 객체는 TypeQuery와 Query가 있는데 반환할 타입을 명확하게 지정할 수..

    [JPA]상속관계맵핑

    조인전략 @Entity @Inheritance(strategy=InheritanceType.JOINED) // join 전략을 사용 @DiscriminatorColumn(name = "DTYPE") // 부모 클래스에 구분 컬럼을 지정 public class Item{ @Id @GenerateValue private Long id; private String name; private int price; } @Entity @DiscriminatorValue(value = "A") public class Album extends Item{ private String artist; } @Entity @DiscriminatorValue(value = "M") public class Movie extends It..

    [JPA]스프링 데이터 Common:커스텀 리포지토리

    쿼리 메소드로 해결이 되지 않는 경우 직접 코딩으로 구현가능 스프링 데이터 리포지토리 인터페이스에 기능 추가 스프링 데이터 리포지토리 기본 기능 덮어쓰기 가능 구현 방법 커스텀 리포지토리 인터페이스 정의 인터페이스 구현 클래스 만들기(기본 접미어는 IMPL) 엔티티 리포지토리에 커스텀 리포지토리 인터페이스 추가 public Interface PostCustomRepository extends JpaRepository, PostcustomRepository{ List findMyPost(); } 기본 기능도 사용하되 일부 기능은 Override하여 나의 입맛에 맞게 수정하여 사용함 @Repository @Transactional public class PostcustomRepositoryImpl imple..

    [JPA]fetch join

    fetch 조인 Property: 완료 생성일: 2021년 8월 11일 오전 11:16 주제: JPA 최종 업데이트: 2022년 1월 18일 오후 6:29 회원을 조회하면서 연관된 팀도 함께 조회한다. (SQL 한번에) 엔티티에 직접 적용하는 글로벌 로딩 전략보다 우선(@oneToMany(fetch = fetchType.Lazy) 최적화가 필요한 곳은 fetch조인으로 해결 ex) [JPQL] select m from Member m join fetch m.team [sql] SELECT M., T. From MEMBER M INNER JOIN TEAM T ON M.TEAM_ID = T.ID 만약 fetch조인을 하지 않는다면? 회원1조회할때 팀A에 대한 쿼리한번 회원2조회할때는 영속성 캐쉬에서 호출 회..

    [JPA]MappedSuperClass

    @MappedSuperclass public class BaseEntity{ @Column(name = "INSERT_MEMBER") privateString createdBy; //위 방법으로 하면 해당 테이블 이름을 INSERT_MEMBER로 생성함 private LocalDateTime createDate; private String lastmodifiedBy; private LocalDateTime lastModifiedDate; } 위와 같이 공통으로 사용하는 컬럼의 base entity를 생성함 상속관계 매핑이 아니다. 엔티티가 x (baseEntity 테이블이 생성되는게 아님) 부모 클래스를 상속 받는 자식 클래스에 매핑 정보만 제공 조회, 검색 불가 직접 생성해서 사용할 일이 없으므로 추상..

    [JPA] 프록시

    지연 로딩 기능을 사용하려면 실제 엔티티 객체 대신에 데이터베이스 조회를 지연할 수 있는 가짜 객체가 필요한데 이것을 프록시 객체라고 한다. 프록시 특징 프록시 클래스는 실제 클래스를 상속 받아서 만들어지므로 실제 클래스와 겉 모양이 같다. 프록시 객체의 초기화 프록시 객체는 member.getName()처럼 실제 사용될 때 데이터베이스를 조회해서 실제 엔티티 객체를 생성하는데 이것을 프록시 객체의 초기화라 한다. 프록시의 특징 프록시 객체는 처음 사용할 때 한번만 초기화된다. 프록시 객체를 초기화한다고 프록시 객체가 실제 엔티티로 바뀌는 것은 아니다. 프록시 객체가 초기화되면 프록시 객체를 통해서 실제 엔티티에 접근할 수 있다. 프록시 객체는 원본 엔티티를 상속받은 객체이므로 타입 체크 시에 주의해서 ..

    [JPA]객체지향 쿼리 심화

    벌크 연산 엔티티를 수정하여 영속성 컨텍스트의 변경 감지 기능이나 병합을 사용하고 삭제할때 EntityManager.remove() 사용한다. 하지만 이 방법으로 수백개 이상의 엔티티를 하나씩 처리하기에는 시간이 너무 오래걸리고, 이럴 때 여러건을 한 번에 수정하거나 삭제하는 벌크 연산을 사용한다.\ // UPDATE 벌크 연산 String sqlString = "update Product p set p.price = p.price * 1.1 where p.stockAmount < :stockAmount"; int resultCount = em.createQuery(sqlString).setParameter("stockAmount", 10).executeUpdate(); 벌크 연산은 executeUpda..