블로그
전체 7#카테고리
- 백엔드
#태그
- 인프런
- 워밍업
- 클럽
- 스터디
- 1기
2025. 03. 30.
0
워밍업 클럽 3기 BE 클린코드&테스트 - 4주차 발자국
학습 내용섹션 7. Mock을 마주하는 자세Test Double: 테스트에서 실제 객체를 대체하여 사용하는 가짜 객체의 총칭 (대역 객체) Dummy아무 것도 하지 않는 깡통 객체Fake단순한 형태로 동일한 기능을 수행하나, 프로덕션에서 쓰기는 부족한 객체Stub테스트에서 요청한 것에 대해 미리 준비한 결과를 제공하는 객체 (그 외에는 응답하지 않음) 상태 검증 / StatefulSpyStub이면서 호출된 내용을 기록하여 보여줄 수 있는 객체 일부는 실제 객체처럼 동작시키고 일부만 Stubbing할 수 있다.Mock행위에 대한 기대를 명세하고, 그에 따라 동작하도록 만들어진 객체 행위 검증 / Stateless @Mock, @MockBean, @Spy, @SpyBean, @IngectMocks@Mock진짜 객체가 아닌 가짜 객체를 생성해서 (테스트에) 사용Spring Context와 무관@InjectMocks나 수동으로 주입 가능단위 테스트에서 사용@MockBeanSpring에 의존적Spring 빈에 등록된 객체를 Mock으로 대체Spring에서 의존성 주입을 해줌통합 테스트에 사용@Spy실제 객체의 일부 동작만 Mocking (객체의 일부만 stub 처리)Spring Context와 무관단위 테스트에 사용@SpyBeanSpring에 의존적Spring Bean에 등록된 객체를 Spy로 대체통합 테스트에 사용@InjectMocks@Mock 또는 @Spy로 만든 객체를 의존성으로 주입(해주는 대상 클래스 지정) 섹션8. 더 나은 테스트를 작성하기 위한 구체적 조언 테스트 하나 당 목적은 하나한 문단에 하나의 주제만논리 구조(분기문, 반복문)은 최대한 지양하기 완벽한 제어테스트 환경 조성시 모든 조건을 완벽하게 제어할 수 있어야 함현재 날짜/시간, 랜덤 등 제어할 수 없는 변수 사용 지양 사용해야 하면 파라미터로 넘겨서 상위 계층에서 관리테스트 환경의 독립성, 테스트 간 독립성 보장given절에서 팩토리 메서드 대신 순수한 생성자/builder 기반으로 객체 생성 공유 자원 사용 XTest FixtureTest Fixture: 테스트를 위해 원하는 상태로 고정시킨 일련의 객체한 눈에 들어오는 Test Fixture 구성하기각 테스트마다 명시해 한 눈에 들어오도록 테스트 작성 @BeforeEach, @BeforeAll, @AfterEach, @AfterAll Test Fixture 클렌징 Test Fixture 클렌징 deleteAll()deleteAllInBatch()@ParameterizedTest, @DynamicTest@ParameterizedTest: 동일한 테스트를 다른 입력값으로 테스트할 때 사용 @DynamicTest: 시나리오 기반으로 테스트할 때 사용 (테스트를 실행할 때 동적으로 생성하는 방식) 수행 환경 통합하기테스트도 비용이기 때문에 환경을 통합해야 한다.통합 클래스를 만들어 서버 뜨는 횟수를 최소화 private method testprivate method는 테스트 수행할 필요 없음 테스트에서만 필요한 코드만들어도 되지만 최대한 지양 섹션 9. Appendix지만 중요한 것들학습 테스트잘 모르는 기능, 라이브러리, 프레임워크를 학습하기 위해 작성하는 테스트여러 테스트 케이스를 스스로 정의하고 검증하는 과정을 통해 구체적인 동작과 기능을 학습Spring Rest Docs 테스트 코드를 통한 API 문서 자동화 도구API 명세를 문서로 만들고 외부에 제공함으로써 협업을 원활하게 한다. 미션Day 16https://inf.run/2pwfMDay18https://inf.run/jgrRS 회고드디어 열심히 달려온 워밍업 클럽이 끝났다. 한달 동안 가독성 좋은 코드를 작성하는 방법과, 코드를 테스트하는 법에 대해 정말 많은 것을 배웠다. 솔직히 후반부에는 진도를 따라가기도 벅차게 느껴졌고, 미션도 몇번 놓쳤지만 포기하지 않고 완주해낸 것 자체가 뿌듯하다. 또한 그간 코드를 작성하며 크게 신경쓰지 않았던 것들에 대해 완전히 다른 시각을 접할 수 있어서 정말 알차고 좋은 시간이었다. 아직 학습한 내용을 온전히 소화하지는 못했지만, 다시한번 강의 내용을 복습하며 공부해보고, 수료식 전까지 놓친 미션들도 다시 수행해볼 것이다.
백엔드
2025. 03. 23.
0
워밍업 클럽 3기 BE 클린코드&테스트 - 3주차 발자국
학습 내용섹션6. Spring & JPA 기반 테스트Layered Architecture: 관심사의 분리 때문에 레이어를 분리해야 함Persisitence Layer쿼리가 의도대로 작성되었는지 확인쿼리를 구현하는 기술이 바뀌어도 기능의 동작을 보장하도록 테스트를 작성@DataJpaTestBusiness Layer비즈니스 로직 흐름과 트랜잭션 처리 검증트랜잭션을 보장하는지 확인@TransactionalPresentation Layer외부 요청, 파라미터 위주로 검증의존관계를 가짜 객체를 사용해(Mocking) 환경 재현@WebMvcTest, @MockBean, @MockMvc테스트 코드단위 테스트: 작은 코드 단위를 독립적으로 검증하는 테스트통합 테스트: 여러 모듈이 협력하는 기능을 통합적으로 검증하는 테스트 회고이번주는 Layered Architecture 구조의 Layer별로 테스트를 작성해보며 TDD를 적용하는 과정을 배웠다.점점 수업 내용을 이해하고 내 것으로 만들기 어려워지는 것 같다. 워밍업 클럽 시작 전 커리큘럼을 보고 학습양이나 난이도가 만만치 않겠다고 생각하긴 했지만, 직접 수업을 들어보니 내 부족한 점들이 더 잘 보인다. 이번주가 특히나 힘들었는데, 진도를 맞추는 데 급급해 강사님이 라이브코딩하는 것을 보며 코드를 따라치는게 고작이었다. 그래서인지 수업을 다 들어놓고도 내가 제대로 배우고 이해한 게 맞나?라는 의문이 머릿속을 떠나지 않았던 한 주였다. 우선은 완주를 목표로 진도표에 맞춰 학습하고, 일정이 끝난 후 강의를 다시 들으며 개념을 보강하는 과정이 필요할 것 같다.
백엔드
2025. 03. 16.
0
워밍업 클럽 3기 BE 클린코드&테스트 - 2주차 발자국
강의 수강Readable Code: 읽기 좋은 코드를 작성하는 사고법 학습 내용 요약섹션6. 코드 다듬기좋은 주석주석의 양면성주석은 코드로 표현할 수 있는 내용을 대체하는 것으로, 지양해야 함의사 결정의 히스토리를 코드로 표현할 수 없을 때 주석으로 설명해야 함으로 필수임좋은 주석: 코드를 통해 최대한 표현했음에도 전달하지 못한 정보가 남았을 때 사용하는 주석나열 순서변수: 사용하는 순서대로 나열 (인지적 경제성 고려)객체의 공개/비공개 메서드공개 메서드는 기준(중요도, 종류 등)을 가지고 배치비공개 메서드는 공개 메서드에 언급된 순서대로 나열나열 순서로도 의도와 정보 전달 가능 패키지 나누기패키지는 문맥으로써의 정보를 제공패키지 분리 시 유의할 점적절히 쪼개야 함 (너무 안 쪼개면 관리 어렵고, 너무 쪼개도 유지보수 어려움)공통으로 사용하는 클래스들의 패키지 분리/변경은 충돌을 야기함패키지 구조는 가능한 한 초기 프로젝트 설정 때 잘 고민해서 나누기기능 유지보수하기버그 잡기알고리즘 교체IDE 도움 받기 정렬 단축키: Ctrl + Alt + Llinting, style - sonarlint, editorconfig섹션7. 리팩토링 연습메서드 추출로 추상화 레벨 맞추기Optional객체에 메시지 보내기객체의 책임과 응집도IO 통합일급컬렉션display()Order 추출추상화 관점의 차이구현에 초점을 맞춘 추상화 vs. 도메인 개념에 초점을 맞춘 추상화섹션8. 기억하면 좋은 조언들 능동적 읽기복잡하고 엉망인 코드를 읽고 이해해야 할 때 리팩토링하면서 읽기공백으로 단락 구분메서드와 객체로 추상화이해한 내용 주석으로 표기오버 엔지니어링필요한 적정 수준보다 더 높은 수준의 엔지니어링 (불필요)적절하게 적용해서 리팩토링할 것은탄환은 없다항상 정답인 기술은 없다한계까지 연습해보고, 적정 수준, 적정 시점을 깨닫기섹션3. 단위 테스트단위 테스트작은 코드 단위(클래스 or 메서드)를 독립적으로 검증하는 테스트검증 속도가 빠르고 안정적임수동 테스트, 자동화 테스트수동 테스트: 사람이 검증 (콘솔에 출력)자동화 테스트: 기계가 검증Junit5, AssertJJunit5: 단위 테스트를 위한 테스트 프레임워크AssertJ: 테스트 코드 작성을 돕는 테스트 라이브러리해피 테스트, 예외 케이스경계값 테스트:범위, 구간의 경계값으로 테스트 테스트하기 쉬운/어려운 영역 (순수함수)테스트하기 어려운 영역관측할 때마다 다른 값에 의존하는 코드외부 세계에 영향을 주는 코드 (외부에 의존하는 코드)순수 함수테스트하기 쉬운 코드같은 입력에 항상 같은 결과 출력 lombok@Data, @Setter, @AllArgsConstructor 지양양방향 연관관계 시 @ToString 순환 참조 문제섹션4. TDD: Test Driven DevelopmentTDD (테스트 주도 개발)프로덕션 코드보다 테스트 코드를 먼저 작성 -> 테스트가 구현 과정을 주도하도록 하는 방법론 레드-그린-리팩토링레드: 실패하는 테스트 작성그린: 테스트를 통과하는 최소한의 코딩리팩토링: 구현 코드 개선 및 테스트 통과 유지애자일(Agile) 방법론 vs. 폭포수 방법론익트트림 프로그래밍 (XP, eXtreme Programming) 빠른 개발 주기와 지속적인 피드백을 중심으로 하는 소프트웨어 개발 방법론 스크럼(Scrum), 칸반(kanban)스크럼: 짧은 개발 스프린트를 반복적으로 진행해 빠르게 결과물을 만들고 지속적으로 개선칸반: 지속적인 개선과 작업량 관리를 위해 작업을 시각적으로 표현섹션5. 테스트는 []다.-> 테스트 코드는 문서다프로덕션 기능을 설명하는 테스트 코드 문서다양한 테스트 케이스를 통해 프로덕션 코드를 이해하는 시각과 관점을 보완어느 한 사람이 과거에 경험했던 고민의 결과물을 팀 차원으로 승격시켜 모두의 자산으로 공유@DisplayName - 도메인 정책, 용어를 사용한 명확한 문장메서드명만으로는 테스트의 의도 파악 어려움DisplayName을 섬세하게 (모두가 명확히 알아볼 수 있도록)명사의 나열보다는 문장으로 기술테스트 결과까지 기술도메인 용어를 사용하여 한층 추상화된 내용을 담Given / When / Then - 주어진 환경, 행동, 상태 변화Given: 시나리오 진행에 필요한 모든 준비 과정When: 시나리오 행동 진행Then: 시나리오 진행에 대한 결과 명시, 검증BDDTDD에서 파생된 개발 방법시나리오에 기반한 테스트 케이스 자체에 집중하여 테스트JUnit vs. SpockSpcok: Groovy 언어로 BDD 패턴을 적용해서 테스트 코드를 작성 회고바쁜 한주를 정신없이 보내고 나니 벌써 중간점검을 할 시기라 좀 놀랐다. 이번주는 할일이 많아 강의 진도를 따라가기 급급한 나머지 Day 7 미션은 기한 내에 끝내지 못했다. 강의를 들으며 강사님을 따라할 때는 어렵지 않았는데, 막상 배운 내용을 적용해보려 하니 생각보다 막막하고 오랫동안 고민해야 했다. 아쉽게도 강의를 끝내지 못한 상태로 중간 점검 라이브에 참여했지만, 다른 사람들이 리팩토링한 코드와 그에 대한 강사님의 피드백을 보며 코드를 리팩토링하는 다양한 접근법을 확인할 수 있어서 좋았다. 동시에 내가 얼마나 부족한지 깨닫는 시간이기도 했다... 이번 스터디가 끝나더라도 배운 내용을 다시 한번 정리하고, 코드를 리팩토링하는 것도 꾸준히 연습해야겠다.칭찬하고 싶은점: 바쁜 한주였지만 들어야 하는 강의는 다 들었고, 지난주에 하지 못한 정리도 끝냈다.아쉬웠던 점: 너무 바빠서 이번주 미션은 끝내지 못했다.보완할 점: 다음 주말에 Day 7 미션을 끝내고, 다른 사람들이 리팩토링한 것과 비교하며 공부하기다음 주 목표: 강의와 미션 진도표에 맞춰서 끝내기
백엔드
2025. 03. 09.
0
워밍업 클럽 3기 BE 클린코드&테스트 - 1주차 발자국
강의 수강Readable Code: 읽기 좋은 코드를 작성하는 사고법 학습 내용 요약섹션2. 추상추상화: 구체에서 정보를 제거하고 함축하여 중요한 것만 남기는 과정구체화: 추상을 보고 유추를 통해 생략된 정보를 재현해내서 이해하는 과정추상화 레벨: 얼마나 추상화했는지를 나타내는 단계고수준: 추상화 레벨이 높다 (추상적)저수준: 추상화 레벨이 낮다 (구체적)적절한 추상화: 해당 도메인의 문맥 안에서 핵심 개념만 남겨서 표현하는 것-> 적절한 추상화는 복잡한 데이터/로직을 단순화하여 코드를 이해하기 쉽게 한다.이름 짓기, 메서드로 추출 + 메서드 선언부, 매직 넘버/매직 스트링 상수로 추출섹션3. 논리, 사고의 흐름뇌 메모리 적게 쓰기 (인지적 경제성)코드를 작성할 때 읽는 사람의 뇌 메모리를 최대한 적게 사용하도록 작성할 것Early returnearly return: 메서드를 분리해 끝낼 수 있는 케이스들은 빨리 return 해버려 아래쪽 케이스를 읽을 때 위쪽 케이스를 신경쓰지 않아도 되도록 하는 것 사고의 depth 줄이기코드를 읽는 사람의 사고가 적당한 수준으로(추상화된 정도로) 이해할 수 있도록 메서드 분리공백 라인으로 의미 단위 표현부정 연산자 제거예외 처리개발자가 의도한 예외개발자가 의도하지 않은 예외섹션4. 객체 지향 패러다임 관심사의 분리: 관심사에 따라 기능과 책임을 나누어 객체 생성높은 응집도낮은 결합도SOLIDSRP(단일 책임 원칙)하나의 클래스는 하나의 책임(관심사)만을 가져야 한다.SRP를 지킴으로써 각 클래스의 응집도를 높이고, 클래스 간의 결합도를 낮출 수 있다.OCP(개방-폐쇄 원칙)확장에는 열려 있고, 변경에는 닫혀 있어야 한다.기존 코드의 변경 없이도 시스템의 기능을 확장할 수 있어야 한다.추상화와 다형성을 활용해서 OCP를 지킬 수 있다.LSP(리스코프 치환 원칙)부모 클래스의 인스턴스를 자식 클래스의 인스턴스로 치환해도 정상 작동해야 한다.상속 구조에서 자식 클래스는 부모 클래스의 책임을 준수하고 행동을 변경하지 않아야 한다.ISP(인터페이스 분리 원칙)클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안된다.인터페이스를 필요한 기능 단위로 잘게 쪼개서 사용해야 한다.DIP(의존성 역전 원칙)상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다.둘 모두 추상화에 의존해야 한다.구체적인 구현 클래스가 아닌 추상화(인터페이스, 추상 클래스)에 의존해야 한다.섹션5. 객체 지향 적용하기 회고평소에 코드를 짤 때 좋은 코드 작성에 대해서 깊게 생각하지 않았다. 일단 코드가 제기능을 하는지가 가장 큰 관심사였고, 개인 프로젝트를 주로 해왔기 때문에 내가 이해할 수 있으면 가독성에 대해 크게 신경쓰지 않았기 때문이다. 그래서 읽는 사람보다는 코드를 작성하는 나의 입장에서 편한 방향으로 코드를 작성해왔다.강의를 왜 좋은 코드를 작성해야 하는지 명확하게 이해하고, 지금껏 생각하지 못한 관점을 배울 수 있었다. 또한 강사님을 따라 코드를 리팩토링하며 앞으로 코드를 짤 때 배운 내용을 적용하여 읽는 이가 이해하기 쉬운 코드를 짤 수 있도록 노력해야 겠다는 다짐을 하게 되었다.칭찬하고 싶은점: 바쁜 한주였지만 매일 학습 진도표에 맞춰서 미루지 않고 강의를 들었다.아쉬웠던 점: 강의 내용을 정리하며 학습하는 것은 조금 밀렸고, 미션 수행만으로는 학습한 내용을 내가 온전히 이해하고 있는지 확인하기 어려웠다.보완할 점: 이론적인 내용을 정리하는 것 외에도 배운 내용을 실제 코드에 적용해보는 연습이 더 필요할 것 같다.다음 주 목표: 강의와 미션 외에도 기존에 내가 짠 코드를 리팩토링 해봐야겠다. 미션코드 리팩토링리팩토링 전public boolean validateOrder(Order order) { if (order.getItems().size() == 0) { log.info("주문 항목이 없습니다."); return false; } else { if (order.getTotalPrice() > 0) { if (!order.hasCustomerInfo()) { log.info("사용자 정보가 없습니다."); return false; } else { return true; } } else if (!(order.getTotalPrice() > 0)) { log.info("올바르지 않은 총 가격입니다."); return false; } } return true; } 리팩토링 후 public static final String EMPTY_ORDER_MESSAGE = "주문 항목이 없습니다."; public static final String INVALID_TOTAL_PRICE_MESSAGE = "올바르지 않은 총 가격입니다."; public static final String NO_USER_INFO_MESSAGE = "사용자 정보가 없습니다."; public boolean validateOrder(Order order) { if (order.hasNoItem()) { log.info(EMPTY_ORDER_MESSAGE); return false; } if (order.hasInvalidTotalPrice()) { log.info(INVALID_TOTAL_PRICE_MESSAGE); return false; } if (order.hasNoCustomerInfo()) { log.info(NO_USER_INFO_MESSAGE); return false; } return true; }미션 해결 과정코드를 살펴보며 강의에서 배운 내용을 하나씩 적용해보았다.중첩되어 복잡한 분기문 -> Early return을 적용해 불필요한 else와 중첩된 분기 제거if문의 조건이 복잡함 -> if문의 조건을 메서드로 추출 분기 조건이 한번에 이해되도록 함 (사고의 depth 줄임)또한 order의 정보를 객체 외부에서 getter로 빼와 조작하는 대신 order가 처리하게 하여 캡슐화를if문 조건에 부정 연산자 존재 -> 별도의 메서드(hasNoItem())를 만들어 if문 조건의 부정 연산자(!) 제거매직 스트링이었던 로그 메시지를 상수로 추출해 가독성을 높이고 유지보수를 용이하게 함읽는 이가 의미 단위로 이해할 수 있도록 공백 라인 추가회고if문의 조건을 order의 메서드로 추출하는 과정에서 메서드의 이름을 짓는 것이 생각보다 고민되었다. 좀 더 많은 코드를 보며 이런 기능의 메서드의 이름을 관용적으로 어떻게 짓는지 공부해볼 필요가 있어 보인다.다시 보니 log.info()로 처리되고 있는 예외 처리 부분을 thrwo와 try-catch로 관리하는 것이 유지보수에 좋았을 것 같다는 생각이 든다.
백엔드
2024. 05. 19.
0
[인프런 워밍업 클럽 스터디 1기] BE 3주차 회고
세번째 발자국 인프런 워밍업 클럽 스터디에 참여하여 일주일을 보낸 후 쓰는 세번째 회고록. 학습 내용 Section 5 - 책 요구사항 구현하기연관관계두 개 이상의 테이블 또는 객체 간의 관계를 정의하는 방법엔티티 간 객체지향적 모델링 가능 연관관계의 주인 효과상대 테이블을 참조하고 있으면 연관관계의 주인연관관계의 주인이 아니면 MappedBy를 사용연관관계의 주인의 setter가 사용되어야만 테이블 연결 JPA 연관관계1:1 관계@OneToOne한 엔티티가 하나의 엔티티와만 연관된 경우두 엔티티 모두 @OneToOne 설정주인이 아닌 곳에 mappedBy 붙여야 함N:1 관계@ManyToOne여러 엔티티가 한 개의 엔티티와 연관된 경우연관관계의 주인은 무조건 N (숫자가 많은 쪽)N쪽(Many)에 @ManyToOne을 설정하고 1쪽(One)에 @OneToMany를 설정@ManytoOne은 단방향으로 사용 가능@JoinColumn연관관계의 주인이 활용할 수 있는 어노테이션필드의 이름이나 null 여부, 유일성 여부, 업데이트 여부 등을 지정N:M 관계@ManyToMany여러 엔티티가 여러 개의 엔티티와 연관된 경우구조가 복잡하고 테이블이 직관적으로 매핑되지 않아 사용하지 않는 것이 좋음casade 옵션한 객체가 저장되거나 삭제될 때, 그 변경이 폭포처럼 흘러 연결되어 있는 객체도 함께 저장되거나 삭제되는 기능orphanRemoval 옵션객체 간의 관계가 끊어진 데이터를 자동으로 제거하는 옵션 Section 6 - 생애 최초 배포 준비하기배포최종 사용자에게 SW를 전달하는 과정전용 컴퓨터에 우리의 서버를 옮겨 실행시키는 것 전용 컴퓨터에 코드를 옮기고 필요한 프로그램을 설치해 최종 사용자가 접속할 수 있도록 하는 것 profile같은 서버 코드를 실행시키지만, 실행 설정을 다르게 하고 싶을 때 사용DB 설정, 외부 API 키 등의 환경 구성을 다르게 할 수 있음local -> H2 DB, dev -> MySQL DBapplication.yml에서 ---로 옵션 구분 H2 DB경량 데이터베이스로, 개발 단계에서 많이 사용함디스크가 아닌 메모리에 데이터를 저장 가능개발단계에서는 수정사항이 많아 데이터가 휘발되는 것이 장점으로 작용ddl-auto 옵션을 create로 설정하면 테이블이 자동 생성/삭제가 되어 편리함 git코드를 쉽게 관리할 수 있도록 해주는 버전 관리 프로그램githubgit으로 관리되는 프로젝트의 코드가 저장되는 저장소코드는 어떠한 이유로든 소실될 가능성이 있기 때문에 백업용으로 사용프로젝트 공유, 협업, 배포 등에 활용 가능git 명령어git initgit 초기화해당 프로젝트를 git이 관리하겠다는 의미git remote add orign [각자의 주소]현재 프로젝트의 git 저장소를 주어진 주소로 설정git add . 작업 디렉토리의 모든 (변경된) 파일을 스테이징 영역(commit의 대상)으로 추가 (택배 상자에 파일 담기). 대신 [파일 이름]을 넣으면 특정 파일만 추가 가능git statusgit 상태 확인 (택배 상자 안에 담긴 내용 확인)git commit -m "메시지"스테이징 영역의 상태를 버전으로 기록 (택배를 포장하고 송장 붙이기)commit을 해주면 commit한 곳으로 언제든지 돌아올 수 있어 코드의 추가, 삭제가 자유로움commit 메시지에는 적고 싶은 내용(어떤 코드인지, 업데이트 내용 등)git push 원격 저장소(github)에 코드 변경분을 업로드 (택배 상자 github에 보내기)git pull원격 저장소의 코드를 다운로드.gitignoregit을 통해 관리하고 싶지 않거나 원격 저장소에 올리고 싶지 않은 파일을 관리하기 위한 파일파일의 경로나 파일 이름을 적어둠 AWS(Amazon Web Service)가입하면 우리가 배포할 전용 컴퓨터를 대여 가능지역을 한국으로 변경EC2 (Elastic Compute Cloud)탄력적으로 사용할 수 있는 원격 컴퓨터탄력적 : 원격으로 언제든 생성/제거 가능인스턴스 = 우리가 빌린 컴퓨터인스턴스 시작을 누른 후 설정이름 및 태그 : 우리가 빌릴 컴퓨터의 이름 지정애플리케이션 및 OS 이미지 : 기본적으로 Amazon Linux 2 AMI(아마존에서 관리하는 리눅스 운영체제)인스턴스 유형 : 우리가 빌릴 컴퓨터 사양키 페어(로그인) : 빌린 컴퓨터에 접속할 때 필요한 보안 파일네트워크 설정 : 빌린 컴퓨터에 접속할 때 접근을 허용할 IP, 포트 등을 설정하는 보안 그룹 생성스토리지 구성 : 빌릴 컴퓨터의 디스크 용량 결정 Section 7 - 생애 최초 배포하기EC2 접속키 페어를 이용하는 방법다운로드 받은 키 페어(pem key)키 페어 파일의 보안을 설정 : chmod 400 경로/키페어명 .pemchmod : 접근 권한 변경 (400)ssh 접속 : ssh -i 경로/키페어명.pem ec2-user@IPAWS 콘솔을 활용하는 방법AWS EC2 웹사이트에 접속해 연결 버튼 누르기 리눅스 명령어mkdir: 폴더를 만드는 명령어ls: 현재 위치에서 폴더나 파일을 확인하는 명령어ls -l : 더 자세한 정보 확인drwxrwxr-xd: 폴더(디렉토리)r: 읽는 권한, w: 쓰는 권한, x: 실행 권한rwx / rwx / r-x : 소유자 권한 / 소유 그룹 권한 / 아무나 접근할 때의 권한2 : 폴더에 걸려 있는 바로가기 개수ec2-user : 폴더 소유자의 이름ec2-user : 폴더 소유 그룹의 이름6 : 파일의 크기(byte)Dec 5 06:00 : 파일의 최종 변경 시각folder1 : 파일 이름cd(change directory): 폴더 안으로 들어가는 명령어cd .. : 상위 폴더로 이동pwd(print working directory): 현재 위치를 확인하는 명령어rmdir: 특정 폴더(디렉토리)를 제거하는 명령어 서버 설정 및 배포Git, Java, MySQL 설치코드를 가져오기 위한 Git서버를 구동할 Java사용할 데이터베이스 MySQL리눅스에서 스프링 배포 프로그램 설치Github에서 코드 가져오기git clone [저장소 주소]Swap 설정메모리가 부족할 경우 일부 디스크를 사용하도록 하는 설정 무료로 사용하는 EC2는 메모리가 적기 때문sudo dd if=/dev/zero of=/swapfile bs=128M count=16 : swap 메모리 할당sudo chmod 600 /swapfile : swap 파일에 대한 권한 업데이트sudo mkswap /swapfile : swap 영역 설정sudo swapon /swapfile : swap 파일 사용 설정sudo swapon -s : swap 성공 확인빌드chmod +x ./gradlew : gradLew를 사용할 수 있도록 쓰기 권한 설정./gradlew build -x test : gradle을 이용해 프로젝트 빌드 (테스트 코드 실행 X)서버 실행java -jar build/libs/[빌드한 파일명.jar] --spring.profiles.active=devJar 파일을 실행만 했는데 서버가 동작하는 이유 : Spring Boot에 톰캣이 내장되어 있기 때문톰캣 : 웹 애플리케이션 서버의 한 종류. 들어온 요청을 형식에 맞추어 스프링에 전달ctrl+c : 무언가를 중단하는 신호(실행중인 서버 중단)./gradlew clean : 현재 빌드되어 있는 결과물 제거 foreground vs backgroundforeground우리가 보고 있는 프로그램(현재 보이는 화면의 프로그램)background 우리가 보고 있지 않은데 실행 중인 프로그램ec2 접속을 종료해도 서버가 종료되지 않도록 하려면 서버를 background로 동작하게 해야 함nohup [명령어] &background 서버 다운ps aux : 현재 실행중인 프로그램 목록을 확인ps aux | grep java : java가 들어가는 프로그램을 확인(각 프로그램의 고유 번호 확인)kill -9 프로그램번호 : 해당 프로그램을 종료 DNS 적용가비아 회원가입 후 도메인 구매도메인 네임 등록 : 구매한 도메인과 빌린 EC2 서버 연결타입 : A호스트 : www값/위치 : EC2에서 빌린 인스턴스의 IP방화벽 설정접근 가능한 IP 혹 포트 설정 Section 8 - Spring Boot의 이모저모build.gradle빌드 스크립트gradle을 이용해 프로젝트를 빌드하고 의존성을 관리하기 위해 작성plugins : 프로젝트에 적용하고 싶은 플러그인 추가group : 프로젝트의 그룹version : 프로젝트의 버전sourceCompatibility : 프로젝트가 사용하고 있는 JDK 버전repositories : 외부 라이브러리나 프레임워크를 가져오는 장소 설정dependencies : 우리가 사용하는 라이브러리/프레임워크 표시tasks.named('test') : 테스트를 수행할 때 사용할 프레임 워크 Spring Boot의 특징(Spring과의 차이점)간편한 설정xml 대신 어노테이션 기반의 설정 가능기본적으로 필요한 것을 모두 자동 설정간단한 의존성 관리의존성을 필요한 것끼리 묶어 starter로 관리필요한 라이브러리나 프레임워크 하나 하나 적을 필요 없음강력한 확장성starter 추가만으로 필요한 기술을 도입할 수 있음 application.ymlYAML 문법 사용.yaml 또는 .yml : YAML의 확장자기본적으로 key : value 형식으로 데이터 정의각 계층은 들여쓰기를 통해 구분 (이를 통해 중복 제거)value로 들어갈 수 있는 타입 : 참/거짓, 숫자, 문자열(큰 따옴표 사용)배열은 - 사용#로 주석 표현application.propertiesapplicatoin.yml 대신 사용 가능key : value 형식으로 데이터 기록들여 쓰기를 통해 중복을 제거할 수는 없음application-프로파일 이름.properties 파일을 새로 만들어 profile 설정가독성 떨어짐lombok생성자, getter, setter, equals, toString 등 반복되는 보일러 플레이트 코드(boiler palte code)를 자동으로 생성해줌(반복되는 코드 제거)lombok 도입을 위한 설정lombok 의존성 추가IntelliJ lombok 플러그인 추가intelliJ Annotation Processor 설정 과제 6일차 과제 - Controller 3단 분리하기 https://shimmer-exoplanet-946.notion.site/6-18433147fcf443ad8597ac6b4fac8c43?pvs=4 문제 1번은 과제 4에서 만들었던 코드를 Controller - Service - Repository로 분리하는 과제였다. 수업 때 배운대로 API와 HTTP를 담당하는 부분만 Controller에 남겨두고 분기 처리나 로직을 담당하는 부분은 Service로, SQL을 이용해 DB와 통신을 담당하는 부분은 Repository로 분리해 주었다.문제 2번은 Repository를 DB에 데이터를 저장하는 MysqlRepository와 메모리에 데이터를 저장하는 MemoryRepository로 분리하는 과제였다. 기존 코드가 SQL을 이용해 DB에 데이터를 저장하는 방식이었으므로 그대로 MysqlRepository로 옮겨주고, MemoryRepository의 경우 List을 만들어 메모리에 과일에 대한 정보들을 저장했다. 기존 함수에서 id가 필요한 부분이 있었는데, mysql에서 id는 자동으로 생성되기 때문에 MemoryRepository에만 변수 num을 0으로 초기화해두고 createFruit가 호출될 때마다 1씩 증가하게 하여 id 대신 사용했다.문제 2개 모두 수업 시간에 했던 방식에서 크게 달라지지 않아 무난하게 해결했다. 확실히 코드를 계층별로 분리해두니 각 계층의 역할이 명확하게 보이고 코드가 간결해져 보기 편했다. 7일차 과제 - JPA 적용하기https://shimmer-exoplanet-946.notion.site/7-9e89cd27e6284807b1f448d6934b30fe?pvs=4문제 1은 과제 #6에서 만들었던 기능들을 JPA를 이용하도록 변경하는 것이었다. 수업에서 배운대로 Fruit 객체에 @Entity 어노테이션을 붙이고 각 필드를 테이블의 속성과 매핑되도록 적절한 어노테이션을 붙여주었다. 그후 FruitService에서 SQL을 문자열로 하나하나 타이핑하는 것이 아니라 JPA 함수를 이용해 DB와 통신하도록 수정하고, 추가적으로 필요한 함수는 FruitRepository 인터페이스에 선언해주었다.문제 2는 과일의 이름을 받아 지금까지 가계를 거쳐간 해당 과일의 개수를 세는 기능을 만드는 것이었다. 테이블에서 특정 이름을 가진 레코드의 개수를 세면 되는 것이라 countByName을 이용하여 원하는 값을 구했다. postman으로 테스트할 때 406 Not Acceptable 에러가 발생했는데, FruitCountResponse에 getter를 추가해주니 정상 작동했다.문제 3은 아직 판매되지 않은 과일 중 특정 금액 이상 혹은 특정 금액 이하의 과일 목록을 받아오는 기능을 만드는 것이었다. findAllByPriceGreaterThanEqual / findAllByPriceLessThanEqual을 이용해 특정 가격 이상/이하의 과일들을 가져온 후, Fruit의 isPurchase 함수를 이용해 팔린 과일인지 확인하여 팔리지 않은 과일들만 넣은 리스트를 반환해주었다.세 문제 모두 수업에서 배운 내용을 그대로 사용하거나 간단한 응용만 하는 방식이라 할 만 했다. 다만 stream과 같은 기능이 익숙하지 않아 해당 부분에서 발생한 에러를 해결하거나 특정 기능을 사용하는 방법을 찾기 위해 구글링을 해야 했다. 수업을 들으면서도 느꼈지만 자바 공부를 좀 더 해야겠다. 회고 다른 일들이 많이 겹쳐 공휴일이 끼어 있는데도 바쁜 한 주를 보냈다. 덕분에 저번주에 배운 내용을 다시 한번 복습하고 정리하겠다는 다짐은 지켰지만, 후반부 강의도 조금 밀려 늦게 들었고 따로 공부해보려던 것은 못한 점이 아쉽다. 이번주 강의는 새로운 개념을 익히기 보다는 배포 과정을 체험해보는 것에 가까웠던 점이 다행이었다. 강의를 따라하는 게 다지만 강사님의 화면과 다른 부분이 조금씩 있어 따로 찾아봐야 했는데, 그래도 진도를 마치고 배포까지 해내고 나니 굉장히 뿌듯하고 자신감이 붙었다. 처음에는 잘 사용하지 않는 리눅스나 AWS 부분에 대한 막연한 두려움이 있었는데 강의에서 세세히 설명해주니 어렵게만 느껴졌던 것들이 이해가 돼서 좋았다. 이번주로 스터디는 마무리되고 남은 것은 미니 프로젝트와 마무리 강의들 뿐이다. 다음주는 미니 프로젝트를 할 수 있는 부분까지만이라도 수행해보고, 시간이 된다면 강의에서 배운 것들을 전체적으로 복습하려 한다. 또한 스터디가 끝나더라도 한 주의 회고를 작성하는 것은 계속하는 습관을 들여보려 한다. 발자국을 작성하는 것은 이번 스터디를 통해서 처음 해봤는데, 한주동안 배운 내용을 한번씩 정리하는 것이 많은 도움이 되었다. 작성을 하는 동안 지난 한주를 돌아보며 아쉬운 점을 개선할 방법을 찾아보고, 다음주에 대한 계획을 세우게 되는 것도 좋았다. 이 마음가짐을 쭉 유지해서 스터디가 끝난 이후에도 계속해서 체계적으로 공부를 할 수 있도록 노력해야겠다.
백엔드
・
인프런
・
워밍업
・
클럽
・
스터디
2024. 05. 12.
0
[인프런 워밍업 클럽 스터디 1기] BE 2주차 회고
두번째 발자국 인프런 워밍업 클럽 스터디에 참여하여 일주일을 보낸 후 쓰는 두번째 회고록. Section 3 - 역할의 분리와 스프링 컨테이너스프링 컨테이너 : 서버가 시작되면 스프링 서버 내부에 만들어지는 거대한 컨테이너이 컨테이너 안에는 (여러) 클래스가 들어가게 된다.스프링 컨테이너 안에 들어간 클래스를 스프링 빈이라 한다.스프링 빈은 (미리 작성된 프레임워크의 코드에 의해) 서버가 시작될 때 자동으로 등록되기도 하고, 코더가 @RestController 등의 어노테이션을 이용해 직접 설정하기도 한다.이때 스프링 빈 간 필요한 의존성이 자동으로 설정되고, 인스턴스화도 이루어진다. 제어의 역전(IOC, Inversion of Control)객체를 생성하는 과정에서 스프링 컨테이너가 필요한 의존성을 자동으로 선택해서 주입해주는 방식new를 이용해 어떤 구현체를 사용할지 결정하지 않고, 스프링 컨테이너가 대신 결정해주는 방식의존성 주입(DI, Dependency Injection)컨테이너가 특정 구현체를 선택해 클래스에 넣어주는 과정 (필요한 의존성을 설정해주는 과정)스프링 빈 등록 방법@RestController, @Service, @Repository@Configuration(클래스에 붙임), @Bean(메소드에 붙여 메소드에서 반환된 객체를 등록)@Component(컨트롤러, 서비스, 레포지토리 외의 클래스를 추가적으로 등록하기 위해 사용)스프링 빈 주입받는 방법생성자를 이용해 주입(권장)Setter와 @Autowired 사용필드에 직접 주입(@Autowired 사용)@Qualifier Section 4 - 생애 최초 JPA 사용하기JPA(Java Persistence API) 자바 진영 ORM 기술 표준ORM(Object-Relational Mapping) : 데이터와 관계형 DB의 테이블을 짝짓는 방법(객체와 관계형 DB를 짝지어) 데이터를 영구적으로 저장할 수 있도록 정해진 Java 진영의 규칙영속성 : 서버가 재시작되도 데이터는 영구적으로 저장되는 속성HibernateJPA를 구현해서 코드로 작성한 구현체JPA는 단순히 API이므로, 실제 동작을 위해서는 JPA 구현체가 필요함내부적으로 JDBC를 사용JPA 어노테이션@Entity : 스프링이 객체와 테이블을 같은 것으로 바라봄Entity : 관리되어야 하는 데이터@Id : 해당 필드를 primary key로 간주@GeneratedValue : primary key는 자동 생성되는 값@Column : 객체의 필드와 Table의 필드를 매핑JPA를 사용하려면 반드시 기본 생성자가 필요함!JPA 기능save : 주어지는 객체를 저장하거나 업데이트findAll : 주어지는 객체가 매핑된 테이블의 모든 데이터를 가져옴findById : id를 기준으로 특정한 1개의 데이터 가져옴Spring Data JPA : 복잡한 JPA 코드를 스프링과 함께 쉽게 사용할 수 있도록 도와주는 라이브러리By 앞에 들어갈 수 있는 구절 정리find: 1건을 가져옴. 반환 타입은 객체가 될 수도 있고 Optional이 될 수도 있음findAll: 쿼리의 결과물이 N개인 경우 사용. List 반환exists: 쿼리 결과가 존재하는지 확인. 반환 타입은 booleancount : SQL의 결과 개수를 셈. 반환 타입은 longBy 뒤에 들어갈 수 있는 기능 정리And / OrGreaterThan : 초과GreaterThanEqual : 이상LessThan : 미만LessThanEqual : 이하Between : 사이에StartsWith : ~로 시작하는EndsWith : ~로 끝나는 트랜잭션(Transaction)쪼갤 수 없는 업무의 최소 단위 트랜잭션의 모든 로직이 성공적으로 수행되면 commit 처리되고, 예외가 발생하면 rollback 처리됨영속성 : 모든 로직을 성공시키거나, 로직들 중 하나라도 실패하면 모두 없었던 일로 하는 속트랜잭션으로 처리할 메서드 앞에 @Transactional을 붙여서 구현 영속성 컨텍스트(Persistence Context)테이블과 매핑된 엔티티 객체를 관리/보관하는 역할스프링에서는 트랜잭션 수행 중 엔티티 객체를 관리/보관하는 역할을 수행트랜잭션이 수행될 때 자동으로 생성되고, 트랜잭션이 종료되면 함께 종료됨영속성 컨텍스트의 특수 기능 :변경 감지(Dirty Check) : 영속성 컨텍스트 안에서 불러와진 엔티티는 별도의 save 필요 없이 엔티티의 변경 사항을 자동으로 감지하여 저장쓰기 지연 : 모든 SQL 요청을 트랜잭션이 commit될 때 모아서 한 번만 날림1차 캐싱 : 조회된 엔티티 객체를 id를 기준으로 캐싱하여 DB 접근 횟수를 줄임 Section 5 - 책 요구사항 구현하기 책 생성 APIHTTP Method : POSTHTTP Path : /bookHTTP Body (JSON) : 결과 반환 : X (HTTP 200 OK)대출 기능HTTP Method: POSTHTTP Path: /book/loanHTTP Body(JSON) :결과 반환 X : (HTTP 200 OK)반납 기능HTTP Method: PUTHTTP Path: /book/returnHTTP Body(JSON) :결과 반환 X : (HTTP 200 OK) 과제과제 4https://shimmer-exoplanet-946.notion.site/4-0d91a864aa444cef9137e454a1c29b5d?pvs=4과일 정보를 저장하는 API, 과일이 팔리면 과일을 팔린 상태로 변경하는 API, 과일의 이름을 받으면 해당 과일을 기준으로 팔린 금액과 팔리지 않은 금액을 조회하는 API를 작성하는 과제였다.우선 과일을 저장할 테이블을 만들어야 했는데, 문제에서 요구되는 id, name, warehousingDate, price, status 등을 column으로 넣어주었다. 이때 status는 ENUM 타입으로 설정해 SOLD나 NOT_SOLD 두 상태 중 하나가 되도록 하였고, 디폴트 값은 NOT_SOLD로 설정해두었다.이후 API 작성은 수업에서 배운대로 JdbcTemplatae과 직접 작성한 SQL문을 이용해 DB에 쿼리를 날리는 방식이라 크게 어렵지 않았다. 문제 3번은 배운 내용을 조금 응용해야 했는데, 과일의 이름을 받아 해당 과일이 DB에 존재하는지 확인하여 분기 처리를 하는 부분은 기존에 배운 것과 동일했지만, 해당 과일 중 팔린 과일과 필리지 않은 과일의 총액을 조회하는 부분에서 내가 원하는 기능을 수행하는 SQL 쿼리에 대한 검색을 좀 해야 했다. 우선 name이 해당 과일의 이름이고 팔린/팔리지 않은 상태의 과일들을 조회해온 다음, SUM(price)를 이용해 조회된 과일들의 price값을 합산한 후, COALESCE 함수를 이용해 SUM의 결과가 NULL이면 0을 반환하도록 했다. 과제 5https://shimmer-exoplanet-946.notion.site/5-e7d1b6bae1fe44d5baf250c702270028?pvs=4주어진 코드를 클린 코드로 리팩토링 하는 과제였다. 클린 코드가 정확히 무엇인지 알기 위해 검색을 해서 정리했다. 의미있는 변수/함수/클래스 이름을 지정하고 코드를 기능(역할)에 따라 모듈화하여 최대한 간결하면서 의도를 명확히 전달할 수 있는 코드를 짜는 것이 핵심이었다. 우선 변수와 함수의 이름을 사용 의도가 명확히 보이도록 고쳐주었고, 기존에 반복되던 코드를 for문을 이용하여 간결하게 해주었다. 또한 기존 코드는 main 함수에서 모든 기능을 수행하고 있었기 때문에 기능별로 함수를 분리해주었다. 두 과제 모두 무난하고 재미있게 수행할 수 있었다. 과제 4를 통해서는 수업에서 배운 것 외의 SQL 문법에 대해 공부해볼 수 있었고, 과제 5는 다른 사람들이 어떻게 리팩토링했는지 보며 내가 미처 생각하지 못한 개선점들을 볼 수 있었다. 회고저번 주 강의는 기본적인 지식들을 쌓는 것이었는데, 이번주는 본격적인 내용으로 들어가면서 필기할 내용도 많아지고 배운 것들을 이해하는 데 더 많은 시간을 쏟아야 했다. 그래서 강의를 듣는 것도 좀 밀리고, 강의를 다 듣긴 했지만 배운 내용을 온전히 소화하지는 못했다. 다음주는 이번주 강의 내용을 다시 정리해보고, 시간을 좀 더 효율적으로 사용할 수 있도록 해야겠다. 그래도 JPA를 이용해 실제로 동작하는 도서 관리 어플리케이션을 개발해보는 과정은 정말 즐거웠다. 이번주 금요일에 코드 리팩토링에 관한 라이브 방송이 있었는데, 그걸 모르고 있다가 방송이 끝나갈 쯤에야 참여해서 아쉬움이 컸다. 과제 5를 수행하면서 클린 코드를 짜는 것이 생각보다 고려할 점이 많다는 것을 느껴서 더더욱 그랬다. 다행히 키워드와 코드를 남겨주셔서 혼자 공부해봐야 할 것 같다.
백엔드
・
인프런
・
워밍업
・
클럽
・
스터디
・
1기
2024. 05. 05.
0
[인프런 워밍업 클럽 스터디 1기] BE 1주차 회고
첫번째 발자국 인프런 워밍업 클럽 스터디에 참여하여 일주일을 보낸 후 쓰는 첫번째 회고록. Section 1 - 생애 최초 API 만들기JVM자바 가상 머신의 약자os 별로 존재한다.바이너리 코드들을 읽고 검증한다.JRE자바 실행 환경의 약자JRE = JVM + 자바 프로그램 실행에 필요한 라이브러리 파일 등JVM의 실행 환경을 구현JDK자바 개발 도구의 약자JDK = JRE + 개발을 위한 도구(통합 개발 도구)컴파일러, 디버그 도구 등이 포함되어 있다.여러 버전이 있고, 각 버전별로 새로운 기능이 추가되거나 기존 기능이 사라진다.여러 종류가 있고, 기능 자체는 동일하나 성능과 비용에 약간의 차이가 있을 수 있다. 빌드 : 소스코드 파일을 컴퓨터에서 실행할 수 있는 독립 SW 가공물(Artifact, 독립적인 하나의 파일)로 변환시키는 과정실행 : 작성한 코드를 컴파일을 거쳐 작동시켜보는 것(독립 SW 가공물이 나올수도 있고, 나오지 않을 수도 있음)빌드 과정 자동화와 외부 라이브러리 관리를 위해 빌드 툴이 사용되며, 자주 사용되는 자바 빌드툴에는 maven, gradle이 있다. 어노테이션자동으로 설정/기능을 동작하게 하는 것@ + (어노테이션으로 만들어둔) 클래스 이름 서버 : 어떤 기능을 제공하는 프로그램. 또는 그 프로그램을 실행시키고 있는 컴퓨터클라이언트 : 서버에 어떤 기능을 요청하는 프로그램. 또는 그 프로그램을 실행시키고 있는 컴퓨터HTTP : 컴퓨터가 네트워크를 통해 다른 컴퓨터와 데이터를 주고받을 때 사용되는 통신 규약(중 하나)HTTP Method : HTTP 요청을 받는 컴퓨터에게 요청하는 행위(GET, POST, PUT, DELETE 등)요청을 받는 컴퓨터(IP 주소 / 도메인)와 프로그램(port) 정보Path : HTTP 요청을 받는 컴퓨터에게 원하는 자원Query : 자원의 세부 조건(조건이 여러개면 &로 구분)Body(JSON) : 저장할 자원의 정보JSON : 객체 표기법. 중괄호 안에 "key": value로 표기하며, 속성 각각은 ,로 구분한다. 요청에 대한 HTTP 응답200 OK (요청이 잘 처리됨)300 Moved Permanently (다른 곳으로 옮겨가라)404 NotFound (요청한 것을 찾을 수 없음)500 Internal Server Error (우리 내부에 문제가 생김)응답에는 추가 정보(바디)를 담을 수도 있음 API정해진 약속을 하여 특정 기능을 수행하는 것클라이언트와 서버는 HTTP를 주고 받으며 기능을 동작하는데 이때 정해진 규칙API의 구성 요소(명세)HTTP MethodHTTP PathQuery(key와 value)API의 반환 결과 @RestController: 주어진 클래스를 Controller(API의 입구)로 등록한다 -> 현재 클래스를 API의 진입 지점으로 만들어줌@GetMapping("/add"): 아래 함수를 HTTP Method가 GET이고 HTTP Path가 /add인 API로 지정한다.@RequestParam: 주어지는 쿼리를 함수 파라미터에 넣는다 -> 같은 이름을 가진 쿼리의 값이 함수의 argument로 들어온다@RequestBody: HTTP Body 안에 담긴 JSON을 DTO 객체로 변환 (DTO : 정보를 전달하는 역할의 객체) Section 2 - Database 조작하기Database의 필요성: API를 통해 생성된 정보는 단기 기억장치인 RAM에 기록되는데, RAM에 기록된 정보는 서버가 종료되면 사라지기 때문에 DISK에 장기 저장하기 위해 DB를 사용한다. Database : 데이터를 구조화해서 저장하는 것RDB(Relational DB) - MySQL : 데이터를 표처럼 구조화해서 저장하는 DBSQL(Structured Query Language) : 표처럼 구조화된 데이터를 조회,저장 등 조작하는 언어-> MySQL을 사용 DDL(Data Definition Language) : 데이터를 정의하는 언어데이터베이스 만들기 :create database [데이터베이스 이름];데이터베이스 목록 보기 :show databases;데이터베이스 지우기 :drop database [데이터베이스 이름];데이터베이스 안으로 들어가기 :use [데이터베이스 이름];(특정 데이터베이스 안으로 들어간 후)테이블 목록 보기 :show tables;테이블 만들기 :create table [테이블 이름] ([필드1 이름] [타입] [부가조건],[필드2 이름] [타입] [부가조건],...primary key ([필드이름]));테이블 제거하기 :drop table [테이블 이름];DML(Data Manipulation Language) : 데이터를 조작하는 언어데이터를 넣는다 = 생성, create데이터를 조회한다 = 조회(읽기), retrieve of read데이터를 수정한다 = 업데이트, update데이터를 삭제한다 = 제거, delete-> CRUD데이터 넣기INSERT INTO [테이블 이름] (필드1이름, 필드2이름, ...)VALUDES(값1, 값2, ...)필드 이름과 값의 순서가 맞아야 한다명령어는 소문자로 써도 상관 없다auto_increment로 지정된 필드값은 지정해주지 않아도 자동으로 설정된다데이터 조회하기SELECT * FROM [테이블 이름];* 대신 필드 이름을 넣을 수 있다. 여러 개 넣는 것도 가능하다.SELECT * FROM [테이블 이름] WHERE [조건];where을 이용해 필터(조건)을 걸 수 있다.AND 또는 OR을 이용해 조건을 이어 붙일 수 있다.조건에는 =, , >=, between, in, not in 등이 있다.BETWEEN [범위의 시작값] AND [범위의 끝값] : 양끝값을 포함한 범위 내의 값들만 가져온다.IN(조건1, 조건2) : 여러 조건을 한 번에 표시할 때 사용NOT IN() : 괄호 안 조건들에 포함되지 않는 데이터만 조회할 때 사용데이터 업데이트하기UPDATE [테이블 이름] SET 필드1이름=값, 필드2이름=값, ...WHERE [조건];where 절을 사용해 [조건]을 붙이지 않으면, 모든 데이터가 변경(업데이트)되니 주의해야 함데이터 삭제하기DELETE FROM [테이블 이름] WHERE [조건];[조건]을 붙이지 않으면 모든 데이터가 삭제되니 주의할 것!Spring에서 Database 사용하기사람이 아닌 스프링 서버가 MySQL 서버에 접근하게 하는 것application.yml 만들고 설정spring: datasource: url: "jdbc:mysql://localhost/library" username: "root" password: "5502" driver-class-name: com.mysql.cj.jdbc.DriverAPI 변경jdbcTemplate을 이용해 SQL을 날릴 수 있다. SQL을 만들어 문자열 변수로 저장한다. 이때 값이 들어가는 부분에 ?를 사용하면, 값을 유동적으로 넣을 수 있다.jdbcTemplate.update()는 INSERT, UPDATE, DELETE 쿼리에 사용할 수 있다(데이터에 변경을 주는 쿼리). 첫 파라미터로는 sql을 받고, ?를 데신할 값을 차례로 넣으면 된다.jdbcTemplate.query(sql, RowMapper 구현 익명클래스) : mapRow라는 함수를 override하고, override한 MapRow 안에서 sql의 실행 결과가 나오면 그 결과들의 데이터를 가져와 UserResponse(dto)로 바꿔준다. Section 3 - 역할의 분리와 스프링 컨테이너클린 코드가 중요한 이유 코드 : 요구사항을 표현하는 언어-> 개발자는 요구사항을 구현하기 위해 코드를 읽고 작성한다.-> 코드를 읽는 것은 필수적이고 피할 수 없으므로, 코드만 보고도 의미를 명확하게 파악할 수 있도록 코드를 작성해야 한다.클린 코드함수는 최대한 작게 만들고 한 가지 일만 수행하는 것이 좋다.클래스는 작아야 하며 하나의 책임만을 가져야 한다.Controller의 함수 1개를 역할에 따라 분리API의 진입 지점으로써 HTTP Body를 객체로 변환하고 있다. -> Controller의 역할로 남겨둠현재 유저가 있는지, 없는지 등을 확인하고 예외 처리를 해준다. -> Service의 역할로 분리SQL을 통해 실제 DB와의 통신을 담당한다. -> Repository의 역할로 분리 3가지 역할로 구분된 구조controller : API와 HTTP 역할 담당service : 분기 처리, 로직 담당repository : DB와의 접근 담당* controller는 service를 사용하고, service는 repostory를 사용함** DTO는 계층 간의 정보를 전달하는 역할(여러 계층을 왔다갔다 함)-> 이런 구조를 Layered Architecture라고 한다!과제과제3https://shimmer-exoplanet-946.notion.site/3-07f12f6102e24a509e57519f890b43ec?pvs=4자바의 람다식과 익명 클래스에 대해 공부해보는 과제였다. 강의를 들으면서 람다식이라는 개념을 처음 접했는데 과제를 통해 따로 공부할 수 있어서 좋았다. 수업을 들을 때도 익명 클래스 부분에서 버벅였는데, 과제를 진행하며 블로그 글을 읽어도 완전히 이해한 것 같지 자바에 대한 공부가 추가로 필요하겠다고 느꼈다. 회고인프런 워밍업 클럽 스터디에 참여한지 벌써 일주일이 지났다. 이번주에 다른 일들이 많이 겹쳐 내 생각보다 더 힘들었지만, 혼자서 공부하는 것보다 이점이 훨씬 많았다.진도표에 매일 공부할 분량이 체계적으로 정해져 있어 내가 별도로 학습 계획을 짜지 않아도 계획적으로 공부할 수 있었다. 여러명이 함께 강의를 수강하는 스터디 방식이라 강의 듣는 것을 미루지 않고 진도표에 맞춰 학습할 동기부여가 되었다. 추가적으로 주어지는 과제를 통해 배운 내용에 대해 스스로 학습하고 정리할 수 있는 것도 좋았다.강의 내용도 매우 흥미로웠다. 자바와 스프링에 대한 기초 지식부터, 백엔드 개발에 필요한 서버 관련 내용까지 차근차근 정리할 수 있었다. 또한 API 설계 및 개발 과정을 실습으로 진행하며 각 기능이 어떻게 동작하고 구현되는지 직접 코딩을 하며 익혔다.다른 일들이 겹쳐 과제를 많이 놓치기도 하고 실습 중 자바에 대한 이해가 부족하다는 것을 느껴 조금 아쉬운 1주차였지만, 2주차부터는 좀 더 많은 시간을 투자하고 자바에 대한 학습도 병행하며 더 충실한 일주일을 보낼 수 있도록 노력할 것이다.
백엔드
・
인프런
・
워밍업
・
클럽
・
스터디
・
1기