블로그

msj09252

[인프런 워밍업 클럽 스터디 2기] 백엔드 클린 코드, 테스트 코드 1주차 발자국

해당 글은 박우빈님의 강의를 수강하며 작성한 글입니다. 강의 수강1. 추상과 구체추상과 구체, 이 두 단어는 항상 같이 다니는 한 쌍이다.추상이란?구체적인 정보에서 어떤 이미지를 뽑아내는 것.중요한 정보는 가려내어 남기고 덜 중요한 정보는 생략하여 버린다.추상은 항상 구체적인 실재에서 시작해야 한다.위 내용을 통해 구체적인 내용에서 추상의 단계로 가는 방법이 있고, 그 반대의 방법도 존재한다.우리는 강의를 통해서 구체적인 지뢰찾기 코드를 추상화해가며 객체지향의 개념을 적용해보는 시간을 가졌다.  2. 논리, 사고의 흐름뇌 메모리 적게 쓰기최소한의 인지적 노력으로 최대의 정보를 제공해야 한다.뇌는 범주화라는 작업을 통해 무언가를 떠올린다.이 말은 즉, 누군가 작성한 코드(조상)가 남(후손)이 보아도 쉽게 읽고 이해할 수 있다면, 그것은 뇌 메모리를 적게 쓸 수 있게 한 효과적인 코드가 아닐까 싶다.Early returnEarly return 사용을 통해 else의 사용을 지양하자사고의 depth 줄이기공백 라인공백 라인도 의미를 가진다.읽는 사람으로 하여금 의미를 분절시켜 추가적인 정보전달이 가능하다.부정어 사용부정어구를 쓰지 않아도 되는 상황인지 체크부정의 의미를 담은 다른 단어가 존재하는지 고민하거나 부정어구 메서드 사용해피 케이스와 예외 처리 3. 객체 지향 패러다임객체 설계하기 : 미션으로 대체SOLIDSRP: Single Responsibility PrincipleOCP: Open-Closed PrincipleLSP: Liskov Substitution PrincipleISP: Interface Segregation PrincipleDIP: Dependency Inversion Principle 4. 객체 지향 적용하기상속과 조합상속보단 조합을 이용하자.조합과 인터페이스를 활용하는 것이 유연한 구조다.Value Object훌륭한 추상화 기법 중 하나기본 타입을 객체로 감싸서 의미 부여 및 추상화를 하는 것.동등성 vs 동일성일급 컬렉션Enum의 특성과 활용상수집합변경이 잦은 개념은 Enum보다 DB로 관리하자.다형성 활용하기숨겨져 있는 도메인 개념 도출하기도메인 지식은 만드는 것이 아니라 발견하는 것이다.미션Day 2추상과 구체의 예시 제시추상"노래를 듣는다" 라는 추상적인 문장을 구체화 해보았다구체이어폰에서 발생한 음파가 공기를 통해 외이로 도달한다.외이도를 통해 전달된 음파는 고막에 도달하고, 고막은 음파에 의해 진동한다.고막의 진동은 중이의 세 개의 작은 뼈로 전달된다.세 개의 뼈는 음파의 진동을 증폭시켜 내이의 달팽이관으로 전달한다.달팽이관에 있는 액체가 움직이면서 유모 세포를 흔들고, 이 과정에서 전기 신호로 생성한다.전기 신호가 청각 신경을 통해 뇌로 전달된다.뇌의 청각 피질이 신호를 분석하고 해석하여 소리를 인식한다.Day 41. 코드 리팩토링2. SOLID에 대한 자기만의 언어로 정리깃허브 링크 대체노션 링크 대체회고클린코드란 무엇인가 에 대해 다시 한번 고민하게 되는 주간이었다. 사이드 프로젝트를 진행하면서 주로 나의 코드를 내가 자주 보고 고치기 때문에 남이 어떻게 이해할지에 대해서 깊게 고민해보지 못했던 것 같다. 이번 기회를 통해 프로젝트 코드에서 고칠 부분이 상당히 많이 떠올랐고, 스터디 중간 중간 적용해보려고 노력하려 한다. 빡빡한 스케줄을 회사와 병행하다보니 강의 수강과 미션 수행을 모두 처리하는 것이 상당히 쉽지 않았다. 다행히 이번 주간에는 쉬는 날이 많아서 겨우 맞춰나간 것 같다. 많은 스터디원 분들이 성실히 수행하는 것을 보며 동기부여가 되고 있다.남은 3주도 잘 마무리하여 완주러너가 되고 싶다.

BE클린코드워밍업클럽

ykm8864

[인프런 워밍업 클럽 백엔드 스터디 2기] 1주차 발자국

학습 내용리팩토링을 왜할까? 클린코드를 왜 작성할까?우리는 생산을 해냈다고 끝이 아니다. 이후에 조상들이 작성한 코드를 후손들이 유지보수하는 일이 생기기 마련이다. 이에 관련하여 여러가지 방법에 대하여 배워보자추상? 그게 뭔데의미를 담을 수 있는 더 작은 단위, 책임이름짓기단수와 복수의 구분관용어가 아닌 이상 줄임말 자제그 집단만 알 수 있는 은어/방언 사용하지 않기좋은 코드를 많이 보기메서드로의 분리의미를 담을 수 있는 더 작은 단위로 메서드를 분리하기기준 : 추상화되는 의미가 있는가? 이미 이해가 잘 간다면 그대로 두는게 더 나을 수 있다.추상화 레벨 구체에 가깝다 = 추상화 레벨이 낮다. (디테일한 코드 상세) 추상에 가깝다 = 추상화 레벨이 높다. (디테일한 코드를 외부세계로 감싸는 메서드)하나의 세계 안에서는, 추상화 레벨이 동등해야 한다. 내가 너무 주변 레벨에 비해서 구체화시키고 있다면 추상화를 고려해보자매직넘버와 매직스트링의미를 갖고 있으나, 상수로 추출되지 않은 숫자상수를 추출하고 이름을 짓고 의미를 부여함으로서 가독성이 향상될 수 있다.상수로 뺀다는건, 이거는 중요한 숫자야~ 유지보수할때 중요깊게 봐야할 필요가 있을거야~ 라는 의미를 줄 수 있다.  논리 사고의 흐름#최소의 인지적 노력으로 최대의 정보를 제공# 뇌는 한번에 한가지 일 밖에 하지 못한다. 멀티태스킹? 그건 저글링일 뿐이다.뇌에 메모리를 적게 쓰게 하기.Early return논리의 흐름을 빠르게 중단시켜 생각 회로를 단순화 한다.코드 흐름을 단순화하고 가독성을 향상중첩분기, 중첩반복문에 대한 최적화depth를 1로 만들 수 있는지 생각해보기때로는 stream에 대한 활용도 고려할 수 있다.2중 중첩구조 안에도 사고에도움이 된다면 중첩 안에 메서드를 분리하여 두어도 좋다.사용할 변수는 가깝게 선언하기공백라인도 의미를 가진다복잡한 로직의 의미 단위를 나누어 보여줌으로써 읽는 사람에게 추가적인 정보를 전달할 수 있다.부정어를 대하는 자세논리를 거꾸로하여 생각하는 과정을 거친다는 것은 가독 저하의 요인일 수 있다.부정어구를 쓰지 않아도 되는 상황인지 체크하기 (무조건 부정조건으로검사해야하는 상황인지)부정의 의미를 담은 다른 단어자체가 존재하는지 고민하기 or 부정어구로 메서드 명 구성해피케이스와 예외 처리예외가 발생할 가능성 낮추기검증로직은 생성자 or 별도의 분리가 필요의도한 예외와 예상하지 못한 예외를 구분하기Null을 대하는 자세equals작성시 상수를 앞에 둔다.Optional은 비싼 객체라 항상 좋은건 아니지만 값이 있을 수도 있고 없을 수도 있는 상황에는 고려할 수 있다. 이때 멤버변수에 Optional은 좋지 않다. 만들어진 목적이 메서드의 반환타입에 쓰게금 설계되어있다.[orElse() : 괄호 안에 값이 항상 실행orElseGet() : 옵셔널안에 원본값이 null인 경우 실행orElseThrow() : 값이 있으면 쓰고 없으면 예외를 던지겠다. 라는 의미라서 그냥 써도된다.StackTrace는 안티패턴이다. 추상의 관점으로 바라보는 객체 지향객체지향 패러다임객체 간의 협력과 객체가 담당하는 책임객체간의 협력과 객체가 담당하는 책임의 관점으로 추상화를 접목시켜 이해하는 것이 중요하다.관심사의 분리관심사끼리 객체를 분리한다.높은 응집도, 낮은 결합도 유지객체 설계하기객체도 추상화와 같이 객체로 나누는 순간 외부와 경계가 발생한다. 이때 외부세계와 소통을 위해서 공개메서드를 활용한다.객체는 외부로 기능을 제공해준다. (개념의 가시화 = 관심사)비공개필드(데이터), 비공개로직(기능 구현부), 공개 메서드 선언부만 외부로 노출하여 이루어진다.여러 객체를 사용하는 입장에서는 구체적인 구현에 신경쓰지 않고 보다 높은 추상화 레벨에서 도메인 로직을 다룰 수 있다.새로운 객체를 만들 때 주의할 점1개의 관심사로 명확하게 책임이 정의되었는지 확인유효성 검증setter 사용 자제(데이터의 불변성)getter가 꼭 필요한지 생각해보기 (객체에 메시지를 보내서 필요한 정보를 메서드로 가져올 수 없는지?)필드의 수는 적을 수록 좋다. 객체지향 패러다임(SOLID)SRP : ”책임을 볼 줄 아는 눈”전문가가 되어야한다. 하나 이상의 일을 책임지게 되면 업무의 효율성이 떨어지게 된다. 이를 어기면 각각의 역할에 집중할 수 없고 공통 업무의 변화가 생기면 모두 바뀌어야한다.OCP : "기존 코드의 변경 없이 , 시슽템의 기능을 확장할 수 있어야한다. (추상화와 다형성의 활용)"전기콘센트 같은것. 허용 전압 규격만 맞으면 냉장고, 가스레인지 등 모든 가전제품을 사용 가능하다. 가전제품이 늘어나도 규격이 맞으면 사용 가능하고 전기콘센트를 교체할 필요 없다.LSP : "자식클래스는 부모클래스의 책임을 준수하며, 부코클래스의 행동을 변경하지 않아야한다."엄마말을 잘 듣자. 상속의 세계에서는 자식은 부모를 이길 수 없다. 따라서, 자식은 부모의 규칙을 어기거나 변경할 수 없이 말을 잘 들어야한다.ISP : "인터페이스를 기능단위로 잘게 쪼개라"덜어냄의 미학. 흑백요리사에서처럼 인터페이스도 많은 기능(책임)을 가진다고 좋은게 아니다. 필요한 만큼만 가지는게 최고다.DIP : "상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다. 둘 모두 추상화에 의존해야 한다."수준에 맞게 놀자. 고수준(추상 : 핵심비지니스 로직) 모듈이 저수준(구체 : 구현세부사항)모듈을 직접적으로 참조하는 것은 저수준모듈의 변경에 민감하게 반응하게된다. 객체지향 적용하기상속과 조합상속보다는 조합을 사용하자상속은 시멘트처럼 굳어진 구조다. (부모와 자식의 결합도가 높다.)조합과 인터페이스를 활용하는 것이 유연한 구조다.상속을 통한 코드의 중복 제거가 주는 이점보다, 중복이 생기더라도 유연한 구조 설계가 주는 이점이 더 크다.상속 : extends → 부모 - 자식 간의 필수 오버라이딩 제약이 없고, 부모의 구현을 자식이 알고있는 관계 → 자식.부모메서드() 로 호출이 가능하여 재사용성이 향상됐다고 볼 수 있지만 객체 지향 관점에서는 캡슐화가 깨진 상태라고도 볼 수 있음조합 : 부모에는 공통 스팩 제공하는 인터페이스를 사용하고, 해당 부모의 구현체들은 부모의 스팩만 유지한 상태라면 부모에 독립적이고 변경이 많아질 수 있는 부분은 부모 클래스에 두지 않고 별도의 클래스로 분리함으로써 캡슐화와 확장성을 지킨다.주입 : 외부에서 부모 클래스나 자식 클래스가 의존하는 객체들을 주입함으로써, 객체 간의 강한 결합을 방지하고, 필요 시 구현체를 쉽게 교체할 수 있게 하여 유지보수와 테스트의 용이성을 높인다.Value Object도메인의 어떤 개념을 추상화하여 표현한 값 객체 값으로 취급하기 위해서, 불변성, 동등성, 유효성 검증 등을 보장해야 한다.엔티티와 vo의 차이(식별자 유무 차이)일급 컬렉션일급시민이란? -> 다른 요소(누군가의 파라미터, 변수, 함수의 결과로 return)에게 사용 가능한 모든 연산을 지원하는 요소일급컬렉션이란?컬렉션을 포장하면서 필드로 무조건 해당 컬렉션 하나만을 가지고 있는 객체컬렉션을 다른 객체와 동등한 레벨로 다루기 위함getter로 컬렉션을 반환할 일이 생긴다면 필드에서 가지고 있는 컬렉션과 같은 참조를 리턴하는 일이 생기지 않도록 new해서 새로운 컬렉션을 반환하자.enum의 특성과 활용상수의 집합변경이 정말 잦은 개념이면 enum보다 db로 관리하는게 좋을 수 있음.다형성 활용하기변하는 것과 변하지 않는 것을 분리하여 추상화하는 것.변하지 않는 것을 지켜야[추상] → 변경에는 닫혀있는 상태를 유지 가능변화하는 것에는 유동적으로 해결이 되어야[구체] → 확장에 열려있는 상태가 된다. 숨겨져 있는 도메인 개념 도출하기완벽한 설계는 없다. 그 당시의 최선이 있을 뿐.도메인 지식은 만드는 것이 아니라 발견하는 것설계할 때는 근시적, 거시적 관점에서 최대한 미래를 예측하려는 시도가 필요하다시간이 지나 만약 틀렸다는 것을 인지하면 언제든 돌아올 수 있도록 코드를 만들어야 한다.미션-> 주어진 코드에 대한 리팩토링얼리리턴추상화레벨 맞추기처리해야할 예외와 그렇지 않은 예외의 분리변수명, 함수명책임의 분리등.. 배운 지식을 활용하여 최적화하는 연습을 해보았다.   1주차 회고Keep (만족했고, 앞으로도 지속하고 싶은 부분)현재 코드를 작성하면서 "조상"과 "후손"이라는 표현을 사용한 점이 인상 깊었다. 이 표현은 코드의 지속성과 유지보수의 중요성을 잘 드러낸다고 생각이 들었다. 실무에서는 생산성과 클린 코드를 상반된 개념으로 보는 경우가 많은데, 이는 조직의 코드 문화에 긍정적이지 않다는 생각도 같이 들곤 했다. 이러한 문화를 개선하기 위한 방법론을 이번 학습을 통해 구체적으로 알게 되어 만족스러웠다..Problem (아쉬웠던 점)처음 보는 코드에 대한 빠른 이해가 부족하다는 점을 느꼈다. 즉, 현재 짜여진 코드를 너무 쉽게 납득해버리는 경향이 있는게 아닌가 싶다. 강사님처럼 코드를 보고 잠재적인 문제와 개선 가능성을 구조적으로 접근하는 시야가 필요하다고 생각한다. 이를 통해 "보는 눈"에 대한 중요성을 느꼈다.Try (다음에 시도해볼 점)구체적인 코드 설계에서 추상과 구체를 명확하게 분리하는 연습을 해보고 싶다. 처음부터 완벽한 설계를 할 수는 없겠지만, 도메인의 책임을 분리하고 리팩토링을 고려한 설계를 시도해봐야겠다. 우선 흐름대로 코드를 작성한 후, 리팩토링을 통해 개선하는 과정을 반복하며 사고력을 기르는 과정을 연습해보아야 할 거 같다.

백엔드워밍업클럽회고자기계발몰입하는개발자BE백엔드

구르밍

인프런 워밍업 클럽 BE 1기 - 2주차 발자국

UserController의 의아한점static이 아닌 코드를 사용하려면 인스턴스화 (new)가 필요하다UserController를 인스턴스화하고 있지 않은데 누가 하고 있는것인가???UserController는 JdbcTemplate에 의존하고 있다. 그런데 JdbcTemplate란 클래스도 설정해준적이 없다..! 어떻게 가져온거지?⇒ @RestController가 다해주고 있었다!!!!!⇒ UserController클래스를 API의 진입지점으로 만들 뿐 아니라 UserController 클래스를 스프링 빈으로 등록 시킨다. 스프링 빈(Bean)이란?서버가 시작되면, 스프링 서버 내부에 거대한 컨테이너를 만들게 되고, 컨테이너 안에는 클래스가 들어가게 된다.!이때 다양한 정보도 함께 들어있고, 인스턴스화도 이루어진다.JdbcTemplate도 스프링 빈에 등로되어 있었기에 사용할 수 있었다. (dependencies로 의존)UserRepository는 JdbcTemplate을 가져오지 못할까?JdbcTemplate을 가져오려면 UserRepository가 스프링 빈이어야 하는데 UserRepository는 스프링 빈이 아니다!!→ UserRepository를 스프링 빈으로 등록하자!스프링 컨테이너를 왜 사용할까?메모리에 저장하는 레포를 만든다고 가정하고 코딩…→ MySQL로 저장하고 싶은데?→ 관련된 모든 것들을 다 MySQL로 변경하는 레포로 변경해야함!!! 데이터를 메모리에 저장할지, MySQL에 저장할지 Repository의 역할에 관련된 것만 바꾸고 싶은데 BookService까지 바꿔야 한다. (OMG)⇒ Java의 interface를 활용하자!그래도 Service를 수정해야하는 상황이 발생.. 스프링 컨테이너를 사용하면?BookMemoryRepository, BookMySqlRepository 둘 중 BookService에 쓰일 것을 컨테이너가 선택한다!!→ 이런 방식을 제어의 역전(IoC, Inversion of Control)이라 한다.→ 컨테이너가 선택해 BookService에 넣어주는 과정을 의존성 주입(DI, Dependency Injection)라고 한다.@Primary를 붙여주면 해당 어노테이션이 있는 곳이 사용된다. (우선권 결정)⇒ 나중에 바꿔야 Memory에서 mysql로 바꾸는 작업이 있어서 코드를 다 바꿔야 할 경우 @Primary를 붙여 스프링이 자동으로 해당 레포로 선택하게 하면 된다! 스프링 컨테이너를 다루는 방법빈을 등록하는 방법@Configuration클래스에 붙이는 어노테이션@Bean을 사용할 때 함께 사용해 주어야 한다.@Bean메소드에 붙이는 어노테이션메소드에서 반환되는 객체를 스프링 빈에 등록한다.UserRepository.java에 있는 @Repository 어노테이션 삭제 후 @Bean으로 등록언제 @Service, @Repository를 사용해야하나??→ 개발자가 직접 만든 클래스를 스프링 빈으로 사용할 때@Configuration, @Bean는 언제 사용?→ 외부 라이브러리, 프레임워크에서 만든 클래스를 등록할 때@Component주어진 클래스를 ‘컴포넌트’로 간주한다.이 클래스들은 스프링 서버가 뜰 때 자동으로 감지된다.→ 사실 숨겨져 있었다.. 타고 들어가면 사용되고 있는것을 확인할 수 있다.→ 컨트롤러, 서비스, 리포지토리가 모두 아니고, 개발자가 직접 작성한 클래스를 스프링 빈으로 등록할 때 사용되기도 한다. 스프링 빈을 주입 받는 몇 가지 방법생성자를 이용해 주입받는 방식 (가장 권장)기존에는 @Autowired 어노테이션을 붙여야했는데 스프링 버전이 업데이트 되면서 안붙여도 자동으로 등록되게 되었다.setter와 @Autowired 사용 → setter를 사용할 경우 오류발생 확률 높아짐필드에 직접 @Autowired 사용 → 테스트하기 어렵다.@Qualifier: 여러개의 후보군이 있을때 그 중 하나를 특정해서 가져올 수 있게 끔 한다.스프링 빈을 사용하는 쪽, 스프링 빈을 등록하는 쪽 모두 @Qualifier를 사용할 수 있다.스프링 빈을 사용하는 쪽에서만 쓰며, 빈의 이름을 적어주어야 한다.양쪽 모두 사용하면, @Qualifier끼리 연결된다.@Primary vs @Qualifier → 동시에 사용할 경우 어떤게 우선일까?사용하는 쪽에서 직접 적어준 @Qualifier가 이긴다.SQL을 직접 작성하게되면..SQL을 직접 작성할 경우 오류가 나도 확인하기 힘들다⇒ 컴파일 시점에 발견되지 않고 런타임 시점(서버가 이미 가동된 후)에 발견된다특정 데이터베이스에 종속적이게 된다.⇒ 다른 DB를 사용할경우 다 바꿔줘야 한다.반복 작업이 많아진다. 테이블을 하나 만들 대마다 CRUD쿼리가 항상 필요하다.데이터베이스의 테이블과 객체는 패러다임이 다르다.→ JPA( Java Persistence API) 등장!: 객체와 관계형 DB의 테이블을 짝지어 데이터를 영구적으로 저장할 수 있도록 정해진 Java 진영의 규칙 유저테이블에 대응되는 Entity Class 만들기@Entity 어노테이션을 User 클래스에 붙인다.→ @Entity : 스프링이 User객체와 user 테이블을 같은 것으로 바라본다. (저장되고, 관리되어야 하는 데이터)우선 테이블의 PK인 id를 만들어보자@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id = null;@Id : 이 필드를 primary key로 간주한다.@GeneratedValue : primary key는 자동 생성되는 값이다.(strategy = GenerationType.IDENTITY)여기 부분은 DB종류마다 자동생성 전략이 다르다!! 주의!!MySQL의 auto_increment를 사용했기에 IDENTITY를 매칭@Entity를 사용할 경우 - 매개변수가 하나도 없는 기본 생성자가 꼭 필요하기 때문에 다음 코드를 작성!protected User() {}@Column : 객체의 필드와 Table의 필드를 매핑한다.→ null이 들어갈 수 있는지 여부, 길이 제한, DB에서의 column이름 등등…@Column(nullable = false, length = 20, name = "name") //name varchar(20) private String name;null이 들어갈 수 없거, 길이는 20자, 필드의 이름은 name (이 경우는 name = “name” 동일하기에 생략 가능) @Column 은 생략가능하기 때문에 널이 들어갈 수 있고 굳이 특정할필요 없다면 생략이 가능하다. JPA 설정 추가 - application.ymljpa: hibernate: ddl-auto: none properties: hibernate: show_sql: true format_sql : true dialect: org.hibernate.dialect.MySQL8Dialectddl-auto : 스프링이 시작할 때 DB에 있는 테이블을 어떻게 처리할지none 외에 다른 종류create : 기존 테이블이 있다면 삭제 후 다시 생성create-drop : 스프링이 종료될 때 테이블을 모두 제거 -… 사용 조심할것 ! 데이터가 모두 날라갈 수있음.update : 객체와 테이블이 다른 부분만 변경validate : 객체와 테이블이 동일한지 확인none : 별다른 조치를 하지 않는다.show_sql : JPA를 사용해 DB에 SQL을 날릴 때 SQL을 보여줄 것인가format_sql : SQL을 보여줄 때 예쁘게 포맷팅 할 것인가dialect : 방언, 사투리.. → 이 옵션으로 DB를 특정하면 조금씩 다른 SQL을 수정해준다. Spring Date JPA를 이용하여 자동으로 쿼리 날리기기존 UserRepository.java를 UserJdbcRepository.java로 변경하고domain > user > UserRepository 인터페이스를 생성하자생성 후 JpaRespository를 상속 받는다.public interface UserRepository extends JpaRepository<User, Long> {}<User, Long> → User의 primary key인 Id의 타입이 Long이라 Long으로 작성한다. 유저 데이터 정보 추가하기 (INSERT)public void saveUser(UserCreateRequest request) { userRepository.save(new User(request.getName(), request.getAge())); }JpaRepository를 상속 받는 userRepository에 save메소드를 객체에 넣어주면 INSERT SQL이 자동으로 날아간다. → save되고 난 후의 User는 id가 들어 있다유저 정보 조회하기 (SELECT)public List<UserResponse> getUserList(){ return userRepository.findAll().stream() .map(user -> new UserResponse(user.getId(), user.getName(), user.getAge())) .collect(Collectors.toList()); }findAll() : 해당 테이블의 모든 데이터를 조회한다.user를 stream으로 mapping시켜주고 user에 new UserResponse로 id, name, age를 넣어준다.그 후 결과를 List로 반환유저 정보 조회 후 수정하기 (UPDATE) public void updateUser(UserUpdateRequest request) { User user = userRepository.findById(request.getId()) .orElseThrow(IllegalArgumentException::new); user.updateName(request.getName()); userRepository.save(user); }findById를 사용하면 id를 기준으로 1개의 데이터를 가져온다..orElseThrow(IllegalArgumentException::new);→ Optional의 orElseThrow를 사용해 User가 없다면 예외를 던진다. 있을경우 user에 담긴다user.updateName(request.getName()); userRepository.save(user);도메인 user의 updateName메소드에 변경할 reqest.getName을 인자로 넣어 이름을 변경해주고save를 통해 user의 정보를 저장한다. (자동으로 UPDATE SQL이 날라가게 된다.) 어떻게 SQL을 작성하지 않아도 동작하지? JPA인가?→ Spring Data JPA가 도와준다.: 복잡한 JPA 코드를 스프링과 함께 쉽게 사용할 수 있도록 도와주는 라이브러리 By앞에 들어갈 수 있는 구절 정리find : 1건을 가져온다. 반환타입은 객체가 될수도 있고, Optional<타입>이 될 수도 있다.finalAll : 쿼리의 결과물이 N개인 경우 사용. List<타입> 반환exists : 쿼리 결과가 존재하는지 확인. 반환 타입은 booleancount : SQL의 결과 개수 반환타입은 longBy뒤에 들어갈 수 있는 구절 정리GreaterThan : 초과GreaterThanEqual : 이상LessThan : 미만LessThanEqual : 이하Between : 사이에SELECT * FROM user WHERE age BETWEEN ? AND ?;List<User> findAllByAgeBetween(int startAge, int endAge);StartsWith : ~로 시작하는EndsWith : ~로 끝나는트랜잭션 이란 : 쪼갤 수 없는 업무 최소 단위→ 모든 SQL을 성공시키거나 하나라도 실패하면 모두 실패시키자!트랜잭션 시작하기start transaction;트랜잭션 정상 종료하기 (SQL 반영)commit;트랜잭션 실패처리(SQL 미반영)rollback; 트랜잭션 적용과 영속성 컨텍스트우리가 원하는 것은서비스 메소드가 시작할 때 트랜잭션이 시작되어서비스 메소드 로직이 모두 정상적으로 성공하면 commit 되고서비스 메소드 로직 실행 도중 문제가 생기면 rollback 되는 것@Transactional 어노테이션으로 우리가 원하는 것을 할 수 있다!SELECT 쿼리만 사용할경우, readOnly 옵션을 사용하여 데이터 변경을 위한 기능이 빠져 약간의 성능 향상이 있다. 영속성 컨텍스트란?테이블과 매핑된 Entity 객체를 관리/보관하는 역할⇒ 스피링에서는 트랜잭션을 사용하면 영속성 컨텍스트가 생겨나고, 트랜잭션이 종료되면 영속성 컨텍스트가 종료된다.변경 감지 (Dirty Check): 영속성 컨텐스트 안에서 불러와진 Entity는 명시적으로 save하지 않더라고, 변경을 감지해 자동으로 저장된다.@Transactional public void updateUser(UserUpdateRequest request) { User user = userRepository.findById(request.getId()) .orElseThrow(IllegalArgumentException::new); user.updateName(request.getName()); //userRepository.save(user); }유저의 정보가 업데이트가 되었네? 바뀌었구나? 하고 자동으로 저장된다. 따라서 save메소드를 작성해주지 않아도 된다.쓰기 지연: DB의 INSERT / UPDATE / DELETE SQL을 바로 날리는 것이 아니라, 트랜잭션이 commit될 때 모아서 한 번만 날린다.예시로 유저가 저장되는 부분이 여러개 일때, 하나씩 날려서 저장하는것이 아니라 우선 기억해두고 한번에 저장하여 DB에 보내게 된다. 1차 캐싱: ID를 기준으로 Entity를 기억한다.쓰기 지연과 비슷하게 이전에 캐싱된 객체를 기억하고 있다가 동일한 값이면 DB에 계속해서 요청하지 않고 알려준다.책 생성 API 개발하기create table book (id bigint auto_increment, name varchar(255), primary key(id));name varchar(255)을 사용한 이유?@Column의 length 기본값이 255문자열 필드는 최적화를 해야 하는 경우가 아닐 때 조금 여유롭게 설정하는 것이 좋다.회고4번째과제는 과일가게 판매에 관련된 내용이었다. 삼단분리 후 뭔가 직접 구현해봐야하는 문제라 그런지 사실 과제를 하면서 재밌게 느껴졌다. 단순히 요구사항에 나와있는데로만 작성하다보니 id를 왜 long 타입으로 써야했을까? 등 '왜' 라는 생각을 잘 하지 못했는데 앞으로는 왜? 의문점을 가지고 생각해봐야겠다!!5번째 과제에선 클린코드에 나와있는 내용을 바탕으로 더 좋은 코드로 변경해보는 과제이었다.문제를 보고 우선 각각의 기능을 하는 함수로 나누어 분리해야겠다는 생각이 들었다. 또 if-else문을 지양해야한다고 했지만, 너무 많은 조건을 가지고 있는 if-else문의 경우에는 사용을 하는것이 오히려 나을수도 있다는 블로그 글을 참고하여조건부분을 따로 함수로 만들어 그 함수를 호출하는 if-else문을 생각하고 1차 리팩토링 하였다.하지만 그래도 if-else문에는 너무 반복되는 부분이 많았고 이부분을 결국 for문으로 변경하였다..!금요일에 깜짝 라이브를 참석하지 못해서 너무 아쉬웠지만 따로 내용을 올려주셔서 참고할 수 있었다 : )

백엔드워밍업BESpring

긱북이

[인프런 워밍업 클럽 1기] BE 1주차 발자국

첫 걸음인프런 워밍업 클럽 1기 BE에서 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지] 강의를 수강하며 작성하였다.강의 학습HTTP와 APIHTTP란 다른 컴퓨터로 데이터를 보내기 위한 데이터 표준이다.API는 정해진 약속에 따라 특정 기능을 수행하는 코드이다. HTTP Method 중 하나인 GET은 쿼리를 통해 정보를 보낸 후 데이터를 요청한다.→ /add?number1=10&number2=20 Controller는 API가 실행되는 입구와 같다.@GetMapping("/add") public int addTwoNumbers(@RequestParam int number1, @RequestParam int number2) { return number1 + number2; } GET 방식에서 매개변수를 각각 하나씩 입력받을 때에는 @RequestParam을 사용하여 변수에 쿼리의 값을 넣는다.만약 매개변수가 많을 경우, DTO 객체로 만들어 관리한다.@Getter public class CalculatorAddRequest { private final int number1; private final int number2; public CalculatorAddRequest(int number1, int number2) { this.number1 = number1; this.number2 = number2; } }GET 방식의 DTO 객체는 반드시 생성자를 포함해야 한다. DTO 객체를 이용한 Controller는 다음과 같다.@GetMapping("/add") public int addTwoNumbers(CalculatorAddRequest request) { return request.getNumber1() + request.getNumber2(); }DTO를 이용할 때는 @RequestParam을 제거해야 하며 변수를 객체로 감싸 불러오기 때문에 getter를 사용해야 한다. 마찬가지로 HTTP Method인 POST는 Body를 통해 정보를 보낸다.객체 표기법인 JSON을 사용하고, List를 사용하거나 JSON 안에 JSON을 사용하는 것도 가능하다.POST 방식에서 DTO를 이용한 Controller는 다음과 같다.@PostMapping("/multiply") public int multiplyTwoNumbers(@RequestBody CalculatorMultiplyRequest request) { return request.getNumber1() * request.getNumber2(); } @RequestBody를 사용하여 HTTP Body로 들어오는 JSON을 DTO 객체 형태로 변환한다.GET 요청의 @RequestParam과는 달리 DTO 객체를 사용해도 Annotaion을 생략할 수 없다. GET 요청과 달리 POST 요청은 생성자가 필요하지 않다. Domain(Entity)와 DTO의 차이DTO는 계층 간 데이터 교환을 위해 사용된다. 반면, Domain은 DB 테이블과 매핑되어 데이터를 저장하거나 관리하는 실제 비즈니스 도메인을 표현한다. DTO는 단순히 어떤 데이터로 통신할 것인지 정의하고, 상세한 정의는 Domain에서 한다. Spring에서 Database 사용하기private final JdbcTemplate jdbcTemplate; public UserController(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @PostMapping("/user") public void saveUser(@RequestBody UserCreateRequest request) { String sql = "insert into user (name, age) values (?, ?)"; jdbcTemplate.update(sql, request.getName(), request.getAge()); }JdbcTemplate를 이용하면 Spring에 SQL을 전달할 수 있다.SQL문을 작성하여 문자열 변수로 저장하는데, 값이 들어갈 부분에 ?를 사용하면 데이터를 넣을 수 있다.  과제 수행1일차 과제 : JAVA Annotation어노테이션은 실제 데이터가 아닌 메타데이터로써 클래스와 메서드에 추가하여 다양한 기능을 부여한다.반복적인 코드 작성을 줄일 수 있어 코드량이 감소하고, 코드의 역할을 명확히 지정할 수 있어 유지보수가 용이하다는 장점이 있다.사용자가 원하는 기능을 수행하는 커스텀 어노테이션을 만드는 방법도 알아보았다. 2일차 과제 : GET & POST API날짜를 받는 API를 구현할 때, String으로 날짜를 받은 후 LocalDate로 변환하는 과정을 거쳤다.그러나, 스프링 부트 2버전에서는 @DateTimeFormat을 사용해 LocalDate를 바로 받을 수 있다고 한다.3버전대에서는 어노테이션 없이 LocalDate를 바로 받을 수 있다. 3일차 과제 : 람다식과 익명 클래스익명 클래스란 이미 정의되어 있는 부모 클래스의 자원을 일회성으로 재정의한 클래스이며, 자식 클래스를 정의할 필요 없이 객체화가 가능하다.람다란 자바의 인터페이스를 익명 클래스로 구현한 익명 구현 객체를 짧게 표현한 것이다. 메서드 타입과 이름, 매개변수 타입, 중괄호, return문을 생략하고 화살표 기호를 넣는다. 4일차 과제 : 과일 가게 API 만들기enum 타입을 통해 과일의 판매 여부를 ‘SOLD’, ‘NOT_SOLD’의 두 가지 상태로 구분하였다.COALESCE()를 사용하여 팔린 과일 혹은 팔리지 않은 과일이 존재하지 않을 경우, NULL이 아닌 0으로 표시되도록 하였다.쿼리의 결과가 하나이므로 queryForObject를 이용해 SQL의 결과를 직접 long 타입의 객체로 매핑하였다.  느낀 점Spring의 기초를 복습하면서 ‘이건 왜 이렇게 쓰일까’와 같은 질문을 던지며 천천히 학습할 수 있었다.특히, 인프런의 각 강의에 있는 질문 게시판을 활용하였다.강의를 들으며 의문이 든 부분들은 이미 선배 러너들이 질문을 했고, 강의자 분께서 자세하게 답변을 달아 주셨기 때문에 편하게 학습할 수 있었다. 매일 과제가 있지만 하루에 학습할 양을 안내해 주는 진도표가 존재하고, 하루치 공부 양이 그렇게 많지 않았기 때문에 오히려 꾸준하게 하루 공부를 진행할 수 있어 좋았다.일주일을 돌아보며 작성하는 발자국은 그동안 배운 내용을 정리하고, 느낀 점을 회고할 수 있어 좋은 방법인 것 같다.강의를 들으며 개조식으로 정리한 내용을 글로 풀어 쓰니 내가 얼만큼 이해하고 있는지 확인할 수도 있다.

백엔드워밍업클럽BE발자국1주차

김찬희

[인프런 워밍업 클럽 스터디 1기] BE 2주차 <두 번째 회고록>

스프링 컨테이너 (1) Static 이 아닌 코드를 사용하려면 인스턴스화가 필요하다 . 이때, @RestController( Controller 클래스) 등을 사용해 클래스를 스프링 빈으로 등록시켜준다. 서버가 시작되면 스프링 서버 내부에 컨테이너를 만들게 되는데 이때, 스프링 컨테이너에 기존에 등록되어 있던 빈들이 다 등록 되고 나면 @RestController 등으로 스프링 빈 등록한 클래스 들이 등록된다. 이때, 다양한 정보들도 함께 들어있고 인스턴스화도 이뤄진다. ex ) UserController에 @RestController를 붙였다면 이름 : UserController , 타입 : UserController 로 등록되는 것이다. 이렇게 스프링 컨테이너 안에 들어간 클래스들을 스프링 빈이라고 한다. 우리가 이전에 사용했던 JdbcTemplate 은 이미 스프링 빈으로 등록되어 있어 따로 등록하지 않아도 된다. ( 우리가 bulid.gradle 에서 dependencies 설정을 해줬기 때문이다.) 이후에 빈 등록이 완료되면 필요한 의존성을 자동으로 연결시켜주는데 UserController는 JdbcTemplate의 의존 관계가 연결된다. 그런데 만약 이때 BookController -> BookService-> BookMemoryRepository 에서 BookMySqlRepository를 연결하고 싶다면 기존의 Repository 코드뿐만 아니라 Service 코드에서의 인스턴스화 부분등 수정코드가 발생한다 우리는 이를 해결하기 위해 스프링 컨테이너를 사용해서 BookController -> BookService -> <interface>BookRepository <- BookMySqlRepository <- BookMemoryRepository 로 BookRepository 라는 인터페이스를 2개의 구현체가 구현하는 형태를 만들고 컨테이너가 어떤 Repository를 사용할지 선택하게 한다. 이러한 방식을 제어의 역전 (IOC ,Inversion of Control) 이라고 하고 컨테이너가 구현체를 선택해 BookService에 넣어주는 과정을 의존성 주입 (DI, Dependency Injection)이라고 한다.(2) Bean 을 등록하는 방법 @ Configuration : 클래스에 붙이는 어노테이션 , @Bean 과 함께 사용한다.@ Bean : 메소드에 붙이는 어노테이션 , 메소드에서 반환되는 객체를 스프링 빈으로 등록한다.@Service, @Repository : 개발자가 직접 만든 클래스를 스프링 빈으로 등록시 사용 @Component : 주어진 클래스를 컴포턴트로 간주한다. 이 클래스들은 스프링 서버가 시작할때 자동으로 감지(스프링 빈 등록) , Component는 @Service ,@ Controller, @Repository 에 다 있다.(3) 스프링 빈을 주입 받는 방법생성자 주입 ( 권장 ) : 프로젝트에서 제일 많이 사용하는 방식으로 private final 타입 변수 ; 로 선언후 생성자를 통해 인스턴스화 하는 방법 Setter 와 @Autowired 사용 : 누군가 Setter 사용시 오류가 발생할 여지가 있음 (주의) 생성자 주입에도 @Autowired 를 사용해야 하지만 생략이 가능하다.3. 필드에 직접 @Autowired 사용 : 제일 편리하지만 추후 테스트 작성시 코드 작성을 어렵게 하는 요인이 된다.  (4) <interface> 의 구현체가 여러개 일때 선택 기준  1. @Primary : @Primary 어노테이션이 있는 구현체가 우선권이 있다. 2.@Qualifier : 사용하는 Service 와 사용하는 Repository 구현체에 @Qualifier("main")을 적어주고 사용하는 Service 에 @ Qualifier("구현체이름") 을 추가한다.이때 @Primary 와 @Qualifier을 동시에 사용할 경우 더 자세한 @Qualifier 이 우선 순위를 가진다.회고 이번 주는 강의를 복습 하고 개념을 정리하는데 집중했다. 강의를 2번씩 들어보면서 스프링 컨테이너 ,빈 과 등록방법, DI, IOC 등 스프링의 핵심이라고 할 수 있는 개념을 정말 이해해보는데 시간을 많이 사용했고 전보다 깊이 있는 이해가 되었다. 다음주 강의에서는 개발한 API를 배포하는 과정을 거치는데 기대된다. 나만의 서비스를 만들어보고 싶은 마음이 컸는데 강의를 통해 목표에 조금 더 가까워진듯하다.

백엔드BE

mingle

[인프런 워밍업 클럽 스터디 BE 1기] 첫 번째 발자국

늦었지만 올려보는 첫 번째 발자국참여 계기취업 한지 벌써 2년이 되어간다. 일을 할수록 부족한 나를 마주하는 순간이 많았다. 그래서 항상 공부하겠다고 다짐했지만, 퇴근 후 공부는 생각보다 쉽지 않았고…. ㅎㅎ.. 그런 와중에 인프런에 들어왔다가 워밍업 클럽 스터디 배너를 보고 관심이 갔다. BE 강의 커리큘럼을 보니 회사에서 사용하지 않는 기술도 있어 더 흥미가 갔고 공부하기 좋은 기회라고 생각해서 지원하게 됐다. 배운 내용환경 세팅, HTTPHTTP Method(GET, POST, PUT, DELETE)를 활용한 간단한 API 개발MySQL과 DDL, DMLSpring과 DB 연결. CRUD API 개발.관심사의 분리 가장 인상 깊은 강의는 리팩토링이다. 회사 일을 하다가 내가 짠 코드에 대해 다른 직원분으로부터 문의를 받은 적이 있다. 시간에 쫓겨 작성한 부분이었고.. 강의를 들으면서 매우 많이 찔렸다. 아무리 바빠도 이후에 내 코드를 읽을 동료, 나를 위한 개발을 해야겠다고 생각했다. 화이팅~스터디에서 가장 만족하는 점은 과제다. 과제를 하다 보면 관련된 다른 궁금한 점이 생기고, 계속 샛길로 빠지게 된다. 한 과제를 하는데 하루 종일 걸린다ㅎㅎ.. 기한이 2일이라서 다행이다. 과제 덕분에 더 많이 배울 수 있었고 재밌었다. 이번 주에 배울 내용과 할 과제도 기대가 된다. 과제

백엔드BE워밍업1기

강예인

[인프런 워밍업 클럽_1기 BE] 첫번째 발자국

강의 수강일주일 동안 학습했던 내용IntelliJ설치, Spring 환경 설정, MySQL 설치개발을 위한 기본적인 환경설정을 해주었다. 네트워크 기초API 통신을 위한 기본적인 API동작 방식에 대해 학습했다.데이터베이스데이터베이스 세팅과 CRUD에 대해 학습했다.API 제작GET,POST,PUT,DELETE를 써서 사용자를 등록하고 수정하고 삭제하고 조회했다.사용자 정보가 없을 경우에 대해 예외처리를 했다.클린 코드클린코드가 왜 중요한지에 대해 학습했다.Controller가 하나의 기능만 하도록 분리하는 작업을 했다.미션1. 어노테이션어노테이션이 무엇인지와 장단점에 대해 알아보고 나만의 어노테이션을 만들어보았다.미션2. API 실습두 수의 합,차,곱을 반환하는 API제작LocalDate를 활용하여 날짜 요청시 요일 반환 API제작배열 안의 숫자를 모두 더하는 API 제작미션3. 람다식자바에서 람다식이 왜 생겨났는지와 람다식 문법을 알아보았다.회고참가 계기내가 주로 쓰고 있는 언어는 javascript와 C#인데 한국에서는 java를 주로 써서 블로그를 봐도 java에 대한 내용이 더 많이 보이기도 했고 코딩 테스트에서나 개발자를 채용할 때도 대부분 java가 기준이였다. 그래서 나도 한 번 java를 사용해서 서버를 만들어볼까 생각했었고 마침 인프런 워밍업 클럽 1기 스터디 모집 글을 보게 됐다. java를 안해본지 좀 오래됐는데 마지막으로 java를 쓴지는 한...3년 전이였나 기억도 나질 않는다. 그래도 기초부터 시작하니 커리큘럼대로 따라가기만 하면 문제 없을 것 같아서 신청하게 되었다.새로운 것IntelliJ  내가 처음에 java를 배웠을 때 Eclipse를 썼는데 이젠 IntelliJ를 쓰나보다. 솔직히 java는 내 관심 영역은 아니었기에 현재 쓰고 있는 컴퓨터엔 전혀 세팅이 되어 있지도 않았다. 내가 친숙한건 vscode,Visual Studio 이것 뿐.. Spring boot도 처음 써본다... mysql?  mysql은 써보긴했는데 이것도 대학생 때 썼으니 오래 전이긴하다. Oracle이랑 비슷해서 문제는 없긴한데 bigint 타입이 있어서 이건 뭐지? 했는데 ORACLE에서 NUMBER(19)를 표현한 거였다. 조금씩 다른데 적다가 헷갈리긴한다. 강의에서 IntelliJ에 DB연결해서 사용하는 부분이 있었는데 유료라서 굳이 돈을 써야할까 싶어서 CLI 창으로 했다. 미션미션 1. 어노테이션어노테이션이 무엇인지와 나만의 어노테이션을 만들어보는 미션이 있었는데 어노테이션이라는 개념을 처음 들어봤다. 그래서 찾아봤는데 C#에서 어튜리뷰트와 좀 비슷한 것 같았다. 이번에 flutter도 시작했는데 dart에도 어노테이션을 지원한다는 것을 알게됐다. java에서 annotation을 만들어보면서 다른 언어에는 어떻게 작동하는지 비교하면서 해결했다.미션2. API 실습  문제2번에서 C#에서 DateTime이 java에서 localDate를 쓰는 것을 확인했다. 작동 방식은 비슷한 것 같았다. 처음에 요청 받을 때 LocalDate로 받는 방식을 썼었다. 에러가 나서 설마 LocalDate로 받아와서 그런가 싶어서 String으로 바꿨었는데 결국 오타 때문에 안된 거였었다. 근데 바꾸기 귀찮아서 다시 안바꿨다. 과제가 끝나고 멘토님이 스프링 부트 2.x.x 버전대에서는 @DateTimeFormat 이라는 어노테이션을 사용해서 LocalDate 를 바로 받을 수 있고 3.x.x 버전 대에서는 어노테이션 추가 없이 LocalDate를 받을 수 있다고 답변 달아주셔서 String으로 받은게 조금 찔려서 다시 수정했다.미션3. 람다식자바에서 람다식에 대한 과제를 내주셨을 때 C#과 javascript,dart에서 쓰고있어서 반가웠다. C# LINQ와 비슷한 스트림(Stream) API도 알게 되었다. 각 언어별로 람다식으로 예제를 만들어서 연습해봤다.느낀점이번주 동안 강의를 듣고 미션을 수행하면서 각 언어 별로 어떻게 다른지 비교하는 방식을 통해 오히려 java에 대한 내용 뿐만 아니라 다른 언어를 이해하는데 도움이 된 것 같다. 언어 별로 독특한 기능과 차이점을 보면서 언어마다 어떤 문제를 해결하기위해 도입했는지 스토리를 찾아보는게 재밌었다.이번주 동안 진도표와 과제제출을 성실하게 수행한 나한테 칭찬한다..ㅎㅎ진도표와 과제제출을 통해 나태한 나에게 압박감을 주는 스터디가 나한테 맞는 것 같다.다음주에도 열심히 따라가야지!!

백엔드발자국인프런워밍업클럽1기BE

김찬희

[인프런 워밍업 클럽 스터디] 1기 첫번째 발자국

회고록 독학으로 공부를 하다보니 자기 객관화와 지금까지 뭔가 프로젝트를 처음부터 끝까지 완성해본 경험이 없고 부족하다는 생각이 들어서 무작정 신청하게 되었다. 처음에는 아 그냥 간단한 게시판 구현해보고 이후에 내가 기능 몇가지 추가해서 프로젝트 구현 하면 되겠다 정도로 가볍게 생각하고 들었던 강의였는데 강의를 하나씩 듣다보니 이전에 학습했던 내용들이 조립되는 느낌이 들어서 정말 개발에 흥미를 붙일 수 있었던 시간이었다. 사실 spring에 대해서 학습하다보면 전체적인 흐름을 놓치게 될때가 종종 있는거 같다. 스프링의 역사가 긴 만큼 하나의 기술에 대해 깊이 있게 파다보면 주변의 다른 기술과의 연결성을 잃을수 있다고 생각하는데 이 강의에서는 그 연결성에 대한 부분을 학습할 수 있어서 성장하는데 도움이 되었다.라이브러리 VS 프레임워크  라이브러리 : 프로그래밍을 개발할 때 만들어져 있는 기능을 가져다 사용하는 것 프레임워크 : 프로그래밍을 개발할 때 미리 만들어져 있는 구조에 코드를 가져다 끼워 넣는 것이때 강의에서는 요리에 비유를 했는데 김치 찌개를 만들때 라이브러리는 김치를 마트에서 가져오는 것, 프레임워크는 김치찌개 원데이 클래스에가서 만드는 것 이라는 설명이 이해하기 쉽게 와닿았다.@Annotation@SpringBootApplication : 스프링을 실행시키기 위해 필요한 다양한 설정들을 모두 자동으로 해주는 Annotation이다.@Annotation에 대한 추가 학습을 통해 개인블로그에 정리해보았다.https://velog.io/@chanheekim125/Annotation 네트워크란?네트워크 : 인터넷 주소 체계 ( 무언가(정보)를 전달할 때 필요한 체계)IP : 컴퓨터별로 갖는 고유 주소 ( ex) 244.69.51.9 ) 처럼 표시한다.DNS : 우리가 사이트에 접속할때 244.54.21.2 를 기억하고 입력할 수는 없으니까 ex) spring.com 등 이름을 사용PORT: 각 IP에는 여러가지의 프로그램을 사용하는데 이때 PORT 번호로 구분한다.HTTP와 API HTTP : 컴퓨터 간의 통신 표준 방식 ( 택배에서 운송장과 같은 개념 )HTTP 요청은 HTTP Method로 GET,POST가 주로 사용되며 PUT,DELETE 등이 있다.HTTP 요청에서 데이터를 전달하기 위해 쿼리(GET) 와 바디(POST)를 사용한다.이때 클라이언트와 서버는 HTTP를 주고 받으며 기능을 동작하는데 이때 정해진 규칙을 API라고 한다.API 개발하기 GET API POST API 직접 API 명세를 읽어보고 개발 해보면서 request를 받아서 데이터를 어떻게 처리하는지 알아보았다.https://velog.io/@chanheekim125/HTTP-API-%EA%B0%9C%EB%B0%9C데이터 베이스 이전 Section 에서는 그동안 Memory에 데이터를 저장하고 있었기 때문에 서버를 내리면 모든 데이터가 없어지는 현상이 발생했었다. 우리는 이러한 현상을 방지하기 위해 데이터를 DB에 SQL 문법을 사용해서 저장,조회,삭제,수정 하는 방법에 대해 학습하였다.SQL 문법은 정처기,SQLD 시험을 준비하면서 익숙했기에 개념보다는 MYSQL 실행툴에 익숙해 지는데 시간을 쓴거 같다. 정리 지금까지는 정말 기초라고 할수 있는 내용에 대해 학습해 보았다. 기본적인 API 기능을 구현할 수 있게 되었고 또, 무작정 강의만 수강해서 진도를 나가는 것이 아니라 과제를 하면서 스스로 동작 순서나 구현방법을 생각해보는 시간에 가장 많이 성장하는 나를 볼 수 있었다.

백엔드인프런워밍클럽StudyBE

이동원

인프런 워밍업 스터디 클럽 0기 BE - 1주차 발자국

1주차 회고 인프런에서 처음으로 시작하는 스터디 클럽에 들어간지 1주일이 되었습니다. 강의는 최태현님의 https://www.inflearn.com/course/lecture?courseSlug=%EC%9E%90%EB%B0%94-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%84%9C%EB%B2%84%EA%B0%9C%EB%B0%9C-%EC%98%AC%EC%9D%B8%EC%9B%90를 강사님께서 하루마다의 과제분을 주시고 공부한것을 블로깅 하는 방식이었습니다. 처음 과제의 양을 봤을때는 "할만한대?" 라는 생각으로 강의를 듣고 블로깅을 하였지만, 처음의 호기로운 생각은 어디가고 이것을 어떻게 글로써 풀어서 쓸지, 강의의 내용을 제대로 이해한 것은 맞는지 엄청나게 해매는 시간을 맛볼수 있었습니다. 강사님께서 훅훅 넘어가시고 중요한 개념을 짚어 주시고 진도를 나가시는데, 이것을 블로깅으로 조금 궁금한 점들을 계속해서 검색해보니, 아 spring이란것이 강사님께서 처음 접하는 사람들을 위해 최소한의 설명으로 이해하고 따라올 수 있도록 설명해주신 거구나, spring의 양은 방대하다는 것과 알아야 할 개념들이 많음을 피부로 느낄수 있었습니다. 또한 저의 부족함과 해야할 공부량에 압도 당하는 시간도 많았습니다. 스터디를 진행하면서 디스코드에 오늘의 과제분과 블로깅을 올려주시는 분들을 보면서 저와 비교되는 퀄리티와 이렇게 같은 강의를 듣고도 이렇게나 수준 차이가 난다고? 라는 생각을 떨쳐 버릴수 없었습니다. 그 와중에 강사님께서 해주신 말씀중 기억나는 것이 있었는데 한 수강생의 질문이 "백엔드 개발자로 취업하기 위해서 얼만큼 깊게 공부해야 하나요?" 라는 어조의 질문이었는데 "정해진 것은 없다 하지만 보통 아는것과 실력이 연봉과 비례한다" 라고 말씀해 주셨었습니다(잘 기억안남ㅎㅎ). 강사님의 말씀을 들으며 한가지 다짐을 했는데 '지금이 어떻든 나아지기 위해 지금의 스터디에 참가하고 좀더 잘하는 사람들의 결과물을 보며 내것으로 만들고 더 배우면 될것 아닌가?' 라는 다짐을 하게 되었으며 부족한 만큼 이 스터디 끝까지 완주해서 많은 것을 남겨 가야겠다 마음 먹었습니다. 이러한 스터디를 만들어 주신 인프런 분들께 감사드리고 열과 정성을 다해 가르쳐 주시는 강사님과, 함께 스터디를 참가하고 있으신 동료분들깨 감사드립니다. 이만 공부하러 가보겠습니다.

study워밍업BE

채널톡 아이콘