게시글
블로그
전체 72024. 02. 28.
0
[인프런 워밍업 클럽] 6일차
진도표 6일차와 연결됩니다우리는 스프링 컨테이너의 개념을 배우고, 기존에 작성했던 Controller 코드를 3단 분리해보았습니다. 앞으로 API를 개발할 때는 이 계층에 맞게 각 코드가 작성되어야 합니다! 🙂과제 #4 에서 만들었던 API를 분리해보며, Controller - Service - Repository 계층에 익숙해져 봅시다! 👍 import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.sql.Date; import java.util.Map; @RestController public class FruitController { private final FruitService fruitService; public FruitController(FruitService fruitService) { this.fruitService = fruitService; } @PostMapping("/api/v1/fruit") public void saveFruit(@RequestBody FruitCreateRequest request) { fruitService.saveFruit(request.getName(), Date.valueOf(request.getWarehousingDate()), request.getPrice()); } @PutMapping("/api/v1/fruit") public ResponseEntity markAsSoldOut(@RequestBody Map body) { Long id = body.get("id"); if (id == null) { return ResponseEntity.badRequest().body("id 누락"); } fruitService.markAsSoldOut(id); return ResponseEntity.ok("'soldout'"); } @GetMapping("/api/v1/fruit/stat") public Map getSalesStat() { return fruitService.getSalesStat(); } }import org.springframework.stereotype.Service; import java.sql.Date; import java.util.Map; @Service public class FruitService { private final FruitRepository fruitRepository; public FruitService(FruitRepository fruitRepository) { this.fruitRepository = fruitRepository; } public void saveFruit(String name, Date warehousingDate, Long price) { fruitRepository.saveFruit(name, warehousingDate, price); } public void markAsSoldOut(Long id) { fruitRepository.markAsSoldOut(id); } public Map getSalesStat() { return fruitRepository.getSalesStat(); } } import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import java.sql.Date; import java.util.HashMap; import java.util.Map; @Repository public class FruitRepository { private final JdbcTemplate jdbcTemplate; public FruitRepository(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } public void saveFruit(String name, Date warehousingDate, Long price) { String sql = "INSERT INTO fruits(name, warehousingDate, price) VALUES(?, ?, ?)"; jdbcTemplate.update(sql, name, warehousingDate, price); } public void markAsSoldOut(Long id) { String sql = "UPDATE fruits SET status = 'soldout' WHERE id = ?"; jdbcTemplate.update(sql, id); } public Map getSalesStat() { String salesAmountSql = "SELECT SUM(price) FROM fruits WHERE status = 'soldout'"; String naoSalesAmountSql = "SELECT SUM(price) FROM fruits WHERE status IS NULL OR status != 'soldout'"; Long salesAmount = jdbcTemplate.queryForObject(salesAmountSql, Long.class); Long naoSalesAmount = jdbcTemplate.queryForObject(naoSalesAmountSql, Long.class); Map result = new HashMap(); result.put("salesAmount", salesAmount != null ? salesAmount : 0); result.put("naoSalesAmount", naoSalesAmount != null ? naoSalesAmount : 0); return result; } }
2024. 02. 26.
0
[인프런 워밍업 클럽] 과제 5일차
진도표 5일차와 연결됩니다우리는 라는 개념을 배웠습니다. 에 대한 감각을 익히기 위해서는 어떤 코드가 좋은 코드이고, 어떤 코드가 좋지 않은 코드인지 이론적인 배경을 학습하는 것도 중요할 뿐 아니라, 다양한 코드를 읽어 보며 어떤 부분이 읽기 쉬웠는지, 어떤 부분이 읽기 어려웠는지, 읽기 어려운 부분은 어떻게 고치면 좋을지 경험해보는 과정이 필요합니다.이번 과제는 제시된 코드를 읽어보며, 코드를 더 좋은 코드로 고쳐나가는 과정입니다. 구글에 “클린 코드” 혹은 “클린 코드 정리”를 키워드로 검색해보면, 이론적인 배경을 충분히 찾아보실 수 있습니다. 🙂 그러한 내용들을 보며 제시된 코드를 더 좋은 코드로 바꿔보세요! (코드를 바꿀 때 왜 바뀐 코드가 더 좋은 코드인지 다른 사람에게 설명하신다고 생각해보시면 더욱 좋습니다.) [제시된 코드]여러 함수로 나누어도 좋습니다! 🙂여러 클래스로 나누어도 좋습니다! 🙂 import java.util.Scanner; public class DiceSimulation { private static final int NUMBER_OF_SIDES = 6; public static void main(String[] args) { int numberOfRolls = promptForNumber(); int[] rollCounts = simulateDiceRolls(numberOfRolls); printRollCounts(rollCounts); } private static int promptForNumber() { Scanner scanner = new Scanner(System.in); System.out.print("숫자를 입력하세요 : "); return scanner.nextInt(); } private static int[] simulateDiceRolls(int numberOfRolls) { int[] rollCounts = new int[NUMBER_OF_SIDES]; for (int i = 0; i private static final int NUMBER_OF_SIDES = 6;여기서 12나 20으로 바꿔도 된다. 주사위 사진 예시 : https://www.google.com/search?sca_esv=600310596&rlz=1C5CHFA_enKR1067KR1067&sxsrf=ACQVn0_iT-qBMV0p_q-wUsDQsHY8hFBtlA:1705893428440&q=정십이면체+주사위&tbm=isch&source=lnms&prmd=ivsnbmz&sa=X&ved=2ahUKEwjMqc6ehPCDAxUSk1YBHUYeCcEQ0pQJegQIDhAB&biw=1512&bih=806&dpr=2
2024. 02. 25.
0
[인프런 워밍업 클럽] 발자국
이번 인프런 워밍업 클럽에 참여하게 되었습니다.인프런에서 강의를 듣고자하였지만 무엇을 들어야할지도 모르겠어서 늘 강의를 고르기만 하다가우연히 인프런 워밍업 클럽 수강을 보게 되었습니다.이걸 시작하면 기초를 다지는데 도움이 되겠다 싶어서 참여하게 되었습니다.강의를 보면서 많은 것을 배우고 알게 되었습니다.GET과 POST에서는 param과 body를 달리 쓴다는 것을 알게 되었습니다.그리고 유저를 생성하고, 수정하고, 삭제까지 배우고, 클린코드를 배웠습니다.지금은 선생님이 만들어주신 웹 사이트로 들어가서 등록하고 삭제버튼 누르고했지만 다음엔 제가 따로 등록버튼이랑 삭제버튼까지 만들어서 시도해보고싶다는 생각도 들었습니다.조금 더 기초를 탄탄히 다지는 느낌이었지만 클린코드는 정말 너무 어려웠습니다... 선생님께선 어떻게 이렇게 많은 코드를 알고 계실까.. 대단하게 느껴졌습니다.. 저도 언젠간 그렇게 능숙하게 되겠죠?코드 읽는 방법도 몰랐는데 강의를 보면서 코드를 어떻게 읽는지도 조금은 배워서 좋았어요. 늘 코드 치고나면 강의선생님께서 코드 해석까지 또 따로 해주셔서 그 부분도 너무 좋았어요.미션은 주로 선생님께 알려주신 것을 바탕으로 해결해나가고자 했습니다. 미션하다가 모르겠으면 코드 쳤던것을 보기도 하고,그래도 해결이 안될 때는 챗지피티의 도움을 받아서 해결해나갔습니다.처음에는 이 강의를 보고 내 개발 실력과 지식을 늘려가봐야지! 라는 생각을 가지며 시작하게 되었지만,지금은 과제를 빨리 해결해버리자가 되었습니다.이번 스터디 끝나면 다시 한번 강의를 복습하려고 합니다.
인프런워밍업클럽
2024. 02. 22.
0
[인프런 워밍업 클럽] 4일차 과제
진도표 4일차와 연결됩니다우리는 GET API와 POST API를 만드는 방법을 배웠습니다. 👍 추가적인 API 들을 만들어 보며 API 개발에 익숙해져 봅시다!CREATE TABLE fruits ( id INT AUTO_INCREMENT, name VARCHAR(255), warehousingDate DATE, price BIGINT, PRIMARY KEY (id) );import java.time.LocalDate; public class FruitCreateRequest { private String name; private LocalDate warehousingDate; private long price; public String getName() { return name; } public LocalDate getWarehousingDate() { return warehousingDate; } public long getPrice() { return price; } } import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.sql.Date; @RestController public class FruitController { private final JdbcTemplate jdbcTemplate; public FruitController(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @PostMapping("/api/v1/fruit") public void saveFruit(@RequestBody FruitCreateRequest request) { String sql = "INSERT INTO fruit(name, warehousingDate, price) VALUES(?, ?, ?)"; jdbcTemplate.update(sql, request.getName(), Date.valueOf(request.getWarehousingDate()), request.getPrice()); } } long을 사용하는 이유는 큰 숫자 범위를 처리하기 위해서이다. @PutMapping("/api/v1/fruit") public ResponseEntity markAsSoldOut(@RequestBody Map body) { Long id = body.get("id"); if (id == null) { return ResponseEntity.badRequest().body("id 누락"); } String sql = "UPDATE fruits SET status = 'soldout' WHERE id = ?"; jdbcTemplate.update(sql, id); return ResponseEntity.ok("'soldout'"); } @GetMapping("/api/v1/fruit/stat") public Map getSalesStat() { String salesAmountSql = "SELECT SUM(price) FROM fruits WHERE status = 'soldout'"; String naoSalesAmountSql = "SELECT SUM(price) FROM fruits WHERE status IS NULL OR status != 'soldout'"; Long salesAmount = jdbcTemplate.queryForObject(salesAmountSql, Long.class); Long naoSalesAmount = jdbcTemplate.queryForObject(naoSalesAmountSql, Long.class); Map result = new HashMap(); result.put("salesAmount", salesAmount != null ? salesAmount : 0); result.put("naoSalesAmount", naoSalesAmount != null ? naoSalesAmount : 0); return result; }
백엔드
・
java
2024. 02. 21.
0
[인프런 워밍업 클럽] 과제 3일차
진도표 3일차와 연결됩니다우리는 JdbcTemplate을 사용하는 과정에서 익명 클래스와 람다식이라는 자바 문법을 사용했습니다. 익명 클래스는 자바의 초창기부터 있던 기능이고, 람다식은 자바 8에서 등장한 기능입니다. 다음 키워드를 사용해 몇 가지 블로그 글을 찾아보세요! 아래 질문을 생각하며 공부해보면 좋습니다! 😊 [키워드]익명 클래스 / 람다 / 함수형 프로그래밍 / @FunctionalInterface / 스트림 API / 메소드 레퍼런스 [질문]자바의 람다식은 왜 등장했을까?람다식과 익명 클래스는 어떤 관계가 있을까? - 람다식의 문법은 어떻게 될까? 자바의 람다식은 왜 등장했을까?자바의 람다식은 코드의 간결성과 함수형 프로그래밍의 도입을 위해 등장했다.람다식을 사용하면 익명 클래스를 생성하고 이를 바로 사용하는 과정을 단순화 시킬 수 있다.이를 통해 코드가 간결해지며 가독성이 향상된다.람다식은 함수형 프로그래밍 패러다임을 자바에 도입하는데 중요한 역할을 한다. 함수형 인터페이스의 인스턴스를 생성하여 함수를 변수처럼 선언하는 람다식에서는메소드의 이름이 불필요하다고 여겨져서 이를 사용하지 않는다.대신 컴파일러가 문맥을 살펴 타입을 추론한다. 람다식과 익명 클래스는 어떤 관계가 있을까? - 람다식의 문법은 어떻게 될까?람다식과 익명 클래스는 둘 다 이름없이 사용되는 함수형 프로그래밍 요소이다.익명 클래스는 클래스 선언과 객체 생성을 한번에 수행하는 방법으로서 일반적으로 인터페이스를 구현하거나 클래스를 상속받아 메서드를 오버라이드 하는데 사용된다.람다식은 익명클래스를 더 간결하게 표현한 형태라고 볼 수 잇다. 람다식은 함수형 인터페이스를 구현하는데 사용된다. 함수형 인터페이스는 단 하나의 추상 메서드만을 가진 인터페이스를 말한다. 람다식 문법// 람다식의 기본 문법 (parameters, ... ) -> { body } /* parameters: 람다식이 받는 매개변수 리스트. 매개변수 타입은 생략 가능 >: 람다식의 표시 body: 람다식의 본문. 식 혹은 문장을 작성 가능. 만약 본문이 한 문장만 있는 경우 중괄호 {}를 생략 가능 */ // 예시 (int a, int b) -> { return a + b; }익명 클래스 문법new SomeFunctionalInterface() { @Override public int someMethod(int a, int b) { return a + b; } } 람다식은 더 간결하게 표현된다.
백엔드
・
JAVA
・
인프런워밍업클럽
2024. 02. 21.
0
[인프런 워밍업 클럽] 과제 2일차
진도표 2일차와 연결됩니다우리는 GET API와 POST API를 만드는 방법을 배웠습니다. 👍 추가적인 API 들을 만들어 보며 API 개발에 익숙해져 봅시다! Controller@RestController public class CalculatorController { @GetMapping("/api/v1/calc") public CalcRequest calc(@RequestParam int num1, @RequestParam int num2) { CalcRequest request = new CalcRequest(); request.setAdd(num1 + num2); request.setMinus(num1 - num2); request.setMultiply(num1 * num2); return request; } }DTO public class CalcRequest { private int add; private int minus; private int multiply; public int getAdd() { return add; } public int getMinus() { return minus; } public int getMultiply() { return multiply; } public void setAdd(int add) { this.add = add; } public void setMinus(int minus) { this.minus = minus; } public void setMultiply(int multiply) { this.multiply = multiply; } }결과Controller @GetMapping("/api/v1/day-of-the-week") public DayResponse getDayofWeek(@RequestParam String date) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDate localDate = LocalDate.parse(date, formatter); String dayOfWeek = localDate.getDayOfWeek().getDisplayName( TextStyle.SHORT, Locale.US).toUpperCase(); DayResponse response = new DayResponse(); response.setDayOfTheWeek(dayOfWeek); return response; } DTO public class DayResponse { private String dayOfTheWeek; public String getDayOfTheWeek() { return dayOfTheWeek; } public void setDayOfTheWeek(String dayOfTheWeek) { this.dayOfTheWeek = dayOfTheWeek; } } 결과DTOpublic class SumRequst { private List numbers; public List getNumbers() { return numbers; } public void setNumbers(List numbers) { this.numbers = numbers; } } Controller @PostMapping("api/v1/sum") public int sumNumbers(@RequestBody SumRequst requst) { return requst.getNumbers().stream().mapToInt(Integer::intValue).sum(); }결과{ "numbers" : [1, 2, 3, 4, 5] }
백엔드
・
JAVA
・
인프런워밍업클럽
2024. 02. 19.
0
[인프런 워밍업 클럽] 1일차 과제
진도표 1일차와 연결됩니다우리는 최초로 API를 만들어 보았습니다. GET API를 만들기 위해 사용했던 어노테이션에 익숙하지 않다면 자바 어노테이션에 대해서 몇 가지 블로그 글을 찾아보세요! 다음 질문을 생각하며 공부해보면 좋습니다! 😊[질문]어노테이션을 사용하는 이유 (효과) 는 무엇일까?나만의 어노테이션은 어떻게 만들 수 있을까?> 어노테이션을 사용하는 이유(효과) 는 무엇일까?어노테이션이란, @로 시작하는 코드이고어떤 용도로 사용할지, 어떤 역할을 부여할지 결정한다. 어노테이션의 장점은간결하다로직을 방해하지 않는다.정보를 제공한다. 어노테이션은 자식 클래스에 여러개의 메소드가 정의되어 있을 때 사용한다.그리고 컴파일러에게 문법 체크를 하도록 알려주는 기능이 있어서 컴파일 하기 전에 컴파일러가 이러한 사항을 체크해주며,프로그램 작성을 위해 매번 많은 설정을 해야하며, 수 많은 설정 파일들을 관리해야했지만 이 문제점을 해결하기 위해 고안된 문법이 어노테이션이라고 한다. 그래서 사용하는 이유는 쉽게 파악할 수 있게 되는 점과 오류 감소라고 생각한다. > 나만의 어노테이션은 어떻게 만들 수 있을까? 어노테이션 유형 package com.xxx.xxx; public @interface TODO{ String value(); } package com.group.libraryapp.controller.calculator; import com.group.libraryapp.controller.dto.calculator.request.CalculatorAddRequest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class CalculatorController { @GetMapping("/add") // GET /add public int addTwoNumbers(CalculatorAddRequest request) { return request.getNumber1() * request.getNumber2(); } } 수강하면서 배운 계산기 어노테이션 +가 아니라 *나 /로도 실행해보았다.
백엔드
・
워밍업스터디
・
백엔드
・
자바
・
JAVA