long startTime = System.currentTimeMillis(); BoardResponse.Detail response = boardService.findBoard(board.getId()); long endTime = System.currentTimeMillis(); // then System.out.println(endTime - startTime); 해당 코드에서 findBoard Service는 게시글의 힌트, 태그, 정답, 공감을 가져와 DTO의 변환을 거쳐 하나의 게시글을 단건조회하는 서비스입니다. 다만 여러 케이스로 테스트했는데 단순히 findById로 로직을 테스트를 하게되면 해당 findBoard는 60~90ms의 실행속도와 쿼리가 지연로딩으로 인해 5개가 나가지만 JPQL을 통해 DTO를 직접 접근하는 식으로 바꿨을땐, 쿼리를 1개로 나가지만 실행속도가 250~290ms가 나오게 되는데 단건조회의 경우 fetchJoin이나 join+DTO 방식을 쓰는것보다 지연로딩이 있더라도 일반적인 findById를 사용하는것이 좋은지 여쭤봅니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 두 객체 생성 방식의 차이를 간단하게 비교해서 알아본 결과 Builder 패턴을 이용하면 가독성이 좋아져서 Builder 패턴을 이용해 객체를 생성하는 것이 좋다 VS Builder 패턴은 코드가 복잡해지고 생성자 보다 성능이 떨어지므로 생성자 방식으로 개겣를 생성하는 것이 좋다. 위와 같은 결론을 얻었습니다. 이렇게만 보면 코드를 작성하는 사람의 차이인거 같은데 실제 현업에서는 어떤 방식을 주로 사용하거나 선호하나요 ??
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 오랜만에 들어갔더니 db연결이안돼요 ㅠ 이거때문에 application 실행도 안 되네요.ㅠㅠ 원래 잘만 되다가 오늘 어노테이션이랑 다 막혀있길래 gradle 을 refresh 했는데 그 이후 다른 빨간줄은 해결됐는데 db연결이 안됩니다
제가 따로 구현하지 않고 Spring Data JPA JpaRepository 에서 상속받은 deleteById 를 사용하면 먼저 select query 가 1번 나간 다음에 찾아온 Entity로 delete 메서드를 호출하는 것 같더라구요 그래서 총 select, delete 쿼리가 각각 1번 총 2번 나가는 것 같은데 PK로 delete 를 하고 싶을 때, @Query로 작성하여 delete 문을 1번 나가게 하는 것과, 위의 방법대로 select, delete 각각 1번 나가는 방법 중에 어떤 방법을 사용하는 것이 좋은가요 ?
안녕하세요 호돌맨님! JWT 관련 강의에서 ArgumentResolver를 활용해 토큰 검증을 하고 사용자 정보를 추출해 반환하셨는데, 만약 프로젝트를 진행할 때 로그인을 해야 모든 URL에 접근할 수 있다고 한다면 아래 코드처럼 인터셉터에서 토큰 검증을 하고 ArgumentResolver에선 별다른 검증 없이 subject만 추출해서 반환해도 문제가 없을까요? 혹시 제가 접근 자체를 잘못하고 있다면 알려주시면 감사하겠습니다 @Slf4j @RequiredArgsConstructor public class LoginCheckInterceptor implements HandlerInterceptor { private final JwtService jwtService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String requestURI = request.getRequestURI(); log.info("인증 체크 인터셉터 실행 {}", requestURI); String accessToken = request.getHeader("Authorization"); jwtService.validateAccessToken(accessToken); try { jwtService.getSubject(accessToken); } catch (JwtException e) { throw new Unauthorized(); } return true; } } @RequiredArgsConstructor public class JwtArgumentResolver implements HandlerMethodArgumentResolver { private final JwtService jwtService; @Override public boolean supportsParameter(MethodParameter parameter) { boolean hasLoginAnnotation = parameter.hasParameterAnnotation(Login.class); boolean hasLoginType = LoginUser.class.isAssignableFrom(parameter.getParameterType()); return hasLoginAnnotation && hasLoginType; } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { String accessToken = webRequest.getHeader("Authorization"); Long userId = jwtService.getSubject(accessToken); log.info("userId = {}", userId); return new LoginUser(userId); } }
연동을 다해놨는데, 스프링 실행할때 에러가 나네요.. 이유를 못찾겠습니다. 구글 드라이브에 올릴게요 강의는 회원등록 4분46초 부분 하고 있었습니다. https://drive.google.com/file/d/1Xes5ztWKL5s4NDre1bSuGeL2t-tbnJIO/view?usp=sharing
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 예시로 드신 Member_Product 테이블의 관계는 주문 테이블이라고 이해가 되는데 이럴경우에는 fk 2개를 pk설정을 하면 중복된 값이 못들어와서 당연히 기본키를 하나 만들어 주는걸로 배웠는데 만약에 주문이 아니고 수강테이블처럼 중복된 값을 막아야 하는 경우에도 테이블 내에 pk를 하나더 만들어 주는게 맞을까요?
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 아니오 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 트랜잭셔널 어노테이션을 레포지토리나 컨트롤러가 아니라 서비스에 붙이는 이유가 있나요?
스프링이 제공하는 기능이 아니라 제가 직접해줘야하는건가요? 영속성 컨텍스트가 일정이상 차면 비워주는 작업을 어떻게 할 수 있을까요? 코드가 나와있긴하지만 그 코드는 너무 로우 레벨아닌가요?? SPRING DATA JPA사용하면서 em을 직접적으로 사용하진 않잖아요.. 자동으로 해주는건가요...?
주문기능테스트 8분 59초 보면 8개로 했다가 10개로 바꾸면 에러 나는데 h2 db에 해당 데이터를 확인할 수 가 없어서요 해당 테스트 한 데이터 값 남게하려면 어떤 어노테이션을 사용했는데 그게 뭘까요 ? 그리고 제가 알기론 테스트는 한번실행하고 나서 다시 초기화 시켜주는 걸로 알고 있는데 어떻게 8개 했다가 10으로 바꿨다고 에러가 나는 건가요 ? 강의를 아무래도 병행하다 보니 드문드문 띄게 되네요 이런게 강의자료에도 잘 설명이 되면 더 좋을텐데 스프링 문법이 안써있어서 너무 아쉬워요 책을 사야 할까요 ?
osiv가 뷰에서도 지연로딩이 가능하게 하려고 도입한거잖아요 (뷰에서 필요한값들을 지연로딩으로 가져오려고) 근데 지연로딩을 하면 결국 필요없는 쿼리가 추가로 나가게될텐데..애초에 필요한 데이터만 jpql사용해서 뽑아서 주면 문제가 해결되는거아닌가요? 왜osiv를 사용하는거죠?? 뷰와 리파지토리가 너무 연관되어서 그런가요..? 그게 그렇게 큰 단점인가요..? 뭔가 osiv의 장점이 엄청많아보이는데 제가 다른 분들 프로젝트를 봤을때는 osiv를 거의 적용안했던것같거든요... 왜 잘 안쓰이는걸까요...
스프링 데이터 JPA 페이징과 정렬 강의 부분에서 페이지를 유지하면서 엔티티를 DTO로 변환하기 Page<Member> page = memberRepository.findByAge(10, pageRequest); Page<MemberDto> dtoPage = page.map(m -> new MemberDto()); 페이지를 유지하면서 엔티티를 DTO로 변환하는 예제가 있습니다. 만약에 아래와 같이 Page<Member> page = memberRepository.findByAge(10, pageRequest); List<Member> dtoPage = faqListPage.stream().map(MemberDto::new) .toList(); List<> 로 반환하여 페이징 처리를 하였는데 페이지를 유지한 첫번째 방식 차이점이 있을까요?? 실무에서는 어떤 방식을 사용하나요?
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요! 먼저 유사한 질문이 있었는지 검색해 보세요. 서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요 강사님 강의 너무 잘 듣고있습니다. 회사에서 Mybatis로 개발 중인데 테스트 코드 작성에 어려움이 있어 질문 드립니다. JPA의 경우 CRUD가 기본적으로 구현되어 있지만, Mybatis의 경우 xml(또는 인터페이스)에 정의된 메서드를 사용하기 때문에 테스트 코드 작성이 어렵더군요.. 만약 Money 테이블이 있고, 해당 Repository에 Select 코드가 없는 경우 어떻게 검증을 해야 좋을까요? 테스트를 위해 xml이나 인터페이스에 새로운 코드를 작성하는 것은 좋은 방법이 아닌 것 같고, Jdbc Template를 이용해봤는데 이 경우에는 데이터가 롤백되지 않는 등의 문제가 있었습니다.( 아마 잘못 사용해서 그런 것 같기도 합니다..) Repository 부분을 Mock으로 Stub하여 테스트를 진행하는 것도 생각해 보았습니다. 이 경우에는 Repository 쿼리를 수정할 때마다 Service에 정의된 Stub도 그에 맞게 계속 수정해야 하는 문제가 있어서 이 방법도 적합하지 않다고 생각이 들었습니다..(이 케이스도 A,B 각각 모듈 단위의 테스트는 성공하나 결합하여 테스트할 때 실패하는 경우라고 볼 수 있을까요?) 회사가 테스트 코드를 작성하는 문화는 아니어서 물어볼 사람이 없어 질문 남깁니다.. 좋은 강의 감사하합니다. 앞으로도 좋은 강의 기대하겠습니다!!
em.persist(member1); em.persist(order1); em.persist(order2); em.flush(); em.clear(); <-- order1 내용 변경 --> em.persist(order1); tx.commit() flush와 clear까지 하면 db에 반영은 되어있고 order1의 내용을 조금 바꾼뒤 persist하면 1차 캐시에 올라가있을텐데, commit을 하면 실제 db에 아무것도 뜨지 않습니다. em.clear 주석 하고, 내용 변경 후 em.persist의 유무와 상관없이 db에 잘 반영이 됩니다. clear와 persist 사이의 무슨 관계가 있는 것 같은데, db에 아무것도 뜨지 않는 이유가 뭔가요?
안녕하세요, 양방향 연관관계 편의 메서드를 하는 이유는 순수한 객체 상태에서 봤을 때 양쪽에 값이 있어야 하기 때문인걸로 이해를 했습니다. order와 member가 다대일인 관계라 했을 때, 보통 멤버를 db에서 find해서 쓸텐데, 이러면 member에서의 orderList를 가지고 오려면 연관관계 편의 메서드 와는 상관없이 db에서 join을 해서 가지고 오더라구요,, 보통 프로젝트나 현업에서 순수한 객체 상태에서 쓸 일이 있나요? 아니면 연관관계 편의 메서드를 썼을 때 다른 이점이 있나요?