블로그

왜 자바 백엔드 실무에선 스프링 부트가 중요할까?

한국은 물론, 세계적으로도 가장 인기 있는 서버 개발 스택은 자바(Java) 언어 기반의 스프링(Spring) 프레임워크를 이용한 백엔드 기술입니다. 스프링은 불필요하거나 반복적인 코드를 줄임으로써 코드의 복잡성을 낮추고, 개발자가 핵심 비즈니스 로직에 집중할 수 있도록 돕는 역할을 합니다.하지만 스프링을 사용하려면 초기 환경을 일일이 설정해야 하는 등 번거롭고 어려운 면이 있었는데요. 이런 스프링의 복잡한 부분을 개선하고 보다 손쉬운 웹 애플리케이션 개발을 가능하게 한 게 바로 스프링 부트(Spring Boot)입니다. 스프링 부트를 통해 XML 구성을 할 필요도 없고, Tomcat 등의 기본 HTTP 서버가 내장되어 있어 편의성은 높으면서도 더 빠른 개발이 가능하게 되었죠.이러한 스프링 부트를 통해 자바/스프링 개발자들은 초기 설정처럼 핵심적인 부분은 아니지만 빼놓을 수 없는 공정의 부담을 덜어내고, 프로그램 및 시스템 운용이라는 관점에 집중하여 개발할 수 있게 된 셈입니다.•••베테랑 시니어 개발자들이 알려주는 스프링 부트 노하우가 궁금하신가요?지금 인프런 프리즘 [스프링 부트 로드맵]을 통해 학습해보세요. https://www.inflearn.com/roadmaps/649•••인프런 프리즘 브랜드 스토리 읽어보기 >>

백엔드SpringSpringBootJava스프링스프링부트백엔드Back-End인프런프리즘InflearnPrism

요즘 백엔드 취업 시장에서 코프링이 핫하다던데?

코틀린(Kotlin)은 젯브레인즈(JetBrains)에서 개발한 크로스 플랫폼 범용 프로그래밍 언어입니다. JVM 기반의 언어이면서 자바(Java)와 100% 호환되도록 설계되었습니다. 구글은 2019년부터 코틀린을 안드로이드 개발 공식 언어로 지정했어요. 간결한 문법, 안정성, 다양한 기능이 있다는 장점과 함께 전 세계적으로 사랑받고 있는 언어입니다.그동안 백엔드에선 자바 언어와 스프링 프레임워크의 조합이 가장 압도적인 점유율을 차지하고 있었는데요. 최근엔 코틀린을 도입하거나 자바를 코틀린으로 대체하려는 기업이 늘면서 코틀린 언어와 스프링 프레임워크의 조합, 일명 '코프링'이 주목받기 시작했습니다. 실제로 현재 취업 시장을 살펴보면 코틀린 언어를 다루는 능력을 자격이나 우대 사항으로 기재해 두는 기업을 어렵지 않게 찾아볼 수 있어요. 하지만 비교적 최근에 주목받고 있는 만큼 백엔드 현업에서의 코틀린 혹은 코프링 관련 사례나 자료를 찾는 건 쉽지 않죠.앞으로 사용이 더 늘어날 것으로 전망되는 코틀린, 코틀린과 코프링의 세계에 발 빠르게 뛰어들고 싶다면 지금 시도해 보는 건 어떨까요?•••Java 개발자를 위한실무밀착형 코프링을 배우고 싶다면?지금 인프런 프리즘 [자바 개발자를 위한 실전 코프링 입문 (Kotlin + Spring)]을 통해 학습해보세요.https://www.inflearn.com/roadmaps/703•••인프런 프리즘 브랜드 스토리 읽어보기 >>

백엔드코틀린Kotlin스프링SpringSpringBoot스프링부트코프링백엔드인프런프리즘InflearnPrism

wnsgh5049

22.11.28.(월) ~ 11.29.(화) TIL

22.11.28.(월) 월요일은 휴가 내고 어디 갔다가 저녁 먹고 <실전! 스프링 부트와 JPA 활용2> 강의를 들었다. RequestBody를 Entity로 받는 것이 아니라 DTO로 받는 것에 대한 내용이었다. 사실 스프링 부트 공부하면서 블로그를 찾아볼 때 DTO, DAO를 사용했는데 그걸 이해 못하고 넘어갔다. entity로 인자를 받거나 응답을 주는 것은 entity에 화면을 뿌리기 위한 로직이 들어가 있다. entity에 프레젠테이션 쪽 로직이 추가된 것이다. 또한 API의 스펙과 기능들이 entity에 들어왔다. 이렇게 되면 entity의 필드명이 바뀌면 API 스펙이 바뀌어 버린다. 또한 응답필드를 확장할 때 유연성도 떨어진다. 그래서 필요한 필드만 요청받고 응답받는 DTO를 사용하는 것이 좋다. 22.11.29.(화)화요일은 업무시간에 삽질한 내용이다. 시니어 개발자 분이 전달해준 기본 세팅이 된 프로젝트 소스코드를 받아서 코드를 볼려고 하였다. STS를 사용했는데 작동이 안되었다. Spring Boot App config에 Main Type이 정의가 안 되어 있었다. 그리고 그 외 여러 설정들을 해주니 실행이 되었다. 이것 저것 삽질하다가 하루가 다 갔다. 역시 세팅하는게 제일 어려운 것 같다... 기본 세팅되어 있는거 실행하는 것도 어렵다... 삽질하는데 전달해줄 때 설정이 뭔가 빠진 것 같다라는 생각이 들은 것에 반성하며...

웹 개발학습일기스프링부트

윤대

[인프런 워밍업 0기 Day5] 한 걸음 더! 객체 지향으로 클린코딩!

!! 해당 글은 독자가 인프런 워밍업 0기를 수강하고 있다는 전제 하에 작성되었습니다 !!과제 수행에 있어 스프링부트 3.2.2 버전을 사용하고 있다는 점을 미리 알려드립니다!안녕하세요🙌! 인프런 워밍업 5일차 과제입니다!이번에는 클린코드의 중요성에 대하여 학습하고 클린코드를 작성하는 방법에 대해 배웠습니다!😎저는 이번 과제를 그동안 책으로만 공부했던 객체 지향을 적용하여 해결해보고자 했습니다.이론으로만 공부했기 때문에 많이 서툴 수 있다는 점! 그렇기에, 저의 말이 정답이 아니라는 점을 미리 말씀 드리며!지금부터 객체 지향을 향한 저의 여정을 소개하겠습니다! 🤸‍♂️💡과제 살펴보기아래는 과제로 주어진 지저분한 코드입니다! 바라보기만 해도 머리가 어지러운데요.. 😥public class Main { public static void main(String[] args) throws Exception { System.out.print("숫자를 입력하세요 : "); Scanner scanner = new Scanner(System.in); int a = scanner.nextInt(); int r1 = 0, r2 = 0, r3 = 0, r4 = 0, r5 = 0, r6 = 0; for (int i= 0; i < a; i++) { double b = Math.random() * 6; if (b >= 0 && b < 1) { r1++; } else if (b >= 1 && b < 2) { r2++; } else if (b >= 2 && b < 3) { r3++; } else if (b >= 3 && b < 4) { r4++; } else if (b >= 4 && b < 5) { r5++; } else if (b >= 5 && b < 6) { r6++; } } System.out.printf("1은 d%번 나왔습니다.\n", r1); System.out.printf("2는 d%번 나왔습니다.\n", r2); System.out.printf("3은 d%번 나왔습니다.\n", r3); System.out.printf("4는 d%번 나왔습니다.\n", r4); System.out.printf("5는 d%번 나왔습니다.\n", r5); System.out.printf("6은 d%번 나왔습니다.\n", r6); } }위 코드는 결국 다음과 같은 동작을 수행합니다!주어지는 숫자를 하나 받는다.해당 숫자만큼 주사위를 던져, 각 숫자가 몇 번 나왔는지 알려준다.위 코드처럼 로직을 열거하여 프로그래밍 하는 방식을 절차 지향 프로그래밍이라 말하며, 저는 이 코드를 클린코드로 수정해야 합니다!위의 코드는 클린 코딩의 중요성을 위한 극단적인 예시일 뿐, 절차 지향이라 지저분한 것이 아닙니다!지나친 추상화는 오히려 코드의 가독성을 떨어트릴 수 있으니 무조건 '객체 지향이 좋다!'의 글이 아니라는 점 알아주세요!저는 위의 코드를 깔끔하게 바꾸기 위해서 아래와 같이 객체 지향의 형태로 수정하여 과제를 완수했습니다!public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); Dice luckyDice = UnknownDice.decideFaces(6); Note memoPad = new MemoPad(); Dealer dealer = Dealer.playWith(luckyDice, memoPad); System.out.print("숫자를 입력하세요 : "); dealer.rollDiceMultipleTimes(scanner.nextInt()); dealer.tellTheResult(); } }어떤가요? 내부 로직이 어떻게 되는지는 모르겠지만, 메소드명만을 보고도 원래의 코드와 똑같은 동작을 수행할 것이 기대할 수 있습니다!그렇다면, 내부는 어떻게 구현됐을까요? 내부 구현을 함께 살펴보기 전에 객체 지향이 무엇인지 짧게 설명 드리고 가겠습니다! 💡객체 지향 프로그래밍이란?객체 지향은 '프로그램이'라는 거대한 로직을 '객체'라는 작은 역할로 나누고, 그 '객체'들끼리 상호 협력하여 데이터를 처리하는 방식을 말합니다!어젯밤에 저는 오렌지를 하나 먹었는데요! 이 오렌지가 집에 오기 까지의 과정을 '프로그램'이라고 보겠습니다.그리고, 지금부터 오렌지의 여정을 절차 지향적으로 설명해보겠습니다! 😎먼저 오렌지 나무를 볕 좋은 곳을 찾아서 심고, 거름도 포대를 찢어서 뿌리 주변에 뿌려주고, 해충도 유기농을 위해 핀셋으로 잡아주고.. 설명이 끝도 없이 길어집니다!그렇다면 이번엔 오렌지의 여정을 객체 지향적으로 설명해볼까요?오렌지를 농부가 '재배'하고, 운송 회사가 '운송'하고, 마트에서 '판매'되어 저의 집까지 왔습니다!어떤가요? 훨씬 설명이 쉽고 이해하기 좋지 않은가요? 오렌지가 어떻게 재배되었는지, 운송되었는지, 판매되었는지 우리는 구체적으로 알 필요가 없습니다! 궁금하지도 않고요!이렇게 내부 구현을 숨기고, 역할 만을 외부에 공개하여 코드의 가독성을 올리고 협업을 용이하게 하는 것이 객체 지향의 장점입니다!이는 개체 지향의 단편적인 장점입니다! 더 많은 장점이 있지만, 지금은 클린코딩과 관련하여 추상화와 캡슐화로 인한 장점 만을 이야기하고 넘어가겠습니다! 😭😭 💡도메인 선정하기!  자! 이제 다시 과제로 넘어와 보겠습니다~ 위에서 객체 지향에서 중요한 것은 역할과 협력이라고 했습니다!우리는 요구 사항을 잘 읽고 작은 역할을 찾고 그 역할을 수행할 주인공(도메인)을 선정해야 합니다. 😎사용자로부터 숫자를 하나 입력 받는다.해당 숫자만큼 주사위를 던져, 각 숫자가 몇 번 나왔는지 알려준다. -> 핵심 로직!!저는 핵심 로직에서 두 가지 역할을 찾았습니다! 하나는 무작위의 수를 생성하는 것, 다른 하나는 생성된 수를 각각 세는 것입니다.그리고, 발견한 역할을 바탕으로 이를 수행할 두 가지 도메인을 만들었습니다.무작위 수를 생성하는 🎲주사위(Dice)와 이를 기록해주는 📃노트(Note)입니다!그렇다면, 이 둘을 재빠르게 설계해 볼까요?abstract public class Dice { private final int faces; protected Dice(int faces) { this.faces = faces; } protected int getFaces() { return this.faces; } abstract int throwDice(); } public interface Note { void record(Integer number); void printTheResult(); }다양한 경험을 위해, 저는 주사위는 추상 클래스로 노트는 인터페이스로 만들었습니다!Dice의 throwDice()는 주사위를 굴리는 행위를 나타내며 무작위 수를 생성합니다!Note의 record()는 입력되는 수를 기록하고 기록된 수는 printTheResult()를 통해 출력할 예정입니다!이렇게, 추상 클래스와 인터페이스로 만드는 이유는 해당 동작을 수행할 수 있다면 그게 무엇이든 역할을 대체할 수 있게 하기 위함입니다! 숫자를 기록하고 출력할 수 있다면 메모지던, 스케치북이던, 스마트폰이던 상관이 없습니다!이제 이 둘을 구현해보겠습니다!public class UnknownDice extends Dice { private UnknownDice(int faces) { super(faces); } public static UnknownDice decideFaces(int faces) { return new UnknownDice(faces); } @Override public int throwDice() { return (int) (Math.random() * super.getFaces()) + 1; } } import java.util.HashMap; import java.util.Map; public class MemoPad implements Note { private final Map<Integer, Integer> page = new HashMap<>(); @Override public void record(Integer number) { page.put(number, page.getOrDefault(number, 0) + 1); } @Override public void printTheResult() { for(Map.Entry<Integer, Integer> number : page.entrySet()){ System.out.printf("%d은(는) %d번 나왔습니다.\n", number.getKey(), number.getValue()); } } }이렇게, 구현이 끝이 났습니다! 그런데, 이럴 수가! 여전히 문제가 있습니다. 도메인을 구현한 것 만으로는 로직을 수행할 수가 없습니다..! 😥바로, 주사위와 노트를 어떻게 사용할 것인지 맥락(컨텍스트)이 없기 때문입니다! 💡컨텍스트 만들기!주사위는 무작위 수를 생성하고! 노트는 기록을 합니다! 제가 생성한 도메인은 자신의 역할을 잘 수행합니다!그러나 노트는 숫자라면 무엇이든 잘 기록할 수 있습니다! 그게 꼭 주사위의 숫자가 아니어도 상관이 없습니다.그렇기에, 우리는 맥락(컨텍스트)이 필요한 것입니다. 도메인을 연결하여 의미가 있는 역할을 수행하게 하는 것이죠!그렇게 저는 딜러(Dealer)라는 새로운 객체를 만들었습니다! 요청을 받아 주사위를 굴리는 게 게임 같았거든요..!public class Dealer { private final Dice dice; private final Note note; private Dealer(Dice dice, Note note) { this.dice = dice; this.note = note; } public static Dealer playWith(Dice dice, Note note) { return new Dealer(dice, note); } public void rollDiceMultipleTimes(int numberOfRoll) { for (int i=0; i<numberOfRoll; i++) { note.record(dice.throwDice()); } } public void tellTheResult() { note.printTheResult(); } }딜러의 역할은 게임의 진행입니다! 사용자에게 요청 받은 숫자만큼 주사위를 굴려주고! 노트에 결과를 전달하고 기록된 결과를 사용자에게 알려주는 역할을 수행합니다! 😃주사위와 노트는 딜러의 게임 진행이라는 맥락(컨텍스트) 아래에서 자신들의 역할을 수행합니다! 어떤가요? 객체들이 서로 협업 하며 역할을 잘 수행하여 로직을 수행하고 있습니다!또한, 흥미로운 점은 딜러는 주사위와 노트가 자신의 역할만 잘 수행할 수 있다면(인터페이스를 충실히 구현했다면) 얼마든지 다른 주사위나 노트로 바꿀 수 있습니다! 사기를 칠 지도 모르겠군요! 😜 💡정리하며...자, 이제 클린코딩을 수행한 코드를 다시 보겠습니다! 현재의 내부 구현은 모두 알지만, 구현체인 주사위와 노트는 언제든지 바뀔 수 있습니다!그러나, 우리는 주사위와 노트가 자신의 역할만 잘 수행할 수 있다면, 그것이 바뀌어도 상관이 없다는 사실도 알고 있습니다!이것이 객체 지향이 주는 다형성이라는 장점입니다! 글이 너무 길어져서 짧게 설명하는 점 죄송합니다...😭public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); Dice luckyDice = UnknownDice.decideFaces(6); Note memoPad = new MemoPad(); Dealer dealer = Dealer.playWith(luckyDice, memoPad); System.out.print("숫자를 입력하세요 : "); dealer.rollDiceMultipleTimes(scanner.nextInt()); dealer.tellTheResult(); } }객체 지향 정말 매력적이지 않은가요? 책을 통해 이론으로만 배운 객체 지향을 직접 설계부터 구현하며 쓴 저의 긴 기록을 지금까지 읽어주셔서 감사드리며, 객체 지향을 모르시던 분들께 조금이라도 도움이 되었으면 합니다!사실.. SOILD부터 대뜸 외우라고 하면, 어렵습니다 객체 지향..남은 스터디 기간도 다들 즐거운 코딩하시길 바라겠습니다! 🙇‍♂️

백엔드객체지향클린코딩스프링부트인프런워밍업클럽스터디도메인컨텍스트추상화캡슐화

wnsgh5049

22.12.03.(토) TIL - 디자인패턴에 대한 첫 고민

오늘은 <실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발>에서 주문 서비스 코드를 작성하였다.하다보니 강의를 보면서 코드를 작성하는 것보다 코드를 먼저 작성해보고 강의를 듣는 것이 코드와 강의를 이해하는게 더 좋은 것 같다.강의를 들으면서 궁금했던 점은 entity에 비즈니스 로직을 넣어도 괜찮은지. 그리고 new XXX() 을 사용해서 인스턴스를 만들어서 사용하지 않는지에 대한 내용이었다.그러면 import해온 entity는 어떻게 저장이 될까... 게다가 repository를 호출 안하고 주문 취소 로직을 작성하는데 어떻게 DB에 데이터가 수정이 될지에 대한 것이었다. 2번 질문에 대한 대답은 JPA의 강점은 entity 내에서 바뀌는 값들을 알아서 쿼리를 만들어 db에 날려준다.(영한님 말로는 변경된 감지라고 한다.) 그러면서 1번 질문에 대한 대답은 인스턴스를 여기저기 생성하여 코드를 작성하면 나중에 유지보수가 어려워진다고 하였다. 요즘 읽고 있는 <심플 소프트웨어>에서 "둘은 너무 많다"는 내용이 떠올랐다. 똑같은 걸 나타내는 상수든 함수든 뭐든지 두 개 이상이면 하나도 만들라는 이야기이다. 또 강의를 보면서 다른 분들이 적은 질문도 보는데 정적 팩토리 메서드, 프록시 같은 개념들도 나왔다. 공부하면 할 수록 더 공부해야되는게 많아지는 느낌이다. 내가 몰랐던 새로운 것들이 나타날 때 방대한 바다에서 헤어나오지 못해 허우적 되는 느낌이랄까... 더 공부해야 할 것JPA를 사용할 때는 도메인 모델 패턴SQL를 사용할 때는 트랜잭션 스크립트 패턴사내에서는 myBatis를 쓰니 트랜잭션 스크립트 패턴을 더 보아야겠다. 요약여러가지 디자인패턴에 대해 알게 되었다. 아직도 많이 모르고 있구나라는 생각이 든다. 그래도 지금이라도 알아서 다행이고, 나중에 연차가 쌓이면 이것들에 대해 진지하게 고민해보고 적용해 볼 날을 기대하며거인 위에 어깨에 올라타 있지만 내가 몰랐던 새로운 것이 나타날 때는 나는 작아진다.그래도 시간 지나 과거에 적은 TIL을 보면서 지난 날보다 성장했음에 뿌듯함을 느낄 날을 기대하면서 오늘도 공부하면서 성장하자.  

백엔드학습일기스프링부트

wnsgh5049

22.11.30.(수)~ 12.02.(금) TIL- 삽질의 연속

11.30.(수) ~ 12.02.(금)출근하기 전에 <실전! 스프링 부트와 JPA 활용2> 강의들었다. 주문조회 API를 Entity로 노출하는 것와 DTO로 노출하는 것, 그리고 fetch 조인에 관한 강의 3편을 들었다. 강의 시작 할 때 JPA를 완전히 이해하고 들으라고 했다. 하지만 일단 강의를 듣고 나중에 실습하면서 이해할려고 했다. 그래도 일단 이해한 것은 entity로 그냥 노출시키면 relation 관계에서 무한로딩이 빠질 수 있다는 점이었다. 해결 방법은 해당 entity 필드 양쪽 중 한 곳 에@JsonIgnore를 처리해야한다. 게다가 relation 걸린 수 많큼 1+N의 쿼리가 나가는데 이럴 때 fetch join을 사용하면 쿼리가 한 번만 나갈 수 있다.JPA를 실무에서 많이 사용하고 편하다고는 사용하기 위해서는 공부를 많이 해야 될 것 같다는 생각이 들었다.우선 사내에서는 mybatis를 사용하니 우선 거기에 익숙해지고 천천히 JPA를 공부해보아야 겠다. 회사에서는 이제 세팅된 스프링부트 코드 해석하고 테스트로 패키지를 따로 만들어서 그 안에 Controller, Mapper, Service, Repository, Entity 등을 다 넣어서 테스트 했다. 하지만 에러가 발생했는데 알고보니 MapperScan, EntityScan가 설정된 경로 외 다른 곳에 패키지를 만들어서 실행이 안되었다. 처음 접해보는거라 삽질을 많이한다. 게다가 테스트로 코드 작성하는 것도 오래 걸리고 나의 뇌가 버벅되어 생산성이 안 나오는 느낌이었다. 빨리 익숙해져야지... VSCode 쓰다가 intelliJ 잠깐 쓰다가 STS쓰니까 단축키 버퍼링도 온다...또한 Redis를 사용하여 토큰 값을 저장하였다. Redis 이야기는 많이 들어보았다. 하지만 사용하지는 않아서 다른 DB랑 똑같은 줄 알았다. Redis를 파고보니 key-value로 데이터를 저장하는 DB였다. 이렇게 새로운 사실을 알고나면 신기하지만 이걸 왜 아직까지 몰랐을까라고 생각하면 아찔하다. 또 Rest API를 사용하기 위해서 restTemplate를 사용해보았다. 세팅된 코드에는 RestTemplate를 @Configurete로 저장하여서 사용하였다. 이걸 인스턴스로 어떻게 꺼내어 사용하까 고민했는데 다른 분에게 물어보니 @Autowired로 사용해서 꺼내쓰면 된다고 하였다. 왜 그 생각을 못했을까... 이렇게 다시 Spring Container에 대해 배운 것이 생각이 났다. 이제 안 까먹겠지?restTemplate.exchage 쓰려다가 안되서 어짜피 post로 외부 API 받아올거라 restTemplate.postForEntity로 사용했다.JS에서 Axios를 사용했는데 사용법이 좀 다른 것 같다. 근데 이것도 익숙해지면 편해지겠지?  요약삽질을 많이했다. 코드 작성하는 속도가 느리다. 뇌가 버벅거린다. 나만의 단축키를 하나 만들어서 다른 코드 편집기를 사용하더라도 그거를 적용해야겠다.이제 담주부터 프로젝트 진도 나가겠지? 너무 떨린다... 근데 빨리 프로젝트하고 싶기도 하다. 배운 걸 빨리 써먹고 싶다.    

백엔드학습일기스프링부트

Yoo Seung Hwan

[인프런 워밍업 클럽 2기 백엔드 프로젝트 과정] 1주차 발자국

참여 동기바야흐로 2024년 8월 13일 1년 6개월간의 군생활을 마치고 전역했습니다.전역 후 아직 미래에 뭘 할지 몰라서 게임 개발, 웹 개발 등등 이것저것 뚝딱이면서 시간을 보내고 있었는데... 메일함에서 발견한 인프런 워밍업 클럽2기 홍보 메일독학의 한계항상 물어볼 곳을 찾고 싶었다.아마 대부분의 초보 코딩 독학러들이 하는 고민일까 싶습니다. 강의를 듣고 내가 프로젝트를 해나가도 내가 하는 방법이 맞는 걸까? 내가 짠 코드가 쓸만한 코드인가? 누군가가 내 코드를 보고 리뷰해줬으면 좋겠고 내가 하고 있는거에 대한 피드백을 해주기를 원했습니다. 부트 캠프는 좀 힘들고...그렇다고 부트캠프나 따로 받기에는 지역도 서울 경기 지방으로 한정되어 있고 대부분 6개월 정도의 긴 기간의 대면 수업을 요구합니다. 지방대생인 저로서는 그런 부트캠프보다는 기간이 짧고 비대면인 워밍업 클럽은 최적의 조건이였습니다. 다른 사람들 생각도 좀 들어보고 싶다.아직 낯설지만 천천히 가보겠습니다.덤으로 다른 개발자들과 소통할 수 있는 창구가 생기는 것 또한 마음에 들었습니다. 다른 개발자들의 생각과 공부법에 대해 궁금한점이 많았던 저에게 워밍업 클럽은 더없이 좋은 기회라 생각하여 신청하게 됬습니다.   1주차 발자국코틀린과 백엔드에 대해 몰라도 따라갈 수 있었습니다.처음에는 코틀린과 스트링 부트에 대해 아는게 하나도 없어서 잘 따라갈 수 있을까 걱정했었는데 양질의 강의 자료와 자세한 설명덕분에 이해하기 수월했습니다. 특히 시작전에 완성된 결과물과 기능에 대해 설명해주셔서 코틀린을 잘 몰라도 코드의 의도를 파악할 수 있어서 좋았습니다. 더 알고 싶은 부분들은 생활코딩 강좌와 구글 검색 chat gpt와 함께 해결해나갔습니다.  1일차 - 섹션1 웹 개발 기본과 프로젝트 준비개발할 프로젝트에 대한 기능 설명과 웹의 동작 원리에 대해 배웠습니다.I. 웹 서비스 구성 요소1) 클라이언트요청 주체 2) 서버응답 주체서버간 통신에서는 서버가 요청 주체가 될 수도 있음  3) 데이터베이스데이터의 집합RDBMS를 의미하기도 함  II. 브라우저에서 주소창을 입력하면 일어나는 일1) 클라이언트 <-> DNS클라이언트가 DNS에 도메인을 보내면 DNS에서 도메인에 해당하는 IP 주소를 찾아서 알려준다. 2) 서버에 데이터 요청클라이언트가 전달된 IP 주소를 통해 서버에 작업을 요청하며 작업에 필요한 데이터를 함께 전달 3) 서버에서 작업 처리서버는 작업을 처리하며 일반적으로 데이터베이스에 대한 CRUD(삽입, 조회, 수정, 삭제) 등의 작업을 수행한다. 4) DB 결과 반환데이터베이스가 서버에서 요청한 결과를 반환한다. 삽입, 수정, 삭제의 경우 작업의 성공 여부를 응답하고 조회의 경우 조회도니 데이터를 전달한다. 5) 작업 결과 클라이언트에 전달서버가 반환된 결과를 클라이언트에 응답 한다.III. 웹 프레임워크와 Spring1) 웹 프레임워크동적 웹 서비스 개발을 편리하게 만들어주는 도구라이브러리와 다른 점은 제어의 주도권이 프레임워크에 있다. (라이브러리는 사용자가 주도권을 가짐)2) Spring Framework자바 기반의 웹 프레임워크웹 서버 개발을 모듈화 3) MVC 패턴 (Model-View-Controller)소프트웨어 아키텍처 디자인 패턴 중 하나데이터와 화면 전달 과정의 역할을 분담해 놓아 유지보수성을 높임  1) Model : 데이터 담기 2) View : 사용자에게 보내지는 화면 담당, 데이터 꺼내옴3) Controller : 요청 받아 작업 수행, Model에 데이터 넣음   4) 레이어드 아키텍처(Controller-Service-Repository)가장 대중적인 소프트웨어 아키텍처 기능별로 세가지 계층으로 구분됨Presentation(Controller)클라이언트가 요청할 수 있는 인터페이스를 정의 Business(Service)목적에 맞게 데이터를 처리 Data Access(Repository)데이터베이스에 접근하여 작업 요청, 다양한 데이터베이스 처리 방법을 제공하면 여러 서비스에서 공통적으로 사용할 수 있다.  5) 스프링 Bean과 의존성 주입(Dependency Injection)Bean : 스프링에서 관리되는 객체를 의미한다. 스프링 컨테이너가 주체가 되어 객체를 관리하는 것 이를 제어의 역전(Inversion of Control), IoC이라고 한다. 처음에는 상속과 동일한 것이라고 생각했는데 상속과는 분명한 차이점이 있었다.Chat Gpt 검색에 따르면 상속과 DI의 차이점은 의존성을 내부에서 관리하냐 외부에서 관리하냐에 따른 차이라고 한다.의존성 주입은 의존성을 외부에서 관리하므로 객체간 결합도를 낮추어 독립적으로 이용되어 코드를 유연하게 구성할 수 있는게 장점이라고 한다. 상속의 목적은 공통 기능을 공유하여 코드의 중복을 줄이는 것, 의존성 주입은 객체간의 결합도를 줄이고 코드 유연성을 높이는것에 초점이 맞춰져 있다. ex) Service와 Client 객체가 있을때 아래와 같이 외부에서 객체를 주입한다.val service = Service() val client = Client(service) client.doWork()  IV. HTTP와 REST API HTTP(Hyper Text Transfer Protocol)네트워크로 통신하는 두 컴포넌트 간의 통신 규약요청/응답1) RequestStartLine, Header, Body로 이루워짐Start Line : HTTP 메서드 , URL, HTTP 버전을 표시Header : 컨텐츠의 길이, 유형, 클라이언트 정보 표현Body : 서버에서 작업을 처리하기 위해 필요한 실질적인 데이터2) ResponseStartLine, Header, Body로 이루워짐Start Line : HTTP버전, 상태 코드, 메시지를 표현Header : 컨텐츠의 길이, 유형, 클라이언트 정보 표현Body : 응답 결과 데이터HTTP 요청 메서드Get, Post, Put, Patch, Delete각각 Read, Create, Update, Delete 작업을 요청할 때 사용c.f) Put과 Patch의 차이점 : Put은 리소스 전체를 새 데이터로 교체, Patch는 리소스의 일부만 수정HTTP 상태 코드요청의 처리 결과를 표현하는 코드 100 단위로 의미를 가지며, 상세한 코드로 구체적인 결과를 표현하기도 한다.200 : Ok300 : Multiple Choice400 : Bad Request500 : Internal Server Error Rest ApiHttp 통신으로 동작하는 어플리케이션 기능을 정의하는 컨벤션 강제성은 없음URL을 이용한 표현HTTP 메서드를 활용한 행위의 표현HATEOAS 준수복잡한 비스니스에서는 REST를 준수하기 어렵기 때문에 팀의 컨벤션을 만들어두는 것이 좋다. V. 데이터베이스의 정의데이터의 집합, DBMS관계형 DB, 비관계형 DB로 나누어짐관계형 DB는 표를 통해 데이터를 표현하며 각 표(테이블)은 관계를 가짐 비관계형 DB는 관계형 DB를 제외한 모든 DB (key-value형 등) VI. JPA(Java Persistence Api)자바 ORM 기술 표준 인터페이스1) ORM인스턴스와 관계형 데이터베이스를 매핑해주는 기술 2) 트랜잭션여러개의 DB 작업을 하나로 묶어주는 것 (두 작업이 모두 실패하거나 성공하도록 묶는 것)     2일차 - 섹션2 개발 - Domain흠... 기본 문법도 모르군객체 지향 프로그래밍도 알고 강의에서 어떤 역할을 하는 코드인지 계속해서 설명해주셔서 코드를 이해하는데 막히지는 않았습니다. 설명이 없는 개념은 대충 추론해가며 강의를 빠르게 들었습니다. 하지만 워밍업 클럽 미니 프로젝트를 위해서는 결국엔 기본 문법에 대해 어느 정도 알고 있어야 할것 같아 강의 코드를 중심으로 GPT와 유튜브 무료 코틀린 강의를 보면서 독학하는 시간을 길게 가져갔습니다. (Annotation과 Package에 관해서도 하나도 몰랐었을 정도로 무지했습니다...) 강의를 보고 따라한 후 Chat Gpt에 코드를 복붙 필요한 개념에 대한 간단한 설명과 함께 부탁했고이를 토대로 개념을 간단하게 학습한 후 추가적으로 궁금하거나 더 알아보고 싶은 부분을 적어 놓은 후 2일차 공부를 마무리 했습니다. 3~4일차 - 복습 및 과제강의를 빠르게 한 번 더 훝어본 후 2일차에 적어 놓은 부분을 구글 검색과 유튜브 등으로 해결 했습니다. 알바를 하면서 모르는 개념을 공부하고 과제도 하다 보니 시간이 촉박했지만 속도보다는 더 자세하게 이해하는게 더 중요하다고 생각해서 개념 공부에 시간을 많이 투자했습니다. 다행히 1주차에는 익숙한 깃에 대한 개념 강의가 섞여 있어서 좀 더 여유롭게 과제에 투자할 수 있는 시간이 있었습니다. 1주차 과제 - 프로젝트 ERD 작성음 분명 강의 들었을땐 이해됬었는데강의에서 사용한 포트폴리오 사이트에 대한 테이블 설계에 대해서는 이해가 정말 잘 되었습니다. 하지만 제 프로젝트에서는 테이블을 어떻게 나눠야 할지 아직 이해가 부족했습니다.추가로 생활코딩님 유튜브를 보면서 공부한 후 다시 강의를 들으니 이해가 훨씬 수월 했습니다. 혹시 저처럼 테이블 설계에서 어려움을 느꼈던 분들은 보시면 도움이 될거 같습니다.https://www.youtube.com/watch?v=1d38YZKCM88&list=PLuHgQVnccGMDF6rHsY9qMuJMd295Yk4sa 처음에는 ERD를 나눌 때 HTML, CSS 작성할때처럼 종속관계가 있어야 좋다고 생각했었지만 강의를 듣고나서는 유지 보수와 확장을 고려해 서로 간의 의존도를 줄이는게 중요하다는걸 알았습니다. 최종적으로 작성된 ERD입니다. 전체 구성사용자 -> 목표로 선택된 책 -> 도서별 세부 목표 -> 목표마다 달린 댓글 구조로 설계했습니다. 사용자 -> 목표로 선택된 책1:N 관계입니다 한명의 사용자가 여러개의 책을 선택할 수 있기 때문에 이렇게 설계했습니다. 처음에는 웹에 있는 도서 목록을 크롤링해서 DB에 넣은 다음 도서 선택을 하는 식으로 할까 고민했었는데 크롤링할 양도 많고 DB에 없는 책을 목표로 선정하고 싶은 경우가 생길 것 같아서 그냥 사용자가 직접 목표 책에 대해 작성할 수 있도록 설계하기로 했습니다. (추후에 서비스를 좀 더 확장하게 된다면 Yes24나 교보문고 같은 사이트에 연결하며 광고 등을 붙이는 구성을 생각하고 있습니다. 만약 그렇게 된다면 유저가 직접 작성한 책과 연동된 책을 따로 다른 테이블에 두어 작성하는것이 기존 DB를 수정하지 않아도 되서 더 좋을거 같다고 생각합니다.) 등록된 책 -> ChosenBook1:N 관계입니다. 등록된 책을 다른 여러 사람들이 선택해서 사용할 수 있기에 이렇게 작성했습니다.  책을 처음 등록하면 DB에 저장하고 다른 사람들이 같은 책을 목표로 삼을때 사용할 수 있도록 지정하면 DB 부담이 좀 줄어들거 같다고 생각해서 이렇게 설계했습니다. 목표로 선택된 책 -> 세부 목표1:N 관계입니다. 하나의 책의 여러개의 세부 목표를 둘 수 있기에 이렇게 설계했습니다.  user에 바로 연결할지 아니면 책과 연동해서 작성해야 할지 고민했는데 사용자별 목표를 보여주는 것보다는 도서별 목표로 보여주는 것이 좀 더 독서 습관 만들기라는 취지에 더 어울릴 것 같아 이렇게 설계했습니다. 세부 목표 -> 댓글1:N 관계입니다. 목표별로 다른 사용자들이 여러 댓글을 달 수 있기에 이렇게 설계하였습니다.   5일차 - 최종 점검최종 점검 이라 적었지만 거의 대부분은 다른 분들이 올리신 과제를 확인하면서 제 과제에 잘못된 부분은 없는지 확인하는 시간이였습니다. 아직 ERD에 대한 확신이 없어서 과제를 올린 후에도 여러번 고쳤던것 같습니다.https://github.com/dellyu03/bookjeogX2ㄴ 혹시 ERD나 프로젝트에 대해 지적해주실 분 있으시면 언제든 환영입니다.   1주차 회고군대를 전역하고 나서 새로 시작한 알바와 워밍업 클럽 과정을 병행해나간 바쁜 한 주였습니다. 휴학하면서 혼자서 공부할 때면 집중하기도 어렵고 딴 짓 하기 바빴는데 정확한 목표를 설정해 주시고 과제도 내주시니 집중이 더 잘되었습니다. 혼자서 그냥 설렁설렁 한달 공부했던 효과를 1주일 압축으로 해낸 것처럼 배운것도 정말 많았습니다. 앞으로도 이렇게 천천히 노력해가면서 꼭 완주를 해내겠다는 다짐을 하게된 한 주였습니다. 

백엔드워밍업클럽스터디기록백엔드코틀린스프링부트

[인프런 워밍업 클럽 스터디] 13일차 - Spring Boot 설정, 버전업 이해하기

build.gradle빌드 스크립트라고도 불리며, gradle을 이용해 프로젝트를 빌드하고 의존성을 관리하기 위해 작성되었다.groovy 언어를 사용해 작성되었고, Kotlin이라는 언어를 사용할 수도 있다. org.springframework.boot 플러그인 역할스프링을 빌드했을 때 실행가능한 jar 파일이 나오게 도와주고스프링 애플리케이션을 실행할 수 있게 도와주고또 다른 플러그인들이 잘 적용될 수 있게 해준다. Spring 과 Spring Boot 의 차이점1. 간편한 설정2. 간단한 의존성 관리3. 강력한 확장성MSA에 적합한 모니터링  Lombokgetter, setter, 생성자와 같은 반복되는 보일러 플레이트 코드(boiler plate code)를 제거할 수 있다.lombok 의존성 추가IntelliJ lombok 플러그인 추가IntelliJ Annotation Processor 설정   Spring Boot 2.7.x 에서 3.0.x 로 업데이트 하기Java 최소 버전이 17로 업그레이드 되었다.많은 스프링 프로젝트, Thrid-party Library 가 버전업 되었다.AOT 기초 작업이 이루어졌다. AOT(Ahead of Time) 빌드를 할 때 스프링 애플리케이션을 분석하고 최적화하는 도구애플리케이션 시작 시간과 메모리 사용량을 줄일 수 있게 해준다.javax 대신 jakarta 패키지를 사용하게 된다.모니터링 기능들의 강화외의 다양한 세부적인 변경사항이 많음   

백엔드워밍업클럽스터디백엔드자바스프링부트

[인프런 워밍업 클럽 스터디] 12일차 - AWS와 EC2 배포

Section 7. 생애 최초 배포하기[목표]EC2에 접속하는 방법을 알아보고, EC2에 접속해 리눅스 명령어를 다뤄본다.개발한 서버의 배포를 위해 환경 셋팅을 리눅스에서 진행하고, 실제 배포를 진행한다.foreground와 background의 차이를 이해하고 background 서버를 제어한다.도메인 이름을 사용해 사용자가 IP 대신 이름으로 접속할 수 있도록 한다.[리눅스 기본 명령어]mkdir : 폴더를 만드는 명령어ls : 현재 위치에서 폴더나 파일을 확인하는 명령어ls -l : 조금 더 자세한 정보를 확인할 수 있다.cd : 폴더 안으로 들어가는 명령어pwd : 현재 위치를 확인하는 명령어cd .. : 상위 폴더로 올라가는 명령어rmdir : 비어있는 폴더(디렉토리)를 제거하는 명령어 sudo yum update : 관리자의 권한으로 설치되어 있는 여러 프로그램을 최신화한다.sudo yum install [프로그램이름] : 관리자의 권한으로 프로그램을 설치한다.sudo systemctl status [프로그램이름] : 프로그램의 상태를 확인한다.suto systemctl restart [프로그램이름] : 프로그램을 재시작한다.chmod : 파일이나 폴더의 권한을 변경한다.ctrl + c : foreground로 실행중인 프로그램을 중단하는 신호nohup [명령어] & : [명령어]를 background에서 동작하게 만드는 명령어rm : 파일을 제거하는 명령어 ps aux : 현재 실행중인 프로그램 목록을 확인할 수 있다. kill -9 [프로그램번호] : 해당 프로그램을 종료시킨다. vi : 리눅스 편집기인 vim을 사용하여 파일을 연다.cat : 파일에 있는 내용물을 모두 출력하는 명령어 tail : 현재 파일의 끝 부분을 출력하는 명령어 tail -f : 현재 파일의 끝 부분을 실시간으로 출력해준다.      

백엔드워밍업클럽스터디백엔드자바스프링부트

[인프런 워밍업 클럽 스터디] 10일차 - 객체지향과 JPA 연관관계

[1 : 1 관계][연관관계의 주인]Table을 보았을 때 누가 관계의 주도권을 가지고 있는가연관관계의 주인이 아닌 쪽에 mappedBy 옵션을 달아 주어야 한다.연관관계의 주인의 값이 설정되어야만 진정한 데이터가 저장된다.객체가 연결되는 기준이 된다. [연관관계의 주인 효과]상대 테이블을 참조하고 있으면 연관관계의 주인연관관계의 주인이 아니면 mappedBy를 사용연관관계의 주인의 setter가 사용되어야만 테이블 연결 [N : 1 관계] - @ManyToOne 과 @OneTOMany@JoinColumn연관관계의 주인이 활용할 수 있는 어노테이션.필드의 이름이나 null 여부, 유일성 여부, 업데이트 여부 등을 지정 [N : M 관계] - @ManyToMany구조가 봅잡하고, 테이블이 직관적으로 매핑되지 않아 사용하지 않는 것을 추천 cascade 옵션 : 한 객체가 저장되거나 삭제될 때, 그 변경이 폭포처럼 흘러 연결되어 있는 객체도 함께 저장되거나 삭제되는 기능orphanRemoval 옵션: 객체간의 관계가 끊어진 데이터를 자동으로 제거하는 옵션  [연관관계 정리]상대 테이블을 가리키는 테이블이 연관관계의 주인이다. 연관관계의 주인이 아닌 객체는 mappedBy를 통해 주인에게 매여 있음을 표히새 주어야 한다.양쪽 모두 연관관계를 갖고 있을 때는 양쪽 모두 한 번에 맺어주는게 좋다.cascade 옵션을 활용하면, 저장이나 삭제를 할 때 연관관계에 놓인 테이블까지 함께 저장 또는 삭제가 이루어진다.orphanRemoval 옵션을 활용하면, 연관관계가 끊어진 데이터를 자동으로 제거해준다.  [연관관계를 사용하면 무엇이 좋을까?]각자의 역할에 집중하게 된다.(응집성)새로운 개발자가 코드를 읽을 때 이해하기 쉬워진다.테스트 코드 작성이 쉬워진다.[연관관계를 사용하는 것이 항상 좋을까?]지나치게 사용하면, 성능상의 문제가 생길 수도 있고 도메인 간의 복잡한 연결로 인해 시스템을 파악하기 어려워질 수 있다.또한 너무 얽혀 있으면, A를 수정했을 때 B, C, D 까지 영향을 받을 수 있다.그렇기 때문에 비즈니스 요구사항, 기술적인 요구사항, 도메인 아키텍처 등 여러 부분을 고민해서 연관관계 사용을 선택해야 한다.  Section 5. 정리책 생성, 대출, 반납 API를 온전히 개발하며 지금까지 다루었던 모든 개념을 실습해본다.객체지향적으로 설계하기 위한 연관관계를 이해하고, 연관관계의 다양한 옵션에 대해 이해한다.JPA에서 연관관계를 매핑하는 방법을 이해하고, 연관관계를 사용해 개발할 때와 사용하지 않고 개발할 때의 차이점을 이해한다.   

백엔드워밍업클럽스터디백엔드자바스프링부트

[인프런 워밍업 클럽 스터디] 7일차 - Spring Data JPA를 사용한 데이터베이스

Section 4. 생애 최초 JPA 사용하기[목표]문자열 SQL을 직접 사용하는 것의 한계를 이해하고, 해결책인 JPA, Hibernate, Spring Data JPA가 무엇인지 이해한다.Spring Data JPA를 이용해 데이터를 생성, 조회, 수정, 삭제할 수 있다.트랜잭션이 왜 필요한지 이해하고, 스프링에서 트랜잭션을 제어하는 방법을 익힌다.영속성 컨텍스트와 트랜잭션의 관계를 이해하고, 영속성 컨텍스트의 특징을 알아본다.[SQL을 직접 작성하면 아쉬운 점]문자열을 작성하기 때문에 실수할 수 있고, 실수를 인지하는 시점이 느리다.특정 데이터베이스에 종속적이게 된다.반복 작업이 많아진다. 테이블을 하나 만들 때 마다 CRUD 쿼리가 항상 필요하다.데이터베이스의 테이블과 객체는 패러다임이 다르다.===> 그렇기 때문에 등장한 것이 JPA(Java Persistence API) [JPA란?]객체와 관계형 DB의 테이블을 짝지어 데이터를 영구적으로 저장할 수 있도록 정해진 Java 진영의 규칙이것을 코드로 구현한 것이 Hibernate. Hibernate는 JDBC를 내부적으로 사용한다. [JPA 어노테이션]@Entity : 스프링이 User 객체와 user 테이블을 같은 것으로 바라본다.  기본생성자 꼭 필요함.@Id : 이 필드를 primary key로 간주한다.@GeneratedValue : primary key는 자동 생성되는 값이다.@Column : 객체의 필드와 Table의 필드를 매핑한다. 이름이 같을 시 생략 가능. [spring.jpa.hibernate.ddl-auto]create: 기존 테이블이 있다면 삭제 후 다시 생성create-drop: 스프링이 종료될 때 테이블을 모두 제거update: 객체와 테이블이 다른 부분만 변경validate: 객체와 테이블이 동일한지 확인none: 별다른 조치를 하지 않는다 [지금까지 사용한 JPA Repository 기능]save: 주어지는 객체를 저장하거나 업데이트 시켜준다.findAll: 주어지는 객체가 매핑된 테이블의 모든 데이터를 가져온다.findById: id를 기준으로 특정한 1개의 데이터를 가져온다. [Spring Data JPA]복잡한 JPA 코드를 스프링과 함께 쉽게 사용할 수 있도록 도와주는 라이브러리 [JPA Repository에서 By 앞에 들어갈 수 있는 구절 정리]find: 1건을 가져온다. 반환 타입은 객체가 될 수도 있고, Optional<타입>이 될 수도 있다.findAll: 쿼리의 결과물이 N개인 경우 사용. List<타입> 반환.exists: 쿼리 결과가 존재하는지 확인. 반환 타입은 boolean.count: SQL의 결과 개수를 센다. 반환 타입은 long. [JPA Repository에서 By 뒤에 들어갈 수 있는 구절 정리]GraterThan: 초과GraterThanEqual: 이상LessThan: 미만LessThanEqual: 이하Between: 사이에StartsWith: ~로 시작하는EndsWith: ~로 끝나는  [과제]진도표 7일차와 연결됩니다우리는 JPA라는 개념을 배우고 유저 테이블에 JPA를 적용해 보았습니다. 몇 가지 문제를 통해 JPA를 연습해 봅시다! 🔥 

백엔드워밍업클럽스터디백엔드자바스프링부트

[인프런 워밍업 클럽 스터디] 6일차 - 스프링 컨테이너의 의미와 사용 방법

[정리] Section 3. 역할의 분리와 스프링 컨테이너좋은 코드가 왜 중요한지 이해하고, 원래 있던 Controller 코드를 보다 좋은 코드로 리팩토링 한다.스프링 컨테이너와 스프링 빈이 무엇인지 이해한다.스프링 컨테이너가 왜 필요한지, 좋은 코드와 어떻게 연관이 있는지 이해한다.스프링 빈을 다루는 여러 방법을 이해한다.  클래스 : 객체를 정의해놓은 설계도. 객체를 생성하기 위해 사용된다.객체 : 클래스에 정의된 내용이 인스턴스화되어 실제로 생성된 것. 설계도를 통해 만들어진 집.인스턴스(화) : 클래스를 실제로 사용할 수 있도록 생성하는 것. 스프링 빈 (UserController에 @RestController를 붙여줌으로써 스프링 빈이 됨)서버가 시작되면 스프링 서버 내부에 거대한 컨테이너(클래스 저장소)를 만든다.컨테이너 안에는 클래스가 들어간다.이 때 다양한 정보도 함께 들어있고, 인스턴스화도 이루어진다.이때 스프링 컨테이너 안으로 들어간 클래스를 스프링 빈이라고 한다.JdbcTemplate도 스프링 빈으로 등록되어 있다. (Dependency가 등록해 주고 있음)스프링 컨테이너는 필요한 클래스를 연결해준다.  서버가 시작되면 일어나는 일스프링 컨테이너(클래스 저장소)가 시작된다.기본적으로 많은 스프링 빈들이 등록된다.우리가 설정해 준 스프링 빈이 등록된다.이 때 필요한 의존성이 자동으로 설정된다. 스프링 빈을 등록하는 방법@Configuration클래스에 붙이는 어노테이션@Bean을 사용할 때 함께 사용해야 한다.  @Bean메소드에 붙이는 어노테이션메소드에서 반환되는 객체를 스프링 빈에 등록한다. @Service - @Repository 사용할 때 개발자가 직접 만든 클래스를 스프링 빈으로 등록할 때  @Configuration - @Bean 사용할 때외부 라이브러리, 프레임워크에서 만든 클래스를 등록할 때알아볼 어노테이션@Component주어진 클래스를 '컴포넌트'로 간주한다. 이 클래스들은 스프링 서버가 뜰 때 자동으로 감지된다.@Qualifier스프링 빈에 이름을 지정함으로써 특정 클래스를 가져옴 스프링 빈을 가져오는 방법(가장 권장) 생성자를 이용해 주입받는 방식 : @Autowired 생략 가능setter와 @Autowired 사용 : 누군가 setter를 사용하면 오작동 할 수 있다.필드에 직접 @Autowired 사용 : 테스트를 어렵게 만드는 요인이다.   참고자료 : https://mihee0703.tistory.com/182 

백엔드워밍업클럽스터디백엔드자바스프링부트

[인프런 워밍업 클럽 스터디] 4일차 - 데이터베이스를 사용해 만드는 API

 [이론 정리]생애 최초 database 조작하기디스크와 메모리 차이를 이해하고, Database의 필요성을 이해한다.SQL을 이용해 MySQL Database를 조작할 수 있다.스프링 서버를 이용해 Database에 접근하고 데이터를 저장, 조회, 업데이트, 삭제할 수 있다.API의 예외 상황을 알아보고 예외를 처리할 수 있다.  [과제]문제 1우리는 작은 과일 가게를 운영하고 있습니다. 과일 가게에 입고된 "과일 정보"를 저장하는 API를 만들어 봅시다. 스펙은 다음과 같습니다.HTTP method : POSTHTTP path : /api/v1/fruitHTTP 요청 Body { "name" : String, "warehousingDate" : LocalDate, "price" : long }HTTP 요청 Body 예시 { "name" : "사과", "warehousingDate" : "2024-02-01", "price" : 5000 }응답 : 성공시 200 💡한 걸음 더!자바에서 정수를 다루는 가장 대표적인 두 가지 방법은 int와 long입니다.이 두 가지 방법 중 위 API에서 long을 사용한 이유는 무엇일까요?  문제 2과일이 팔리게 되면, 우리 시스템에 팔린 과일 정보를 기록해야 합니다. 스펙은 다음과 같습니다.HTTP method : PUTHTTP path : /api/v1/fruitHTTP 요청 Body{ "id" : long }HTTP 요청 Body 예시 { "id" : 3 }응답 : 성공시 200  문제 3우리는 특정 과일을 기준으로 팔린 금액, 팔리지 않은 금액을 조회하고 싶습니다.예를 들어(1, 사과, 3000원, 판매O)(2, 사과, 4000원, 판매X)(3, 사과, 3000원, 판매O)와 같은 세 데이터가 있다면 우리의 API는 판매된 금액 : 6000원, 판매되지 않은 금액 : 4000원 이라고 응답해야 합니다.구체적인 스펙은 다음과 같습니다.HTTP method : GETHTTP path : /api/v1/fruit/statHTTP query- name : 과일 이름예시 GET /api/v1/fruit/stat?name=사과HTTP 응답 Body{ "salesAmount" : long, "notSalesAmount" : long }HTTP 응답 Body 예시 { "salesAmount" : 6000, "notSalesAmount" : 4000 }💡한 걸음 더!(문제 3번을 모두 푸셨다면) SQL의 sum, group by 키워드를 검색해 적용해보세요.   

백엔드워밍업클럽스터디백엔드자바스프링부트

[인프런 워밍업 클럽 스터디] 3일차 - 기본적인 데이터베이스 사용법

Section 2. 생애 최초 Database 조작하기[목표]디스크와 메모리의 차이를 이해하고, Database의 필요성을 이해한다.MySQL Database를 SQL과 함께 조작할 수 있다.스프링 서버를 이용해 Database에 접근하고 데이터를 저장, 조회, 업데이트, 삭제할 수 있다.API의 예외 상황을 알아보고 예외를 처리할 수 있다.  과제[키워드]익명 클래스 / 람다 / 함수형 프로그래밍 / @FunctionalInterface / 스트림 API / 메소드 레퍼런스 [질문]자바의 람다식은 왜 등장했을까? 람다식이 등장하게 된 이유는 불필요한 코드를 줄이고, 가독성을 높이기 위함이다. 그렇기 때문에 함수형 인터페이스의 인스턴스를 생성하여 함수를 변수처럼 선언하는 람다식에서는 메소드의 이름이 불필요하다고 여겨져서 이를 사용하지 않는다. 대신 컴파일러가 문맥을 살펴 타입을 추론하게 된다. 또한 람다식으로 선언된 함수는 1급 객체이기 때문에 Stream API의 매개변수로 전달이 가능해진다. 람다식과 익명 클래스는 어떤 관계가 있을까? -> 람다식의 문법은 어떻게 될까? 람다식(Lambda Expression) 이란 함수를 하나의 식(expression)으로 표현한 것이다. 함수를 람다식으로 표현하면 메소드의 이름이 필요 없기 때문에, 람다식은 익명 함수(Anonymous Function)의 한 종류라고 볼 수 있다.익명함수(Anonymous Function)란 함수의 이름이 없는 함수로, 익명함수들은 모두 일급 객체이다. 일급 객체인 함수는 변수처럼 사용 가능하며 매개 변수로 전달이 가능하다는 등의 특징을 가지고 있다.//람다 방식 (매개변수, ... ) -> { 실행문 ... } //예시 () -> "Hello World!"; 출처 : https://bny9164.tistory.com/79참고 : https://dwaejinho.tistory.com/entry/Java-Lambda-Stream-%EB%8F%84%EC%9E%85-%EB%B0%B0%EA%B2%BD%EA%B3%BC-%EC%9B%90%EB%A6%AC-%ED%8C%8C%ED%95%B4%EC%B9%98%EA%B8%B0#1.1%20%EB%9E%8C%EB%8B%A4%20%EB%8F%84%EC%9E%85%20%EB%B0%B0%EA%B2%BD-1

백엔드워밍업클럽스터디백엔드자바스프링부트

[인프런 워밍업 클럽 스터디] 2일차 - 첫 HTTP API 개발

 [Section 1 정리]스프링 프로젝트를 시작하는 방법과 실행하는 방법네트워크, IP, 도메인, 포트, HTTP 요청과 응답 구조, 클라이언트-서버 구조, API와 같은 기반 지식Spring Boot를 이용해 GET API와 POST API를 만드는 방법 [과제]문제 1두 수를 입력하면, 다음과 같은 결과가 나오는 GET API를 만들어보자!path : /api/v1/calc쿼리 파라미터 : num1, num2 { "add" : 덧셈결과, "minus" : 뺄셈결과, "multiply" : 곱셈결과 } 예시GET /api/v1/calc?num1=10&num2=5{ "add" : 15, "minus" : 5, "multiply" : 50 } 문제 2날짜를 입력하면, 무슨 요일인지 알려주는 GET API를 만들어보자!path와 쿼리 파라미터는 임의로 만들어도 상관없다. 예시GET /api/v1/day-of-the-week?date=2023-01-01{ "dayOfTheWeek" : "MON" } 문제 3여러 수를 받아 총 합을 반환하는 POST API를 만들어보자!API에서 받는 Body는 다음과 같은 형태이다.(HINT : 요청을 받는 DTO에서 List를 갖고 있으면 JSON의 배열을 받을 수 있습니다.){ "numbers" : [1, 2, 3, 4, 5] }반환 결과15⚠주의반환결과는 JSON이 아닙니다.함수에서 String 혹은 Integer를 반환하면, API결과가 JSON으로 나가지 않고, 단순한 값으로 나가게 됩니다.POST MAN과 같은 API 테스트 툴을 이용해 한 번 확인해보세요.

백엔드워밍업클럽스터디백엔드자바스프링부트

[인프런 워밍업 클럽 스터디] 1일차 - 서버 개발을 위한 환경설정

 Section 1. 생애 최초 API 만들기[목표]스프링 프로젝트를 설정해 시작하고 실행할 수 있다.서버란 무엇인지, 네트워크와 HTTP, API는 무엇인지, JSON은 무엇인지 등 서버 개발에 필요한 다양한 개념을 이해한다.스프링 부트를 이용해 간단한 GET API, POST API를 만들 수 있다. [이론 총정리](웹을 통한)컴퓨터 간의 통신은 HTTP라는 표준화된 방식이 있다.HTTP 요청은 HTTP Method (GET, POST)와 Path (/portion)가 핵심이다.요청에서 데이터를 전달하기 위한 2가지 방법은 쿼리와 바디이다.HTTP 응답은 상태코드가 핵심이다.클라이언트와 서버는 HTTP를 주고 받으며 기능을 동작하는데 이때 정해진 규칙을 API라고 한다. [사용 어노테이션]@RestController : 주어진 Class를 Controller로 등록한다. API의 진입 지점.@GetMapping("/add") : 아래의 함수를 HTTP Method가 GET이고 HTTP Path가 /add인 API로 지정한다.@RequestParam : 주어지는 쿼리를 함수 파라미터에 넣는다. [질문]어노테이션을 사용하는 이유 (효과) 는 무엇일까? Annotations in JavaAnnotations are used to provide supplemental information about a program.Annotations start with ‘@’.Annotations do not change the action of a compiled program.Annotations help to associate metadata (information) to the program elements i.e. instance variables, constructors, methods, classes, etc.Annotations are not pure comments as they can change the way a program is treated by the compiler.Annotations basically are used to provide additional information, so could be an alternative to XML and Java marker interfaces. 나만의 어노테이션은 어떻게 만들 수 있을까?How to Create Your Own Annotations in Java?Annotations are a form of metadata that provide information about the program but are not a part of the program itself. An Annotation does not affect the operation of the code they Annotate. Now let us go through different types of java annotations present that are listed as follows:Predefined annotations.: @Deprecated, @Override, @SuppressWarnings, @SafeVarargs, @FunctionalInterface.Meta-annotations: @Retention, @Documented, @Target, @Inherited, @Repeatable.Custom annotations: These are defined by the user. (We will be learning to create custom annotations in this module).Geek, now you must be wondering how can we create our own java annotations, for that refer to simple steps sequentially as follows:To create your own Java Annotation you must use @interface Annotation_name, this will create a new Java Annotation for you.The @interface will describe the new annotation type declaration.After giving a name to your Annotation, you will need to create a block of statements inside which you may declare some variables. 출처 1. https://www.geeksforgeeks.org/annotations-in-java/출처 2. https://www.geeksforgeeks.org/how-to-create-your-own-annotations-in-java/ 

백엔드워밍업클럽스터디백엔드자바스프링부트

채널톡 아이콘