묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 부트 - 핵심 원리와 활용
외부 파일 주입
안녕하세요, 외부 파일 경우, application.properties를 만들어두고,서 강의와 같이 url=dev.db.com23 username=dev_user23 password=dev_pw23를 저장해 두었더니, 2023-03-18T10:44:03.240+09:00 INFO 17556 --- [ main] hello.EnvironmentCheck : env url=dev.db.com232023-03-18T10:44:03.240+09:00 INFO 17556 --- [ main] hello.EnvironmentCheck : env username=um9502023-03-18T10:44:03.240+09:00 INFO 17556 --- [ main] hello.EnvironmentCheck : env password=dev_pw23 라고 출력이 됩니다. username만 제대로 나오지 않는데요, 현재 출려고딘 um950이 제 윈도우 계정이거든요...뭔가 더 높은 우선순위로 잡혀있는 것 같은데 이 부분은 어디서 고치거나/확인 할 수 있을까요...?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
에러 처리에 대해 질문이 있습니다.
에러 처리를 할 수 있는 방법들이 많아지니 어느 상황에 어느 코드를 작성해야하는지 생각이 많아져서 질문 남깁니다. 일단 제가 알고 있는 방법은 1. try,catch로 에러를 잡기2.체크 에러를 런타임 에러로 변환해서 throw하지 않기3. @ExceptionalHandler로 에러 처리하기이렇게 세 가지를 강의를 통해 알게 됐습니다. 이러한 것들을 실무 때 어느 상황에서 써야 좋을 지 실무에서 오래 있던 김영한 이사님의 생각이 듣고 싶어서 질문 드립니다. 개인적으로는 그냥 interface의 구현체에서 try catch로 모든 에러를 잡으면 interface에서도 throw sqlExcpetion같이 메서드 이름에 적을 필요도 없으니 체크 에러를 런타임 에러로 변환할 필요도 없을 거라고 생각합니다. 그리고 @ExceptionalHandler의 사용 용도도 생각해봤는데 잘 모르겠습니다. @ExceptionalHandler를 사용하게 되면 체크 에러가 생기게 되면 메소드 이름에 throw를 해서 에러를 던져야하는데 그럼 체크 에러에 종속적이게 될 거라고 생각합니다. 그래서 try catch로 모든 걸 해결하면 되지 않을까? 라는 결론에 도달하게 됐습니다. 공부할수록 이 생각에서 확장이 안되는데 실무에서 김영한 이사님은 어느 식으로 하는 지 간단하게라도 알려주시면 감사할 것 같습니다.
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
MemberRepositoryV0를 try-with-resources를 사용해 refactoring 해봤습니다..
자바와 관련된 것이라 조금 조심스럽긴 하지만, 해당 클래스를 아래와 같이 try-with-resources를 사용해 refactoring 해 보았습니다.테스트 코드는 잘 돌아가는데, 아래와 같이 변경해도 상관없나해서 질문 남깁니다!감사합니다!package hello.jdbc.repository; import hello.jdbc.connection.DBConnectionUtil; import hello.jdbc.domain.Member; import lombok.extern.slf4j.Slf4j; import java.sql.*; import java.util.NoSuchElementException; /** * JDBC - DriverManager 사용 */ @Slf4j public class MemberRepositoryV0 { // jdbc를 이용해 member 객체 저장 public Member save(Member member) throws SQLException { String sql = "insert into member(member_id, money) values (?,?)"; try (Connection conn = getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, member.getMemberId()); pstmt.setInt(2, member.getMoney()); pstmt.executeUpdate(); return member; } catch (SQLException e) { log.error("db error", e); throw e; } catch (NullPointerException e) { log.info("NPE 발생", e); } return member; } public Member findById(String memberId) throws SQLException { String sql = "select * from member where member_id = ?"; try (Connection conn = getConnection(); PreparedStatement pstmt = createPreparedStatement(sql, conn, memberId); ResultSet rs = pstmt.executeQuery()) { if (rs.next()) { Member member = new Member(); member.setMemberId(rs.getString("member_id")); member.setMoney(rs.getInt("money")); return member; } else { throw new NoSuchElementException("member not found memberId=" + memberId); } } catch (SQLException e) { log.error("db error", e); throw e; } catch (NullPointerException e) { log.info("NPE 발생", e); } return new Member(); } private PreparedStatement createPreparedStatement(String sql, Connection conn, String memberId) throws SQLException { PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, memberId); return pstmt; } public void update(String memberId, int money) throws SQLException { String sql = "update member set money=? where member_id=?"; try (Connection conn = getConnection(); PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setInt(1, money); pstmt.setString(2, memberId); int resultSize = pstmt.executeUpdate(); log.info("resultSize={}", resultSize); } catch (SQLException e) { log.error("db error", e); throw e; } catch (NullPointerException e) { log.info("NPE 발생", e); } } public void delete(String memberId) throws SQLException { String sql = "delete from member where member_id = ?"; try (Connection connection = getConnection(); PreparedStatement preparedStatement = connection.prepareStatement(sql)) { preparedStatement.setString(1, memberId); int resultSize = preparedStatement.executeUpdate(); log.info("resultSize={}", resultSize); } catch (SQLException e) { log.error("db error", e); throw e; } catch (NullPointerException e) { log.info("NPE 발생", e); } } private static Connection getConnection() { return DBConnectionUtil.getConnection(); } }
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
서버에 이미지와 텍스트가 혼재되어 있는 게시글 내용을 저장하고 싶습니다.
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예[질문 내용]안녕하세요. 스프링 MVC 2편 강의를 전부 듣고 JPA 강의를 어느정도 공부한 상태에서 디테일한 게시판 기능을 제공하는 서버를 만들기 위해서 도메인을 설계 중입니다. 네이버 카페, 블로그 등 흔히 접할 수 있는 플랫폼에서 제공하는 게시판은 본문 작성 시 단순히 첨부 파일을 업로드할 수도 있지만, 본문 내에 이미지를 삽입하는 방식으로도 작성하는 방식으로 구현되어 있습니다. 실제로 제가 설계하려는 프로젝트에서도 위와 비슷한 기능을 제공하고 싶습니다. 이렇게 작성한 게시글을 전송하는 방식을 구상하는 부분에서 해결하기 어려운 점이 있습니다.예를 들어, 다음과 같은 게시글 내용을 전달해야 한다고 가정해봅시다.본문내용 1<사진1>본문내용 2<사진2>본문내용 3....위와 같은 상황에서 단순히 이미지를 업로드할 뿐만 아니라 각각의 이미지의 위치가 본문의 어느 부분에 존재하는지에 대한 정보까지도 알고 있어야 합니다. 여기서 저는 두 가지의 해결 방법과 문제점들을 떠올려봤습니다.프론트단에서 본문내용 작성 시 사진과 text가 동시에 들어올 경우, 각각 image 등의 binary 형태로 전송할 수 있는 태그와 plain text를 담을 수 있는 tag로 구분하고 name에 접미사를 붙이는 등의 방법으로 여러 개의 구분되는 part로 보낸 후, 서버 단에서 각각의 file image를 resolve하여 저장 -> 그래서 content를 실제로 db에 어떻게 저장해야되는데?이미지와 text가 포함된 html 정보 자체를 전송하여, 서버측에서 각 tag를 파싱하여 이미지 정보가 들어올 때만 별도로 file resolve 후 S3 등 스토리지 내에 저장된 경로로 재구성하여 전체 markup 문서를 clob형태로 저장 -> html을 직접 파싱하는 데에 어려움이 있을 것 같음, 로컬에 저장된 이미지파일을 url로 넘길 경우, 서버 측에서 어떻게 이미지 주소를 알 수 있지?두 가지 방법 중 어느 것을 선택해도 한계점이 명확히 보여서 어떤 방식으로 접근해야 할지 조언을 구하고 싶습니다. 읽어주셔서 감사합니다.
-
미해결스프링 핵심 원리 - 기본편
getInstance()와 DIP
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]싱글톤은 DIP를 위반한다는 설명에서(기존)public MemberService memberService(){ return new MemberServiceImpl(memberserviceRepository());}(싱글톤 패턴 적용 시)public MemberService memberService(){ return MemberServiceImpl.getInstance();}에서 구체 클래스에 의존하기 때문에 DIP를 위반한다고 하셨습니다. 하지만 AppConfig에는 객체 인스턴스를 연결하기 위해 어차피 구체클래스를 사용하는데, DIP를 위반한다고 하는 이유가 뭔지 궁금합니다!
-
미해결재고시스템으로 알아보는 동시성이슈 해결방법
낙관적 락, 비관적 락 말고 항상 분산락을 쓰는게 좋을까요?
공부하다가 의문이 생겼는데요,낙관적 락 - 충돌 잦으면 락 획득 재시도 로직 때문에 성능 안좋음비관적 락 - 충돌 잦으면 낙관적 락보다 성능좋음.분산 락- 스케일 아웃된 DB 환경에서도 사용 가능- Redis 라이브러리마다 다른데 Lettuce는 스핀락으로 구현되서 재시도 많으면 불리 Redisson은 pub-sub 기반이라 재시도 많으면 유리정확하진 않지만 이렇게 알고있습니다.질문은1. 잘못 알고 있나요?2. 제가 공부한게 맞다면, 무조건 비관적 락, 낙관적 락 말고 분산락 + Redis(Lettuce/Redisson) 쓰는게 좋은건가요?
-
미해결
jsp 체크박스 기능 사용
안녕하세요 현재 spring을 이용하여 개발 중인 초보개발자입니다.다름이 아니라 현재 spring의 ajax 통신 기능을 사용하여 체크박스 기능을 구현 중인데, 생각보다 잘 풀리지 않아 질문하고자 합니다.javascript에 배열을 선언 후 체크박스가 요청하는 데이터베이스 데이터를 mybatis로 구분하여 불러오려 하는데, 배열의 size가 null로 나와 조회가 되지 않습니다. 현재 화면에 데이터를 불러오는데 getmapping을 사용 중인데, 구글링을 하다보니 postmapping이 적합하다고 하는데 혹시 어떤 이유 때문인지 궁금합니다.만약 꼭 바꿔야한다면 getmapping -> postmapping 으로 변경하려 하는데, 컨트롤러와 ajax의 type을 get에서 post로 변경하였는데 아예 데이터가 올라오지 않는 현상이 발생했습니다.혹시 어떻게 형식을 바꾸면 되는지 궁금합니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Formatter 질문입니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]Formatter를 이용해서 String("10,000) 객체를 Number(10000)으로 바꾸어주었습니다. 그런데 Controller에서는 Integer 형식으로 받고있는데, Number에서 Integer로의 타입캐스팅은 스프링이 해주는건가요?
-
미해결스프링 핵심 원리 - 기본편
@PreDestory 가 없어도 실행되는 이유 및 사용하는 경우
@PostConstruct의 경우 주석처리 하면 init 메서드가 실행되지 않더라구요. 근데 @PreDestory의 경우 주석처리를 해도 close 메서드가 실행되던데 @Bean 애노테이션을 이용하여 NetworkClient를 등록 할 때 destoryMethod가 생략됐고, 추론형이 발동해서? 실행되는 거 맞나요? 그렇다면 반대로 @PostConstruct의 경우에는 추론형이 없을까요? 없다면 이유는 무엇인가요? 이 @Postconstruct와 @PreDestory는 언제 사용하나요? Bean의 생명 주기를 알아야 할 필요가 있을까요?
-
미해결스프링 핵심 원리 - 기본편
널 포인트 익셉션이 터지는 이유가 뭔가요 ?
강의 21분쯤에 스프링에서 돌리는게 아니라 순수하게 돌리기 때문에 널포인트 익셉션이 터진다고 말씀하시는데 스프링 컨테이너인 ApplicationContext.getBean()을 통해 인스턴스를 가져오는게 아니라 new OrderServiceImpl() 를 했기 때문에 @Autowired가 동작하지 않게 된 것 맞나요 ? 24분쯤 설명을 보시면 스프링 테스트코드를 이용할 수 있다고 하시면서 CoreApplicationTest를 보여주시는데 CoreApplicationTest 클래스를 제외한 test코드를 작성하는 클래스 에서는 스프링 컨테이너가 작동하지 않는 것인가요? 일반 메서드 주입이랑 생성자 주입이랑 차이점이 무엇인가요? 메서드명을 init으로 하느냐, 클래스 이름으로 하느냐의 차이인가요? 메서드 주입의 이점이 있나요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
트랜잭션 롤백 시 Insert 쿼리
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]여기에 질문 내용을 남겨주세요.위와 같이 테스트를 구현하고 테스트 실행 시 Insert 쿼리가 나갑니다. 그런데 예외가 발생했기 때문에 롤백이 되어서 또는 테스트의 트랜잭션 디폴트 값이 Rollback이라서 Insert 쿼리가 나가지 않아야 하는 것 아닌가요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
Task :test FAILED이 뜹니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]gradlew build를 하면 이런 에러가 발생합니다. 인텔리제이 설정에서 build Tools > Run tests using 항목을 IntelliJ IDEA로 변경을 해보았으나 에러는 동일하게 발생했지만 해결책을 모르겠습니다.
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
DriverManager 가 Driver 후보들을 가지는 방법
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)예[질문 내용]안녕하세요. 데이터베이스 연결을 보면서 궁금증이 생겼습니다.DriverManager 는 제공받은 url 을 핸들링할 수 있는 Driver 구현체를 찾는다고 이해했는데요.DriverManager 는 위의 검증 이전에 어떻게 Driver 구현체들을 후보로 리스트로 들고있게되나요?
-
미해결실전! Querydsl
querydsl에서 oneToMany 관계인데 Many쪽 검색이 필요할 때 어떻게 해야하나요?
예를 들어 Order와 OrderItem이 있는데 Order의 검색을 동적쿼리로 검색해야해서 querydsl을 사용하고 있는 상황입니다. 그 중 검색조건이 OrderItem의 이름으로 검색해서 Order의 목록을 가져와야하는데 Order와 OrderItem을 조인하고 where절에 OrderItem의 이름으로 조회하는 방법 말고는 없을까요? 그럴 경우 distinct를 쓰거나 따로 중복 제거 로직을 넣어야해서ㅜ 혹시 다른 방법이 있나 문의드립니다.이런 경우에는 양방향 연관관계를 맺어주고 해결해도 될까요?
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
H2 실행 반응없음 윈도우
안녕하세요처음 강의를 들을 때 h2 데이터베이스를 설치하여 진행하였을 때는 잘 진행되었는데,강의를 다시 들으며 h2를 실행시켜보니 갑자기 실행이 되지 않습니다.환경변수는 잘 설정되어있고명령 프롬프트로 질문들 검색해서 나온 모든 해결방법을 실행해보았는데, 반응이 없고h2 console 바로가기를 클릭해도 반응이 없습니다...백신관련은 제거했습니다.14.200 말고 최근버젼으로도 도전해봤습니다.어떻게 해야 해결될까요?ㅠㅠ https://www.inflearn.com/questions/543652/%EC%9C%88%EB%8F%84%EC%9A%B0-h2-console-bat-%EC%8B%A4%ED%96%89-%EC%95%88%EB%90%A8-%ED%95%B4%EA%B2%B0%ED%95%A8*이 방법도 시도해봣으나 안됩니다 C:\tools\h2\bin>/"h2.bat"'/"h2.bat"'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는배치 파일이 아닙니다.
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
Spring Boot 3.X distinct 관련
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]주문 조회 V3: 엔티티를 DTO로 변환 - 페치 조인 최적화Spring Boot 3.2버전에서 실습 중에, distinct 옵션을 사용하지 않고도 distinct 옵션을 넣은 것처럼 Row가 2줄 출력됩니다. 이것저것 코드를 확인하다가 Spring Boot를 2.x 버전으로 내린 후에 다시 확인해보았는데, 그제서야 강의에 나오는 것처럼 중복 데이터 4개가 나옵니다. 혹시 이것 관련해서 jpa에서 업데이트가 된 것인지요..? 검색 능력이랑 문서 능력 찾아보는 능력이 딸려, 한참 찾아보다 여기에 질문합니다 ㅜㅜ 실례가 안된다면 이러한 내용을 어떻게 찾는지도 알게 될 수 있다면 좋을거 같습니다!
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
생성메소드
생성메소드에 대해 잘 이해가 안가네요어떨때 사용하게 되는건가요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
주문 생성 메서드 createOrder() 질문
==[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]주문 생성 메서드인 createOrder()의 파라미터로 가변인자인 OrderItem...을 사용하셨는데 List를 사용하지 않고 특별히 가변인자를 사용하신 이유가 있을까요?
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
반납 기능 관련해서 질문드립니다.
강사님 안녕하세요. 이번 강의에서 BookService에 returnBook을 만들어주었는데요, 실행을 하면 반납을 했음에도 불구하고, 같은 이름의 사용자가 이미 반납한 책을 또다시 반납해도 오류가 발생하지 않고, 반납에 성공했다고 결과가 나오는 것을 알게되었습니다.제 생각에는 UserLoanHistory history = userLoanHistoryRepository.findByUserIdAndBookName(user.getId(), request.getBookName()) .orElseThrow(IllegalArgumentException::new);해당 코드에서 findby부분에is return도 추가하여 userLoanHistoryRepository.findByUserIdAndBookNameAndIsReturn(user.getId(), request.getBookName(), false)로 해주어야 대출중인 책을 반납하는 동작이 한번 이루어지고, 중복반납이 안될거 같은데 혹시 제가 이해를 잘못한건지 궁금합니다. 감사합니다!
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
static class 의 new 생성자
강의에서 중요한 부분은 아닙니다만, CheckedTest 클래스와 UnCheckedTest 클래스 내부 클래스에서 각각 Service, Repository 클래스를 내부 static 으로 선언을 했잖아요? 그런데 static으로 선언되었음에도 두 클래스는, new Service(), new Repository() 로 생성이 되는 것이 이해가 안됩니다. 감사합니다.