묻고 답해요
161만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨김영한의 실전 자바 - 기본편
객체 지향 프로그래밍 문제와 풀이 1번 문제
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]저는 Rectangle 클래스 안에서 넓이랑 높이를 5와 8로 초기화해주고 메인 메서드에서 출력할 때 객체로 출력하였는데 이렇게 했을 때의 문제점이 있을까요??
-
미해결김영한의 실전 자바 - 기본편
다운캐스팅에 대한 질
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)강의에서 다운캐스팅에 관해 이야기를 해주셨습니다.부모 클래스인 Parent 타입의 변수에 Parent 인스턴스를 생성해서 참조값을 해당 참조변수에 넣고Child 타입의 참조변수에 다운캐스팅을 하고 나서 해당 child 메서드를 호출하려고 했을 떄 오류가 발생했습니다. 여기서 영한님이 말씀해주신대로 생각해보면 Parent 인스턴스를 생성했을 때, 해당 메모리 안에 Parent 타입의 클래스 정보만을 저장했을테고 자식에 대한 정보가 해당 메모리 주소값 안에 없다. 따라서 다운캐스팅을 해도 자식클래스 메서드를 호출하지 못한다 -> 라고 생각하면 되는 건가요? 그렇지만 다시 생각해보면 메서드는 메서드 영역 내에서 가져다가 호출하는 방식인데, 그렇게 된다면 자식 클래스의 메서드 또한 메서드 영역내에서 불러오면 되니까 호출이 가능한 게 아닐까요..?궁금하네요
-
해결됨김영한의 자바 입문 - 코드로 시작하는 자바 첫걸음
[8.배열][문제와풀이1] 문제 3번
안녕하세요 선생님선생님께서 올려주신 코드와 다르게 하기 처럼 코드를 작성해도 되는 부분인지 궁금증이 생겨 질의드립니다! [선생님 코드][제 코드]System.out.println("출력"); for (int i = numbers.length - 1 ; i >= 0 ; i--) { System.out.print(numbers[i]); if (i != 0) { System.out.print(", "); }(1. int 범위는 numbers.length길이보다 1더 적다 // 2. i는 0과 같지 않다)
-
미해결실전! 스프링 데이터 JPA
대시보드에서 사용되는 Native Query들은 어디에 보관하나요?
보통 연관된 엔티티 레포지토리에 네이티브 쿼리를 넣는다고 생각했는데,대시보드 api를 구현하다보니 이런저런 테이블과 join되는 것들이 많아 연관된 엔티티도 많습니다..public interface SleepRepository extends JpaRepository<Sleep, Long> { // 여기에 sleep entity말고도 3개 이상의 entity가 조인되는 native query가 있습니다 }혹 이런경우는 native 쿼리들을 모아서 보관하나요? 보관하게 된다면 어디에 어떻게 보관하는지 알 수 있을까요?
-
해결됨김영한의 실전 자바 - 기본편
인스턴스 질문입니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]Data dataA = new Data();dataA.value = 10;Data dataB = dataA;에서요 세번째줄에... dataB는 new 선언을 안했는데 쓰일 수 있는건가요?잘 이해가 되지 않아서요Data dataB = new Data();dataB = dataA; 라고 해야하는걸로 알고 있었는데선생님 코드로 해도 잘 되서 혼란스럽네요 ㅠㅠ
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
Java HotSpot 에러가 뜹니다
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요.jar빌드도 되고 다 member테이블도 생겼습니다. 그런데 마지막 단계에서 계속 이런 오류가 뜨면서 쿼리파라미터 로그는 확인할 수 없는데요, 어느 부분이 잘못되었는지 모르겠습니다ㅠㅠ제가 적은 코드입니다 (Junit5로 진행했습니다)package jpabook.jpashop; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.annotation.Rollback; import org.springframework.transaction.annotation.Transactional; import static org.junit.jupiter.api.Assertions.*; @SpringBootTest public class MemberRepositoryTest { @Autowired MemberRepository memberRepository; @Test @Transactional // test에 있으면 test 끝난 뒤 바로 롤백함 -> 테스트 조회 불가능 @Rollback(false) // 롤백 안되게! public void testMember() throws Exception { // given Member member = new Member(); member.setUsername("memberA"); // when Long saveId = memberRepository.save(member); Member findMember = memberRepository.find(saveId); // then assertEquals(findMember.getId(), member.getId()); assertEquals(findMember.getUsername(), member.getUsername()); assertEquals(findMember, member); // 같은 트랜잭션 안에서는 영속성 콘텍스트가 같음 => id가 같으면 같은 엔티티로 식별함 System.out.println("findmember == member: " + (findMember == member)); } }spring: datasource: url: jdbc:h2:tcp://localhost/~/jpashop username: sa password: driver-class-name: org.h2.Driver jpa: hibernate: ddl-auto: create #application 실행 시점에 기존에 있으면 drop하고 없으면 자동으로 테이블 생성 properties: hibernate: # show_sql: true #sysout으로 확인 -> logger로 확인할 것이므로 생략하자! format_sql: true logging: level: org.hibernate.SQL: debug #logger로 확인: hibernate가 생성하는 모든 sql문이 debug로 확인가능 org.hibernate.type: trace #쿼리 파라미터 로그 남기기감사합니다!
-
미해결실습으로 배우는 선착순 이벤트 시스템
카프카 토픽 생성이 안되요.
docker exec -it kafka kafka-topics.sh --bootstrap-server localhost:9092 --create --topic testTopic위와 같이 터미널에 토픽생성하는 명령어를 작성하면 아무것도 |움직이지 않고 터미널이 멈춥니다.도커는 정상적으로 실행하고 kafka,zookeeper도 정상적으로 실행되어있습니다.도커를 삭제하고 다시 다운로드해서 docker compose사용해서 kafka,zookeeper이미지 다시 작동시켜도 위와같이 토픽생성 명령어 입력하고 작동시 아무것도 안하고 멈춥니다..(p.s 카프카 컨테이너 cli들어가서도 토픽 생성 명령어 작동시켜도 작동안합니다.)혹시 해당 문제 해결법 아실까요..?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
연관관계 편의 메소드 관련 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요, 스프링부트 강의 잘 수강하고 있습니다.<엔티티 설계시 주의점> 23:25 강의를 수강하며, 궁금한 점이 두가지 있습니다!메소드 내 순서//연관관계 편의 매소드 public void setMember1(Member member){ this.member = member; member.getOrders().add(this); } //순서 이렇게도 가능한가? public void setMember2(Member member){ member.getOrders().add(this); this.member = member; }강의에서는 setMember1 방식으로 진행을 하였는데,만약 setMember2 방식으로 순서가 바뀌어도 문제가 없는 것인지 궁금합니다.@Setter <-> setMember() 메소드 중복 Order 엔티티에 @setter 어노테이션을 붙였기에, 롬복이 setMember() 메소드를 자동으로 생성해줍니다.강의에서는 연관관계 메소드명을 setMember()으로 생성하여, 롬복이 만들어주는 메소드랑 이름이 중복됩니다. 생성자를 만들어 실험해보니 롬복이 만들어주는 setMember() 메소드는 보여지지 않으며 연관관계 편의 메소드가 덮어쓰기 한 것으로 보이는데, 제대로 한 것이 맞을까요?만약 실무에서 롬복을 사용할 때, 이런 경우(연관관계 메소드가 롬복 @Setter 메소드 위에 덮어쓴 경우)가 된다면 문제가 될 수도 있을까요???
-
미해결김영한의 실전 자바 - 기본편
인스턴스 메서드, 클래스 메서드의 생성 시기 차이
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요, 자바의 메모리 구조 관련 강의를 보고 질문드립니다!인스턴스 메서드들은 인스턴스가 생성될 때마다 매번 메모리가 할당될 필요가 없기에 메서드 영역에 생성되는 것으로 이해했습니다. 정적 메서드 또한 정적이기에 메서드 영역에 할당되는 것으로 이해했습니다. 그렇다면 이 두 종류의 메서드 모두 메서드 영역에 메모리가 할당은 되는데, 생성되는 시점에 차이가 있는 걸까요?예를 들어서.. Student 라는 클래스가 있다고 가정하면, 해당 클래스의 첫 인스턴스가 생성되는 시점에 메서드 영역에 Student 클래스의 인스턴스 메서드들이 할당되는걸까요? 둘의 기능이나 의미상의 차이는 이해가 가는데, 메모리의 관점에서의 이해와 생성 시기의 차이가 이해되지 않는 것 같습니다.그리고 어디부터 어디까지가 클래스의 정보이기에 메서드 영역에 생성되는지 역시도 이해가 잘 가지 않습니다. JVM 로드 시에 메서드 영역에 할당되는 클래스의 정보에 인스턴스 메서드도 포함되는걸까요?제가 혹시 제대로 이해하지 못한 것이라면, 어떤 부분을 다시 들으면 좋을지도 알려주시면 정말 감사할 것 같습니다!
-
미해결자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비
12번 암호문 런타임에러
14e972338646 import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner kb = new Scanner(System.in); int num = Integer.parseInt(kb.nextLine()); String str = kb.nextLine(); solution(str, num); kb.close(); } private static void solution(String str, int num) { List<String> binlist = new ArrayList<>(); for (int i = 0; i < str.length(); i += (str.length() / num)) { int end = Math.min(i + str.length() / num, str.length()); binlist.add(str.substring(i, end)); } for (String each : binlist) { StringBuilder tmp = new StringBuilder(); for (char mos : each.toCharArray()) { if (mos == '#') tmp.append(1); if (mos == '*') tmp.append(0); } binlist.set(binlist.indexOf(each), tmp.toString()); } for(String each : binlist){ solution2(each); } } private static void solution2(String bin) { int ascii = Integer.parseInt(bin,2); System.out.print((char)ascii); } } 다른 질문 글에도 런타임 에러 질문이 있는거 같은데 명확한 답변을 못 찾아 글을 올려봅니다. 12번 암호문제구요.2,3,4,5 테스트 케이스 다 통과했다는데 1번 테스트케이스에서 런타임에러가 나옵니다.다른 글에서 보니 1번은 문제에서 제시한 테스트케이스라는데 로컬에서는 정상 작동을 확인했습니다. 어떤 부분이 문제일까요? 런타임에러가 어떤 상황인지도 알고 싶습니다.
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
@GetMapping 관련 질문입니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]@GetMapping 의 실행순서에 관한 질문입니다.@GetMapping("/") , @GetMapping("/members/new")2개의 매핑이 있을 경우, 매핑의 우선순위를 알고 싶습니다.좀 더 구체적인 경로가 먼저 매핑된다고 알고있었는데그럼 localhost:8080 을 실행했을때 home.html 이 아닌createMemberForm.html 이 나와야 하는건가? 해서요단순히 localhost:8080 으로 실행했기 때문에 "/" 로 간걸로 보면되나요?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
JPA FULL TEXT SEARCH 에 관한 질문입니다.
영한님, 안녕하세요.본 강의와 맞지 않는 질문을 드린거 같아서 죄송합니다. 현재 댓글을 검색하는 기능에 기존 LIKE %keyword% 를 쓰는 방식보다 full text search를 적용하는 것이 성능 상 이점이 있다고 하여 적용 중에 있습니다. 하지만, 기존 like 방식보다 오히려 성능이 안나오는 현상을 겪고 있습니다. 10만 건을 테스트를 해보았고 100만건 1만건 5만건 모두 성능이 비등하거나 떨어집니다.. ex) 10만건 성능like = 429msfull text search = 476ms 의 성능을 보이고 있습니다. 뭔가 놓치고 있는 것 같습니다. 그런데 mysql 실행계획으로 퍼포먼스를 확인해보니, full text search가 2배 빠른 것으로 확인이 되는데 이게 왜 그런 건지 모르겠습니다.
-
미해결김영한의 실전 자바 - 기본편
예제 질문입니다
[질문 내용]질문1)public class RectangleOopMain { public static void main(String[] args) { Rectangle rectangle = new Rectangle(); rectangle.width = 5; rectangle.height = 8; rectangle.print(); } }public class Rectangle { int width; int height; void print(){ int area = calculateArea(); System.out.println("넓이: " + area); int perimeter = calculatePerimeter(); System.out.println("둘레 길이: " + perimeter); boolean square = isSquare(); System.out.println("정사각형 여부: " + square); } int calculateArea() { return width * height; } int calculatePerimeter() { return 2 * (width + height); } boolean isSquare() { return width == height; }Main에 있는 출력을 클래스로 빼서 풀었는데이렇게 풀어도 되는지, 비효율적인지 궁금합니다. 질문2) public class Account { int balance; void deposit(int amount){ balance += amount; } void withdraw(int amount){ if (balance >= amount){ balance -= amount; }else if (balance < amount){ System.out.println("잔액 부족"); } } }Account 문제에서 void deposit 과 void withdraw 클래서에서 return balance를 하지 않아도 되는 이유가 궁금합니다.
-
미해결김영한의 실전 자바 - 기본편
다형성과 상속에 관해 질문 있습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.1.해당 강의에서 Car이라는 interface인데 Private Car car처럼 인스턴스를 생성할 수 있는건가요?? 2.setCar(Car car) 함수를 사용할 때, Car라는 interface를 구현한 클래스인 K3Car와 Model3Car만 매개변수로 사용할 수 있다. 왜냐하면, 인터페이스(Car)와 그 인터페이스의 구현 클래스(K3Car와 Model3Car)는 부모와 자식같은 상속과도 같은 관계이기 때문이다.이렇게 위와 같이 이해했는데 옳게 이해한 것이 맞나요? 3.마지막으로 private static 이렇게 작성하실 때가 종종 있는데 이렇게 작성하시는 이유가 잘 이해가 안됩니다.private를 사용하면 => 해당 클래스에서만 사용하겠다는 의미static을 사용하면 => 메모리에 올려서 전역으로 사용하겠다는 의미라고 이해를 했는데 어떻게 private와 static을 같이 쓸 수 있는건가요??
-
미해결김영한의 실전 자바 - 기본편
Scanner 문제
scanner.nextInt() 다음에 바로 scanner.nextLine()을 하는 이유는 무엇인가요? 그리고 위 코드처럼 하지 않을 시에 왜 이러한 결과가 발생하는지 궁금합니다.
-
미해결김영한의 자바 입문 - 코드로 시작하는 자바 첫걸음
var 타입은 왜 사용을 잘 하지 않나요?
[질문 내용]var타입은 컴파일때 자바가 타입을 추론해서 자동으로 변환해준다고 알고있습니다. 그러면 엄청 편리한 타입인거 같은데 막상 보면 var 를 사용하는 것을 많이 보지 못한거 같습니다. var타입보다 int, String,,, 등등 이러한 명시된 타입이 더 많이 사용되는 이유가 궁금합니다.
-
해결됨자바 동시성 프로그래밍 [리액티브 프로그래밍 Part.1]
[sleep() 강의] sleep(0) 메서드 관련 질문이 있습니다.
안녕하세요. 선생님 sleep() 강의를 듣다가 sleep(0) 메서드 관련해서 질문이 생겨서 질문을 남기게 되었습니다! sleep() 강의 중 12:25 내용을 보면, sleep을 진행하려는 Thread의 priority가 5라서 동일한 우선순위인 5인 Thread가 있는지 찾아본다고 말씀을 해주셨는데요. 제가 여기서 궁금한 점은 반드시 동일한 우선순위의 Thread만을 확인하는지가 궁금합니다. 만약 동일한 우선순위인 우선순위가 5인 Thread는 없더라도, 더 높은 우선순위의 Thread가 존재해도 컨텍스트 스위칭이 일어나지 않는 것일까요 ??
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
강의 로드맵 변경 문의드립니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 아니오2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 네3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 네[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요. 저는 JPA 기술을 연마하고 싶은 개발자입니다!지금 [우아한형제들 최연소 기술이사 출신 김영한의 스프링 완전 정복]을 결제한 상태이고,[스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술] 강의를 다 들었습니다.그런데 이 강의를 다 듣고나니 저한테 맞는 로드맵은[김영한의 스프링 부트와 JPA 실무 완전 정복 로드맵] 인 것 같아서 문의드립니다. 금액이 문제가 될 수 있지만, 어떻게어떻게 로드맵을 변경할 수 있는 방법이 없을까요? 안그래도 일정이 오래 소요 될 듯하여 걱정 됐었는데, 현재 진행중인 [스프링 완전 정복] 대신 차라리 바로 [스프링 부트와 JPA 실무 완전 정복 로드맵] 공부에 들어가면 제 일정과 딱 맞을 것 같습니다..!
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
SpringConfig.java 인식 오류
안녕하세요. 스프링 입문 - 자바 코드로 직접 스프링 빈 등록하기 강의 실습 중 SpringConfig.java 인식이 되지 않는 오류가 발생했습니다. SpringConfig.java 파일 구조와 내용은 위와 같습니다. 에러 코드는 다음과 같습니다.Action: Consider defining a bean of type 'grace.gracespring.service.MemberService' in your configuration. > Task :GraceSpringApplication.main() FAILED Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. For more on this, please refer to https://docs.gradle.org/8.5/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':GraceSpringApplication.main()'. > Process 'command 'C:\Program Files\Java\jdk-17\bin\java.exe'' finished with non-zero exit value 1 아래는 controller, service, repository 코드입니다. 도움 주시면 감사하겠습니다.비슷한 오류가 발생하신 다른 분 해결법(SpringConfig.java 가 클래스로 인식안됨)도 시도해보았지만 같은 에러가 계속 발생합니다ㅜ
-
미해결실전! Querydsl
최종 질문) 페이징 & 정렬
제가 제대로 이해하고 있는지 제대로 잡고 넘어가려고 합니다. 질문1먼저 단순한 제목 검색과 페이지처리와 정렬을 구현했을 때fetchCount 대신에 fetchOne을 사용하기 위해서 별도로 count 쿼리를 생성해서 페이지 처리를 해줍니다.페이지와 정렬을 처리할 때 동적 정렬을 처리하기 위해서 OrderSpecifier을 사용해서 동적 정렬 쿼리를 하기 위해서 다음과 같이 설정http://localhost:9090/v2/members?page=1&sort=memberId,desc Pageable로 페이지랑 정렬을 받아서 동적으로 뽑아와서 메소드를 만들고 orderBy에 넣었습니다. 이런식으로 처리하는게 맞나요?질문2@Repository @Log4j2 public abstract class Querydsl4RepositorySupport { // 이 클래스가 다루는 도메인(엔터티)의 클래스 private final Class domainClass; // 도메인 엔터티에 대한 Querydsl 쿼리를 생성하고 실행 private Querydsl querydsl; // 데이터베이스와의 상호 작용을 담당하는 JPA의 핵심 객체 private EntityManager entityManager; // queryFactory를 통해 Querydsl 쿼리를 생성하고 실행합니다. private JPAQueryFactory queryFactory; public Querydsl4RepositorySupport(Class<?> domainClass) { Assert.notNull(domainClass, "Domain class must not be null!"); this.domainClass = domainClass; } // Pageable안에 있는 Sort를 사용할 수 있도록 설정한 부분 @Autowired public void setEntityManager(EntityManager entityManager) { Assert.notNull(entityManager, "EntityManager must not be null!"); // JpaEntityInformation을 얻기 위해 JpaEntityInformationSupport를 사용합니다. // 이 정보는 JPA 엔터티에 대한 메타데이터 및 정보를 제공합니다. JpaEntityInformation entityInformation = JpaEntityInformationSupport.getEntityInformation(domainClass, entityManager); // 이는 Querydsl에서 엔터티의 경로를 생성하는 데 사용됩니다. SimpleEntityPathResolver resolver = SimpleEntityPathResolver.INSTANCE; // entityInformation을 기반으로 엔티티의 경로를 생성합니다. EntityPath path = resolver.createPath(entityInformation.getJavaType()); this.entityManager = entityManager; // querydsl 객체를 생성합니다. // 이 객체는 Querydsl의 핵심 기능을 사용할 수 있도록 도와줍니다. // 엔터티의 메타모델 정보를 이용하여 Querydsl의 PathBuilder를 생성하고, 이를 이용하여 Querydsl 객체를 초기화합니다. this.querydsl = new Querydsl(entityManager, new PathBuilder<>(path.getType(), path.getMetadata())); this.queryFactory = new JPAQueryFactory(entityManager); } // 해당 클래스의 빈(Bean)이 초기화될 때 자동으로 실행되는 메서드 @PostConstruct public void validate() { Assert.notNull(entityManager, "EntityManager must not be null!"); Assert.notNull(querydsl, "Querydsl must not be null!"); Assert.notNull(queryFactory, "QueryFactory must not be null!"); } // 이 팩토리는 JPA 쿼리를 생성하는 데 사용됩니다. protected JPAQueryFactory getQueryFactory() { return queryFactory; } // 이 객체는 Querydsl의 핵심 기능을 사용하는 데 도움이 됩니다. protected Querydsl getQuerydsl() { return querydsl; } // EntityManager는 JPA 엔터티를 관리하고 JPA 쿼리를 실행하는 데 사용됩니다. protected EntityManager getEntityManager() { return entityManager; } // Querydsl을 사용하여 쿼리의 SELECT 절을 생성하는 메서드입니다. // expr은 선택할 엔터티나 엔터티의 속성에 대한 표현식입니다. protected <T> JPAQuery<T> select(Expression<T> expr) { return getQueryFactory().select(expr); } // Querydsl을 사용하여 쿼리의 FROM 절을 생성하는 메서드입니다. // from은 엔터티에 대한 경로 표현식입니다. protected <T> JPAQuery<T> selectFrom(EntityPath<T> from) { return getQueryFactory().selectFrom(from); } // 이 메서드는 주어진 contentQuery를 사용하여 Querydsl을 통해 JPA 쿼리를 생성하고 실행하고, // 그 결과를 Spring Data의 Page 객체로 변환하는 기능을 제공 protected <T> Page<T> applyPagination(Pageable pageable, Function<JPAQueryFactory, JPAQuery> contentQuery) { // 1. contentQuery를 사용하여 JPAQuery 객체를 생성 JPAQuery jpaQuery = contentQuery.apply(getQueryFactory()); // 2. Querydsl을 사용하여 페이징 및 정렬된 결과를 가져옴 List<T> content = getQuerydsl().applyPagination(pageable, jpaQuery).fetch(); // 3. contentQuery를 다시 사용하여 countQuery를 생성 JPAQuery<Long> countQuery = contentQuery.apply(getQueryFactory()); // 4. countQuery를 실행하고 총 레코드 수를 얻음 long total = countQuery.fetchOne(); // 5. content와 pageable 정보를 사용하여 Spring Data의 Page 객체를 생성하고 반환 return PageableExecutionUtils.getPage(content, pageable, () -> total); } // 이 메서드는 contentQuery와 함께 countQuery를 인자로 받아서 사용합니다. // contentQuery를 사용하여 페이징된 결과를 가져오고, countQuery를 사용하여 전체 레코드 수를 얻습니다. protected <T> Page<T> applyPagination(Pageable pageable, Function<JPAQueryFactory, JPAQuery> contentQuery, Function<JPAQueryFactory, JPAQuery> countQuery) { JPAQuery jpaContentQuery = contentQuery.apply(getQueryFactory()); List<T> content = getQuerydsl().applyPagination(pageable, jpaContentQuery).fetch(); JPAQuery<Long> countResult = countQuery.apply(getQueryFactory()); log.info("countResult : " + countResult ); Long total = countResult.fetchOne(); return PageableExecutionUtils.getPage(content, pageable, () -> total); } }fetchCount() → fetchOne()으로 변경 // count처리 까지 한것 public Page<Member> applyPagination2(MemberSearchCondition condition, Pageable pageable) { return applyPagination(pageable, contentQuery -> contentQuery.selectFrom(member) .leftJoin(member.team, team) .where(userNameEq(condition.getUserName()), teamNameEq(condition.getTeamName()), ageGoe(condition.getAgeGoe()), ageLoe(condition.getAgeLoe()) ), countQuery -> countQuery .select(member.count()) .from(member) .where(userNameEq(condition.getUserName()), teamNameEq(condition.getTeamName()), ageGoe(condition.getAgeGoe()), ageLoe(condition.getAgeLoe())) ); } private BooleanExpression userNameEq(String userName) { return hasText(userName) ? member.userName.eq(userName) : null; } private BooleanExpression teamNameEq(String teamName) { return hasText(teamName) ? team.name.eq(teamName) : null; } private BooleanExpression ageGoe(Integer ageGoe) { return ageGoe != null ? member.age.goe(ageGoe) : null; } private BooleanExpression ageLoe(Integer ageLoe) { return ageLoe != null ? member.age.loe(ageLoe) : null; } @Service @RequiredArgsConstructor public class MemberService { private final MemberTestRepository memberTestRepository; public Page<MemberTeamDTO> search(MemberSearchCondition condition, Pageable pageable) { Sort sort = pageable.getSort(); PageRequest pageRequest = PageRequest.of( (int) pageable.getOffset(), pageable.getPageSize(), sort ); Page<Member> resultPage = memberTestRepository.applyPagination2(condition, pageRequest); return resultPage.map(member -> MemberTeamDTO.builder() .memberId(member.getId()) .age(member.getAge()) .userName(member.getUserName()) .teamId(member.getTeam().getId()) .teamName(member.getTeam().getName()) .build()); } }Sort를 처리할 때 orderBy할 필요 없이 PageRequest.of로 보내주면 된다고 글을 봐서 동적으로 처리할 수 있도록 Sort sort = pageable.getSort(); PageRequest pageRequest = PageRequest.of( (int) pageable.getOffset(), pageable.getPageSize(), sort );이렇게 처리했습니다. Post맨으로 돌려본 결과 제개 원하는 대로 페이징, 정렬이 되었는데 이런식으로 하는게 맞나 확인하고 싶어서 질문드립니다. 질문3 질문1 OrderSpecifier로 동적인 쿼리 처리하고 있는데 Querydsl4RepositorySupport이거를 사용한 이유가 유지보수와 가독성을 더 높여주는 방법이라 이해했는데 맞나요?