묻고 답해요
167만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
em.find 1차 캐시 SELECT 2번 발생
[SELECT 2번 발생]강의에 설명된 내용과 달리 저는 em.find(Member.class, 100L); 두 번 호출하였을 때 SELECT 문이 두 번 발생하였습니다.혹시 설정 차이로 다른 결과가 나온 것일까요? 추가로 지금 확인해보니 tx.commit 이후에도 데이터베이스에 저장도 되지 않고, insert 쿼리가 나가지 않네요.. 어떤 문제에서 잘못된 것일까요?전체 코드 보내드립니다.package hellojpa; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.EntityTransaction; import jakarta.persistence.Persistence; import java.util.List; public class JpaMain { public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); /** * 영속성 컨텍스트1 - 1차 캐시 */ try { // // 비영속 Member member = new Member(); member.setId(100L); member.setName("HelloJPA"); System.out.println("=== BEFORE ==="); em.persist(member); // 영속 System.out.println("=== AFTER ==="); Member member1 = em.find(Member.class, 100L); Member member2 = em.find(Member.class, 100L); System.out.println("result = " + (member1 == member2)); tx.commit(); } catch (Exception e) { tx.rollback(); } finally { em.close(); emf.close(); } } }
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
엔티티 직접 사용 - 외래키값 지연로딩
엔티티 직접 사용 - 외래키값에서 아래 JPQL은 지연로딩설정 해놨지만where 에서 team에 대한 조건값이 있으니 즉시로딩 된걸로 이해하면 될까요?!select m from Member m where m.team = :team
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
3장 Querydsl 검색처리 수업따라하다가 에러가 나요..
TodoServiceImpl.java 작성중에 중간에 소스가 갑자기 바뀌었는데요.그리고 아래와 같이 작성하셔서 따라 작성하였는데요.PageResponseDTO<TodoDto> responseDTO = PageResponseDTO.<TodoDto>withAll() .dtoList(dtoList) .pageRequestDTO(pageRequestDTO) .totalCount(result.getTotalElements()) .build();뭘 놓친건지... 위와 같이 에러 나서 진행이 안돼요. 카페 들어가서 해당 강의 소스도 찾아봤는데수업하신 내용이랑 조금 다르게 되어있긴 하지만 사용법에는 큰 차이는 없어 보이거든요 ㅠlombok도 많이 안써봐서... 잘 모르겠어요..
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
querydsl 빌드 문제 질문드립니다.
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요.강사님처럼 src/main/java 하위에 querydsl 폴더가 생기진 않고 build 폴더쪽에 파일이 생기고 있습니다. 하지만 에러는error: Could not find class file for 'jpabook.jpashop.domain.OrderItem'.이렇게 생기고 있습니다.clean > build 하면 Q파일이 생기지않고celan > other > compileQuerydsl 하면위와 같이 엔티티를 찾을 수 없다는 에러가 발생하고 있습니다. //querydsl buildscript { ext { queryDslVersion = "5.0.0" } } plugins { id 'java' id 'org.springframework.boot' version '3.4.5' id 'io.spring.dependency-management' version '1.1.7' //querydsl 추가 id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" } //querydsl apply plugin: "com.ewerk.gradle.plugins.querydsl" group = 'jpabook' version = '0.0.1-SNAPSHOT' java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-devtools' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.9.0' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5-jakarta' //queryDSL //implementation "com.querydsl:querydsl-jpa:5.0.0:jakarta" //annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" } tasks.named('test') { useJUnitPlatform() } //querydsl 추가 시작 def querydslDir = layout.buildDirectory.dir("src/main/java").get().asFile querydsl { jpa = true querydslSourcesDir = querydslDir } sourceSets { main.java.srcDir querydslDir } compileQuerydsl{ options.annotationProcessorPath = configurations.querydsl } configurations { compileOnly { extendsFrom annotationProcessor } querydsl.extendsFrom compileClasspath } //querydsl 추가 끝제 build.gradle 이며어노테이션 설정도 이렇게 되어 있지만 에러가 발생하고 있습니다!확인부탁드립니다!
-
미해결실전! Querydsl
중급문법 벌크연산에서
mulitply 예제가 잘려있습니다. 수정부탁드립니다.
-
해결됨코드로 배우는 React 19 with 스프링부트 API서버
JWTUtil 에 심각한 버그 존재?
안녕하세요.최초 10분이 지난 후 refreshToken 정보를 이용하여, new accessToken 을 발급받는 것을 적용한 이후에는 오랜 시간이 지나도 다시 new accessToken 발급을 하지 않는 현상이 있더군요.의문을 가지다가 Redis 에 연동하고, ttl JWT:ACCESS:user8@aaa.com 로 accessToken의 남은 시간을 체크해보니 문제가 있다는 걸 확인했습니다.chatGPT 로 점검해서 아래와 같은 코드로 수정한 이후 정상 동작하는 거 같습니다.public static String generateToken(Map<String, Object> valueMap, int min) { SecretKey key = null; try { key = Keys.hmacShaKeyFor(JWTUtil.key.getBytes("UTF-8")); } catch (Exception e) { throw new RuntimeException(e.getMessage()); } // 1. claims 복사 및 exp/iat 제거 Map<String, Object> claims = new HashMap<>(valueMap); claims.remove("exp"); claims.remove("iat"); // 2. 발급시간/만료시간 생성 Date now = Date.from(ZonedDateTime.now().toInstant()); Date exp = Date.from(ZonedDateTime.now().plusMinutes(min).toInstant()); // 3. JWT 생성 return Jwts.builder().header() .add("typ", "JWT") .add("alg", "HS256") .and() .issuedAt(now) .expiration(exp) .claims(claims) .signWith(key) .compact(); }
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
질문있습니다.
안녕하세요,기존 JS기반 강의의 자료는 받을 수 없는 걸까요?유투브로 올려주시긴 했으나코드를 보면서 진행해보고 싶습니다...
-
미해결스프링부트를 이용한 웹 프로그래밍: 웹사이트 이렇게 만드는 거예요!
로그인 후 (인증완료) /member/modify 접근불가
로그인 후 /member/modify 접근할려고하면302 코드 뜨는데 로그인 인증이 됐는데도 자꾸/member/modify 로 접근하면 로그인폼으로 돌아가는데 뭐가문제일까요 ..?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
JPA Cretieria와 QueryDSL
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]강의만 들었을때 JPA Cretieria와 QueryDSL 둘다 JPQL빌더 역할 하는것 같은데 자세한 차이 궁금합니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
값 타입 컬렉션 PK
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]Hibernate: create sequence Member_SEQ start with 1 increment by 50 Hibernate: create table ADDRESS ( MEMBER_ID bigint not null, city varchar(255), zipcode varchar(255) ) Hibernate: create table FAVORITE_FOOD ( MEMBER_ID bigint not null, FOOD_NAME varchar(255) ) Hibernate: create table Member ( MEMBER_ID bigint not null, USERNAME varchar(255), city varchar(255), zipcode varchar(255), primary key (MEMBER_ID) ) Hibernate: alter table if exists ADDRESS add constraint FKsuulxb5rmrxvb83yr43ox86wn foreign key (MEMBER_ID) references Member Hibernate: alter table if exists FAVORITE_FOOD add constraint FKjchfnr69biisfgjdpoe82rpa4 foreign key (MEMBER_ID) references Member 위 그림에서 FAVORITE_FOOD 테이블에서 FOOD_NAME, ADDRESS 테이블에서 CITY, ZIPCODE 가 왜 PK가 되는지 궁금합니다.
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
findOrders()에 fetch join 사용하지 않은 이유는 이거인가요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]N+1 문제 발생시에는 fetch join 을 사용하고,컬렉션이 포함된 조회는 XtoOne 도 fetch join 을 유지했었습니다. 이번 강의의 findOrders 에는 fetch join 이 아닌 일반 join 을 사용한 이유는findOrderItems 에서 OrderItems 를 따로 조회하기 때문에 일반 join 을 사용한건가요? Order -> member 는 ManyToOneOrder -> delivery 는 OneToOne 이라서 N+1 문제는 발생하지 않는다고 이해는 하고 있습니다!컬렉션타입인 OrderItems 는 별개의 쿼리를 이용해서 들고 오기 때문에 XtoOne 연관관계 엔티티를 조회하기 위해 fetch join 을 사용하지 않았다고 이해하면 될까요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
JPA 유의점과 V3.1 에 대한 질문입니다!
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용] 안녕하세요. JPA 유의점과 V3.1 에 대한 질문입니다!지금까지 수업을 들으며 제가 요약한 내용은Repository 에서 Entity 를 조회한다.해당 조회에서 N+1이 발생한다면 -> 회원목록을 조회한다면 N+1 이 발생하지 않지만, 회원목록 + 가장 최근에 주문한 상품1개 도 함께 조회를 한다면 N+1 문제가 발생한다. > 목록데이터를 조회하는데, 목록데이터 각각의 PK를 FK로 참조하는 다른 테이블의 데이터를 함께 조회하는데 Lazy 로딩일 경우 N+1 문제가 발생한다.N+1 이 발생할 경우 fetch join 으로 변경한다.해당 fetch join 쿼리에 컬렉션(리스트 등) 타입이 존재할 경우 select 문에서 컬렉션을 조회하는 쿼리를 지우고, XtoOne 연관관계에 있는 엔티티 조회는 fetch join 을 유지한다. + hibernate.default_batch_fetch_size 설정한다. 이렇게 정리했습니다! 혹시 정정해야하는 부분이 있을까요?? V3.1 에 대한 질문은, 조회쿼리에서 OrderItem은 없지만, Controller 에서의 @Data static class OrderDto { private Long orderId; private String name; private LocalDateTime orderDate; private OrderStatus orderStatus; private Address address; private List<OrderItemDto> orderItems; public OrderDto(Order order) { orderId = order.getId(); name = order.getMember().getName(); orderDate = order.getOrderDate(); orderStatus = order.getStatus(); address = order.getDelivery().getAddress(); orderItems = order.getOrderItems().stream() .map(orderItem -> new OrderItemDto(orderItem)) .collect(toList()); } } @Data static class OrderItemDto { private String itemName; //상품명 private int orderPrice; //주문가격 private int count; //주문수량 public OrderItemDto(OrderItem orderItem) { itemName = orderItem.getItem().getName(); orderPrice = orderItem.getOrderPrice(); count = orderItem.getCount(); } } 여기서 List<OrderItemDto> orderItems부분으로 인하여 proxy 로 들고 왔던 것을 실제 DB조회를 하여orderItems 에 값을 채워넣는 게 맞나요?
-
미해결스프링부트를 이용한 웹 프로그래밍: 웹사이트 이렇게 만드는 거예요!
메일 보내는 메서드에서
MemberEntity updateMember = memberRepository.save(findedMemberEntity);if(updateMember != null) {메일전송} 여기서 if(updateMember != null) 대신try catch 로 묶어서 하는것도괜찮나요 ?
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
docker mariadb 실행
백업은 안하려고 한참 헤메다, 결국 백업으로 해결했네요..ㅎ..환경: window pc에 mariadb client 버전을 설치함dump 생성client 버전이기 떄문에, “mariadb prompt” 를 실행해서 아래의 명령어 실행(cmd에서 mariadb, mysql 명령어 동작 안함)# 생성할 위치로 이동하시거나, 덤프 생성할때 경로 작성하시요. cd "어느 경로"/docker_file # 덤프 생성 mysqldump -u root -p --all-databases > all.sql Dockerfile 생성# Docker Hub에서 공식 MariaDB 이미지 사용 FROM mariadb:latest # 초기화 시 자동 실행될 SQL 복사 COPY ./all.sql /docker-entrypoint-initdb.d/ # 포트 개방 EXPOSE 3306 이미지 생성 및 컨테이너 실행docker build -t [당신의 게정은?]/mariadb:1.0 . docker run -d \\ -p 13306:3306 \\ --name mariadb \\ --network ecommerce-network \\ -e MARIADB_ROOT_PASSWORD=[당신의 root 비번]\\ kimjinwon1432/mariadb:1.0 =============== 추가 ==============강사님께서 알려주신 방법으로 진행해봤어요.일단, 제 pc의 mariadb 설치경로가 "C:\Program Files" 였기 때문에, mariadb폴더 내의 data 폴더와 그 하위 파일 및 디렉터리를 C: 밑에 우리가 사용하는 docker_file 폴더에 넣었습니다* Program Files를 경로로 잡으시면 13에러 코드가 발생합니다. 이는 권한 관련 문제이므로 cli에서 사용하시는 계정에 대해서 mariadb 폴더 내부에 권한을 주셔도 소용이 없어요.* 이 과정은 이전에 설치한 mariadb 이미지가 있으면 삭제?하거나 이미지의 이름을 변경해서 진행하세요.(전 삭제함) * 제 pc의 mariadb 의 버전이 11.4.2여서, docker에서 사용할 수 있는 가장 근접한 버전으로 진행했습니다. docker run -d -p 13306:3306 --network ecommerce-network \ -e MARIADB_ROOT_PASSWORD=[비번] \ --name mariadb -v "C:\study\SpringCloud\docker_files\data:/var/lib/mysql" \ mariadb:11.4.7이렇게 하시면 docker exec -it ~~~ /bin/bash를 통해서 db에 접속 후 데이터베이스를 확인하면 로컬에서 작업했던 db의 데이터가 docker로 전해진 것을 확인 할 수 있어요.
-
해결됨Spring Boot, AWS로 백엔드 서비스 한 사이클 완성하기
다운받은 강의자료 압축풀기가 안되요
다운은 되는데 압축풀기에서 오류가 뜨네요. 파일에 문제가 있을까요?
-
해결됨Spring Boot와 React로 배우는 초간단 REST API 게시판 만들기
DB에 데이터가 저장이 되지 않습니다.
내용을 다 따라한것 같은데 DB에 저장이 안되네요..
-
해결됨스프링 DB 2편 - 데이터 접근 활용 기술
h2 인메모리 테스트중 예약어 충돌날 경우 대처방법
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 아니오2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]개인프로젝트에서 운영 및 로컬DB는 mysql을 사용하고 유저 테이블 이름을 user라고 하였고, User.java 엔티티 클래스를 만들었습니다.테스트DB는 h2 인메모리db를 사용하여 진행했는데, h2에서 user 는 예약어이기 때문에 테스트 도중 sql구문이 맞지 않아 실패했다고 합니다.Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Syntax error in SQL statement "insert into [*]user (login_id,password,user_id) values (?,?,default)"; expected "identifier"; SQL statement: 위 문제를 해결하기 위해 구글링해보았는데mysql에서 테이블 명을 바꾸고 자바 코드의 User 이름들도 바꾼다.User.java 엔티티클래스에@Table(name = "\"user\"")를 추가하여 sql 구문이 생성될때 "user" 로 생성되게 하여 H2의 예약어 user를 피한다.테스트 db를 mysql로 설정한다.이런 방법들을 찾았습니다. 일단 추가적인 사이드 이펙트가 발생하지 않는 1번으로 했는데, 만약 김영한 선생님이라면 이 방법들중 어떤 방법을 사용할지, 아니면 또 다른 방법이 있는지 궁금합니다.
-
해결됨스프링 DB 2편 - 데이터 접근 활용 기술
커스텀aop와 트랜잭션을 같이 사용할때 우선순위에 관한 질문
트랜잭션도 @Transactional을 사용하면 일종의 aop로 작동하지 않습니까?@Transactional은 그러면 우선순위가 어느정도인지 궁금합니다.그리고 커스텀aop를 적용할때 트랜잭션보다 먼저 적용해야하는 건지도 궁금합니다.그리고 @Repository를 사용하면 sql 체크 예외를 DataAccess 언체크 예외로 바꿔주는 aop가 있다는데, 그러면 @Repository가 @Transactional보다 우선순위가 낮아야지 언체크 예외로 변한 예외를 보고 트랜잭션이 롤백을 할텐데, 그러면 Repository는 무조건 Transactional 보다 우선순위가 낮게 만들어진건지도 궁금합니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
group_concat 사용자 정의 함수 등록하는 방법
섹션 11-9 JPQL 함수에서, 사용자 정의 함수(group_concat) 구현 시 Hibernate(6.4.2.Final)버전을 사용할 때 가능한 방법 공유드립니다. 강의에서 MyH2Dialect 클래스 구현하는 대신, FunctionContributor를 구현public class MyH2FunctionContributor implements FunctionContributor { @Override public void contributeFunctions(FunctionContributions fc) { TypeConfiguration typeConfig = fc.getTypeConfiguration(); SqmFunctionRegistry registry = fc.getFunctionRegistry(); // ✅ 문자열 반환 타입을 직접 조회 BasicType<?> stringType = typeConfig.getBasicTypeRegistry().getRegisteredType("string"); // ✅ 사용자 정의 함수 등록 registry.registerPattern( "group_concat", "group_concat(?1)", stringType ); } } 서비스 등록 (META-INF/services/org.hibernate.boot.model.FunctionContributor)jpql.MyH2FunctionContributor 예시 쿼리Team team = new Team(); team.setName("teamA"); em.persist(team); Member member = new Member(); member.setUsername("관리자"); member.setAge(10); member.setType(MemberType.ADMIN); Member member2 = new Member(); member2.setUsername("사용자2"); member2.setAge(10); member2.setType(MemberType.USER); member.changeTeam(team); em.persist(member); em.persist(member2); em.flush(); em.clear(); String query = "select group_concat(m.username) from Member m"; List<String> result = em.createQuery(query, String.class).getResultList(); for (String s : result) { System.out.println("s = " + s); }결과 쿼리Hibernate: /* select group_concat(m.username) from Member m */ select group_concat(m1_0.username) from Member m1_0s = 관리자,사용자2
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
실제 실무에서 RestController 하나로만 개발이 가능한가요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]RestController 는 JSON 으로 응답을 돌려주는 역할을 하며 redirect 와 같은 것을 사용하지 않는 이상 view페이지로 리턴해주는 건 따로 없고, 권장하지 않는다고 배웠습니다. view 페이지 이동 및 view 에서 표출할 단순한 데이터는 @Controller , "기능"에 관련된 것은 @RestController 을 사용해야할 거 같습니다. 예를 들어, 1. 회원목록 페이지 이동은 Controller 및 회원목록조회(DB조회) -> member_list.html 리턴2. 회원상세보기 페이지 이동은 Controller 및 회원상세조회(DB조회) -> member_detail.html 리턴3.회원 상세보기페이지에서의 수정 기능은 RestController 및 JSON 응답 리턴 이렇게 구현이 되어야할 거 같더라구요 !RestAPI 및 @RestController 형식을 사용한다하더라도 전체를 RestController 를 사용하는 건 구현에 무리도 있고 권장되지 않는 거 같기도 하더라구요.패키지 구조로 치면domain(package)-member(package)-controller(package) > MemberApiController.java, MemberController 이렇게요! RestController 하나만 사용하게 된다면메인페이지에서 [회원목록] 을 클릭한다.클릭과 동시에 axios/fetch 등의 비동기 통신이 이루어진다.비동기통신의 url 은 회원목록데이터를 return 하는 @RestController 메서드에 도착한다.응답이 성공하면 axios/fetch 비동기 메서드에 200코드와 회원목록데이터를 전달한다.응답이 성공하면 그 데이터를 회원목록페이지를 보여주는 @RestController 에 다시 전달한다.해당 RestController 메서드가 전달받은 데이터를 view페이지에 표출한다.순서가 이렇게 될 거 같은데5번의 회원목록 페이지를 보여주는 RestController 또한 view 페이지를 열수없으니, redirect 와 같은 걸 사용해야할 거 같더라구요. 상당히 복잡하고 비효율적인거 같아 RestController(기능) 와 Controller(view 페이지 이동) 을 분리해서 사용하기로 결정했는데 실제 현업/실무에서도 @RestController(ResponseEntity) 와 @Controller(ModelAndView) 를 위처럼 기능 / view 페이지 이동 이렇게 구분해서 사용하나요?아니면 RestController(ResponseEntity) 하나만 사용하나요?만약 구분해서 사용해야한다면MemberApiController 는 ResponseEntity 메서드MemberController 는 ModelAndView 메서드 를 작성하는 것을 염두에 두고 있습니다 !