묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨토비의 스프링 부트 - 이해와 원리
안녕하세요. 토비님
안녕하세요. 혹시 다음 강의 계획에 대해 여쭤봐도 될까요? 스프링 학습을 좀 더 깊게하고 싶어 토비의 스프링3.1을 구매하려고 했는데 혹시라도 조만간 토비님의 강의가 나온다면 강의부터 보고 싶은 마음에 질문 드립니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
회원조회 API 버전1 포스트맨에서 could not get response
아래의 코드대로 회원 조회 API를 버전1 과 버전2를 수행하는데, 버전2의 경우는 응답이 잘 받아지는데 버전1은 error: abort 가 뜹니다. /* * 회원 조회 * */ @GetMapping("/api/v1/members") public List<Member> membersV1(){ return memberService.findMembers(); } @GetMapping("/api/v2/members") public Result membersV2(){ List<Member> findMembers = memberService.findMembers(); List<MemberDto> collect = findMembers.stream() .map(m -> new MemberDto(m.getName())) .collect(Collectors.toList()); // 스트림의 처리 결과를 리스트 형태로 수집 return new Result(collect); // Result 클래스를 통해 List<MemberDto>를 반환 }
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
MemoryMemberRepository와 MemberService의 차이는 무엇인가요?
이 둘은 비슷한 메서드를 구현한다고 느껴집니다.(save=join) 왜 이런 구조로 작성하나요?
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
entity 객체에 기본생성자를 넣어주는 이유
안녕하세요User객체에 기본생성자를 넣어야 작동하는 이유가 궁금합니다혹시 필드에 아무값도 넣지않을때를 대비해서 기본생성자를 사용하는건가요?
-
미해결실전! 스프링 데이터 JPA
쿼리 메서드 @Query시 limit
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요, 강의 듣는 도중 궁금증이 생겨 질문드립니다.만약 쿼리 메서드를 사용하여 특정 조건에 의해 게시물 10개만 가져오고 싶을 때List<Board> findTop10ByWriteDatetimeGreaterThanOrderByCommentCountDescViewCountDescWriteDatetimeDesc(String writeDatetime);과 같이 지저분하게 코드를 작성할 수 있었는데 메서드 이름이 너무 길어져 @Query를 사용해서 코드 양을 줄이고 싶었습니다. 하지만, jpql에 limit를 사용할 수 없는데 이 경우 어떻게 jpql을 작성해야 하는지 궁금합니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
상품 수정이 되지 않는데 이유를 모르겠습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]상품 수정페이지 에서 상품에 대한 값 변경 시 데이터베이스에 반영이 되지 않는데 이유를 모르겠습니다. 다음은 코드입니다.ItemController.javapackage jpabook.jpashop.Contorller; import jpabook.jpashop.domain.item.Book; import jpabook.jpashop.domain.item.Item; import jpabook.jpashop.service.ItemService; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import java.util.List; @Controller @RequiredArgsConstructor public class ItemController { private final ItemService itemService; @GetMapping("/items/new") public String createForm(Model model) { model.addAttribute("form", new BookForm()); return "items/createItemForm"; } @PostMapping("/items/new") public String create(BookForm form) { Book book = new Book(); //set안쓰고 Book생성자의 파라미터로 넣는게 더 좋은 설계임 book.setName(form.getName()); book.setPrice(form.getPrice()); book.setStockQuantity(form.getStockQuantity()); book.setAuthor(form.getAuthor()); book.setIsbn(form.getIsbn()); itemService.saveItem(book); return "redirect:/"; } @GetMapping("/items") public String list(Model model) { List<Item> items = itemService.findItems(); model.addAttribute("items", items); return "items/itemList"; } @GetMapping("items/{itemId}/edit") public String updateItemForm(@PathVariable("itemId") Long itemId, Model model) { Book item = (Book) itemService.findById(itemId); // 캐스팅이 별로 좋진 않음 BookForm form = new BookForm(); form.setId(item.getId()); form.setName(item.getName()); form.setPrice(item.getPrice()); form.setStockQuantity(item.getStockQuantity()); form.setAuthor(item.getAuthor()); form.setIsbn(item.getIsbn()); model.addAttribute("form", form); return "items/updateItemForm"; } @PostMapping("items/{itemId}/edit") public String updateItem(@PathVariable("itemId") Long itemId, @ModelAttribute("form") BookForm form) { // Book book = new Book(); 컨트롤러에서 어설프게 엔티티 생성하지 말기 // book.setId(form.getId()); // book.setName(form.getName()); // book.setPrice(form.getPrice()); // book.setStockQuantity(form.getStockQuantity()); // book.setAuthor(form.getAuthor()); // book.setIsbn(form.getIsbn()); // // itemService.saveItem(book); itemService.updateItem(itemId, form.getPrice(), form.getName(), form.getStockQuantity()); return "redirect:/items"; } }ItemService.javapackage jpabook.jpashop.service; import jpabook.jpashop.domain.item.Item; import jpabook.jpashop.repository.ItemRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service @Transactional(readOnly = true) @RequiredArgsConstructor public class ItemService { private final ItemRepository itemRepository; @Transactional public void saveItem(Item item) { itemRepository.save(item); } public List<Item> findItems() { return itemRepository.findAll(); } public Item findById(Long itemId) { return itemRepository.findOne(itemId); } public void updateItem(Long itemId, int price, String name, int stockQuantity) { Item findItem = itemRepository.findOne(itemId); findItem.setPrice(price); findItem.setName(name); findItem.setStockQuantity(stockQuantity); } } HTML파일은 모두 복사붙여넣기 하였습니다.
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
혹시 김영한 선생님 자바 중급/고급 강의 정확히 언제 나오는지 알 수 있을까요
혹시 김영한 선생님 자바 중급/고급 강의 정확히 언제 나오는지 알 수 있을까요~강의 듣는데 이해 안가는 문법들이 많아서요.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
여전히 에러가 발생
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. @Test void 상품주문_재고수량초과() throws Exception { //give Member member = createMember(); Item item = createBook("베렌과 루시엔", 39000, 10); int orderCount = 11; //when orderService.order(member.getId(), item.getId(), orderCount); //then assertThrows(NotEnoughStockException.class, () -> {orderService.order(member.getId(), item.getId(), orderCount);}, "재고 수량 예외가 발생해야 한다."); }JUNIT5 환경에서 이런식으로 해보았는데, 테스트 통과가 안되고 여전히 jpabook.jpashop2.exception.NotEnoughStockException: need more stock 에러가 발생하네요 ㅠㅠㅠ 구글링도 해보고 커뮤니티글도 다 찾아보았는데,여전히 해결되지 않아 글 남깁니다. 다른 분들이랑 똑같이 코드 작성한거 같은데 뭐가 문제일까요..
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
JUNIT5, assertj활용한 테스트 코드입니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.junit4로 해보려고 해도 org.junit.Assert 가 import 불가능하여 따로 테스트 코드를 짜보았습니다. @Test void 상품주문() throws Exception { //give Member member = new Member(); member.setName("jung"); member.setAddress(new Address("서울", "한강로", "12452")); em.persist(member); Book book = new Book(); book.setName("베렌과 루시엔"); book.setPrice(39000); book.setStockQuantity(10); em.persist(book); int orderCount = 3; //when Long orderId = orderService.order(member.getId(), book.getId(), orderCount); //then Order getOrder = orderRepository.findOne(orderId); assertThat(OrderStatus.ORDER).as("상품 주문시 상태는 ORDER.").isEqualTo(getOrder.getStatus()); assertThat(getOrder.getOrderItems().size()).as("주문한 상품 종류 수가 정확해야 한다.").isEqualTo(1); assertThat(getOrder.getTotalPrice()).as("주문 가격은 가격 * 수량이다.").isEqualTo(39000 * orderCount); assertThat(book.getStockQuantity()).as("주문 수량만큼 재고가 줄어야 한다.").isEqualTo(7); }이런식으로 최대한 강사님의 코드와 비슷한 결과가 나오게 해보았는데, 혹시 차이가 있을까요??
-
미해결실습으로 배우는 선착순 이벤트 시스템
쿠폰 개수를 증가시키는 코드에서 궁금한 점이 있습니다.
public Long increment() { return redisTemplate .opsForValue() .increment("coupon_count"); } ---------------------------------------------------- public void apply(Long userId) { Long count = couponCountRepository.increment(); if (count > 100) { return; } couponRepository.save(new Coupon(userId)); }코드에서 쿠폰을 100개 발급할 수 있도록 했는데만약 동시에 100만 개의 요청이 들어오게 되면 redis에도 똑같이 100만 번의 요청이 가서 100개의 요청을 제외한 나머지 불필요한 요청을 redis가 처리해야 되는 문제가 발생할 것 같습니다. public void apply(Long userId) { Long count = couponCountRepository.getCount(); if (count > 100) { return; } couponCountRepository.increment(); couponRepository.save(new Coupon(userId)); }그래서 쿠폰 개수를 먼저 가져와서 검증 후 개수를 올리게 되면 또다시 Race Condition이 발생할 것 같습니다.실무에서는 어떠한 방식으로 코드를 작성하시는지 궁금합니다!
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
자바 스프링부트 버전 선택
스프링부트 버전이 2.7x 버전은 없는데 무엇으로 선택해야 하나요?
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
orderService도 rabbitmq를 어디선가 사용하나요??
order-service의 application.yml를 살펴보고, 다른부분을 살펴봐도 rabbitmq관련 설정이나, 코드는 전혀없던데 다른곳에서 자동으로 사용하는건가요?? -e "spring.rabbitmq.host=rabbitmq" 왜 rabbitmq 설정을 추가해야만 위 로그가 안뜨는지 질문드립니다. 그리고 왜 동일한 설정으로 local로 실행할때는 위 로그가 안뜨다가 왜 docker로 실행할때만 뜨는걸까요??server: port: 0 spring: application: name: order-service datasource: driverClassName: org.h2.Driver # url: jdbc:h2:mem:testdb # username: sa # password: url: jdbc:mariadb://localhost:3306/mydb driver-class-name: org.mariadb.jdbc.Driver username: root password: test1357 jpa: hibernate: ddl-auto: update show-sql: true h2: console: enabled: true settings: web-allow-others: true path: /h2-console cloud: openfeign: micrometer: enabled: true eureka: instance: instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}} register-with-eureka: true fetch-registry: true service-url: defaultZone: http://127.0.0.1:8761/eureka logging: level: com.example.orderservice.client: DEBUG pattern: level: '%5p [%X{traceId:-}-%X{spanId:-}]' management: tracing: sampling: probability: 1.0 propagation: consume: B3 produce: B3_MULTI zipkin: tracing: endpoint: "http://localhost:9411/api/v2/spans" endpoints: web: exposure: include: refresh, health, beans, busrefresh, info, metrics, prometheus application.yml파일입니다
-
미해결백엔드 개발자 성능 개선 초석 다지기
nGrinder 성능테스트 질문이 있습니다.
현재 서버를 aws 같은거로 띄우진 않아서 로컬로 성능테스트를 진행하고 있는데 원래 서버를 띄운 후 성능테스트를 진행해야 하는건가요? 아니면 로컬로 해도되는건지..성능테스트 돌릴때마다 성능이 다르고 어떨땐 아예 실패하고 어떨땐 성공하고 그러네요..그래서 성능개선 전후 비교가 힘듭니다
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
k8s환경에서 Pod 수에 따른 컨슈머 인스턴스 개수가 궁금합니다.
spring kafak consumer의 경우 @Component public class KafkaConsumer { @KafkaListener(topics = "myTopic", groupId = "myGroup") public void listen1(String message) { System.out.println("Listener 1 - Received message: " + message); }위와 같은 로직에서 @KafkaListener에 따라서 컨슈머 인스턴스가 생성된다고 파악했는데, 스프링 어플리케이션과 카프카 컨슈머 인스턴스의 상관관계에 있어 질문이 있습니다. k8s환경에서 5개의 pod로 애플리케이션이 실행될 경우 컨슈머 인스턴스가 5개 생성 되는걸까요?그렇다면 Pod의 개수에 맞춰서 파티션 개수를 조절해야하는지, 파티션의 개수가 pod의 개수보다 적다면 할당되지 않은 리스너는 컨슈밍하지 않는지 궁금합니다. 스프링 어플리케이션 = 카프카 컨슈머 인스턴스 인가요?아래 처럼 코드를 작성하면 컨슈머 인스턴스가 몇개 띄워지는지 궁금합니다@Component public class KafkaConsumer { @KafkaListener(topics = "myTopic", groupId = "myGroup") public void listen1(String message) { System.out.println("Listener 1 - Received message: " + message); } @KafkaListener(topics = "myTopic", groupId = "myGroup") public void listen2(String message) { System.out.println("Listener 1 - Received message: " + message); }
-
미해결스프링 시큐리티
login_proc의 존재에 대한 간략한 설명입니다
정답부터 말하면 내부적인 정상 처리를 위해 일치시켜줘야 합니다.이름이 logic_proc일 필요는 없고요 login 폼의 action이랑, 설정에서 등록해주는 loginProcessingUrl과 맞추기만 하면 됩니다. 저는 /login_perform으로 했는데요.사용자가 로그인 폼에서 아이디와 비밀번호를 입력하면 UsernamePasswordAuthenticationFilter에서 주된 처리를 하게 되잖아요. 본격적인 처리가 들어가기 전에 이 처리를 할지 말지는 요청 Url와 HttpMethod를 검사해야 합니다. 이게 맞아야 해당 요청에 대한 정확한 필터를 작동시키니까요.UsernamePasswordAuthenticationFilter의 실행 여부는 AbstractAuthenticationProcessingFilter가 합니다. doFilter에서 이뤄지죠? 다음 코드를 확인해봅시다.바로 requiresAuthentication 함수를 디버깅해봅시다.저matcher에 loginProcessingUrl에서 설정한 Url과 요청Url이 매치되는지 확인합니다. 해당 Url을 matcher에 설정할 때 시큐리티 내부적으로 POST를 이미 넣어줬습니다. 그렇기 때문에 로그인 폼에서 POST 방식을 지정하고 Action Url을 /login_perform 으로 설정하면 시큐리티에서 설정한 값과 동일하므로 이후의 로그인 절차가 진행될 수 있죠.조금 더 첨언하자면 커스텀 로그인을 하는 순간 로그아웃도 반드시 커스텀해줘야 합니다. 서버 구동 시 설정 쪽에 관련 코드가 있어요. 디폴트 로그인이 아니면 디폴드 로그아웃도 설정 안 한다. 그래서 커스텀 로그인을 하면 DefaultLogoutPageGeneratingFilter가 설정되지 않아요. 그래서 강사님이 /logout 컨트롤러를 생성하신 겁니다. 다시 결론: 로그인 기능을 커스텀할 때 로그인 폼의 action url와 시큐리티에서 loginProcessingUrl은 일치시켜주기만 하면 된다.
-
미해결[개정판 2023-11-27] Spring Boot 3.x 를 이용한 RESTful Web Services 개발
Rest-API 작명
안녕하세요 현제 스터디 중인 대학생입니다. Rest-API 작명 때문에 궁금해서 질문을 남겼습니다.// 관리자 회원관리 GET /v1/admin/members// 전체 회원 조회 GET /v1/admin/members/1// 회원 상세 조회 PUT /v1/admin/members/1// 회원 수정 // 관리자 매장관리 GET /v1/admin/restaurants// 전체 매장 조회 GET /v1/admin/restaurants/1// 매장 상세 조회 POST /v1/admin/restaurants현제 이런 식으로 URL 정보를 미리 작성하고 규약을 따라 코드를 작성하는데, 궁금한 점이 GET /v1/admin/restaurants/search 이 방식과 GET /v1/restaurants/가게 이름 둘 중 어는 것이Rest API가 맞는지 궁금합니다.
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
오류로 인해 실행 안됨
이 에러가 발생합니다.설정에서 Gradle을 jdk로 바꿔봤습니다.아래 3가지를 선택 취소 후 다시 선택했습니다.java 폴더 -> Sources Tab 선택test 폴더 -> tests Tab 선택resource 폴더 -> resource Tab 선택그래도 해결이 안되기에 이렇게 글을 적습니다. 해결: 우측 상단에 Main으로 되어있었는데 이것을 LibraryAppApplication으로 바꾸니 해결되었습니다.
-
미해결백엔드 개발자 성능 개선 초석 다지기
이미 퇴사한 시점에서의 최선의 선택
현재 말씀하시는 대상이 완전 저에게 일치하는데 이미 퇴사를 한 시점이라 주니어 개발자로써 적용하기가 쉽지 않을 것 같은데 이럴때 는 어떻게 하는 게 좋을까요? 강의 내용대로 실무내에서는 문제 없이 기능들을 구현하였는데 이직을 위한 이력서 작성 시 성능 개선 부분에서 작성할 부분이 없네요
-
미해결스프링 시큐리티
top.html에 로그인 링크를 만들어서 로그인을 해봤습니다
안녕하세요.지금 개발환경은 스프링부트, 시큐리티 모두 최신 버전입니다.permitAll()로 static resource를 허용하고 싶은데요. 설정을 분리하니까 login 하고 나서 css 파일이 화면에 나타납니다. 로그인 버튼은 top.html에 링크를 추가했습니다.ignoring()을 쓰거나 설정을 통합하면 문제가 해결되긴 합니다. http.authorizeHttpRequests(registry -> registry .requestMatchers("/mypage").hasRole("USER") .requestMatchers("/messages").hasRole("MANAGER") .requestMatchers("/config").hasRole("ADMIN") .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() .requestMatchers("/").permitAll() .anyRequest().authenticated());하지만 저는 설정을 두 개로 유지하면서, permitAll()을 써도 문제가 없었으면 하는데, 제가 아는 선에서는 방법을 찾기 어려워 질문드리게 됐습니다. @Order(0) @Bean SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests(registry -> registry .requestMatchers("/mypage").hasRole("USER") .requestMatchers("/messages").hasRole("MANAGER") .requestMatchers("/config").hasRole("ADMIN") .requestMatchers("/").permitAll() .anyRequest().authenticated()); http.formLogin(Customizer.withDefaults()); http.logout(config -> config.logoutSuccessUrl("/")); http.userDetailsService(userDetailsService); return http.build(); } @Order(1) @Bean SecurityFilterChain resource(HttpSecurity http) throws Exception { http.authorizeHttpRequests(registry -> registry .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() .anyRequest().authenticated()); return http.build(); }감사합니다.
-
해결됨스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
No DataSource specified 에러가 뜹니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]선생님, 스프링을 통해서 제가 생각한 대로 설계해서 잘 만드는 백엔드 개발자가 꿈인 사람입니다.앞부분에는 천천히 강의 설명을 잘 해주셔서 이상없이 잘 따라왔는데요.순수 jdbc 강의부터 복사 붙여넣기로 강의 속도가 빨라지면서낯선 메소드와 코드들이 보여서 이해가 안가고 있습니다.실무에서 쓰는데 순수 jdbc 원리는 꼭 깊이 있게 짚고 나가지 않아도 될까요? 어렵습니다ㅠㅠ 게다가 SpringConfig에서 JdbcMemberRepository로바꾸면서 db접근도 안되고 화이트라벨 에러만 계속 발생하고 있습니다..ㅠ chatgpt에 물어보고 검색을 해도 이 문제를 도저히 해결할 수가 없네요.. [에러 내용]java.lang.IllegalArgumentException: No DataSource specified윈도우에서 사용하고 있으며, 스프링부트 버전은 3.xh2 데이터베이스도 최신버전으로 설치해서 실행했습니다.[구글 드라이브]https://drive.google.com/file/d/1HzXNwnwBzOTJIvrzJZisrvoO2LkbYIDI/view?usp=sharing