블로그
전체 32024. 02. 22.
0
[인프런워밍업클럽][BE] 과제4 | 과일가게 API 만들기
문제 1.1.1 DB 테이블 생성HTTP 요청 body에 price가 long이기에 int 말고 bigint로 해 봄primary key가 필요하여 수업에서 썼던 id 컬럼을 생성함.1.2 StoreControllerpackage com.group.libraryapp.controller.store; import com.group.libraryapp.dto.store.request.FruitInsertRequest; 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; @RestController public class StoreController { //0. JdbcTemplate 사용하도록 연결 private final JdbcTemplate jdbcTemplate; public StoreController(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } //1. 과일 정보 저장 @PostMapping("/api/v1/fruit") public void insertFruit(@RequestBody FruitInsertRequest request){ String sql = "INSERT INTO fruit(name, warehousingDate, price) values(?,?,?)"; jdbcTemplate.update(sql, request.getName(), request.getWarehousingDate(), request.getPrice()); } } 1.3 FruitInsertRequesthtml body에서 전송된 값을 java 변수 형식으로 변환해서 담아둘 dto가 필요하여 생성함정의된 형식에 맞춰서 생성.package com.group.libraryapp.dto.store.request; import java.util.Date; public class FruitInsertRequest { public String name; public Date warehousingDate; public Long price; public String getName() { return name; } public Date getWarehousingDate() { return warehousingDate; } public Long getPrice() { return price; } } 1.4 시연 결과postman 결과mysql 결과중간에 Date 값이 제대로 안들어갔다. 구글링하니 @JsonFormat이니 @DateTimeFormat이니 써보래서 써봤지만 소용이 없었다.강의록 앞부분을 다시 본 결과 warehousingDate (컬럼명)과 wareHousigDate(변수명)의 차이 때문이었다. 대문자...차이..때문에... 30분은 날린 듯 하지만 다음 문제를 풀어야 해서 테이블을 다시 drop & create 후 데이터를 다시 넣어주었다. 위 API에서 가격에 대하여 int가 아니라 long을 사용한 이유는?int에 비해 long이 표현할 수 있는 숫자의 양이 더 크다고 알고 있다. 그 외에 더 있을지도 모르지만..시간 상 생략.. 문제 2. 판매여부 데이터를 넣으라고 하는 문제근데, '판매여부' 관련 컬럼이 없다.2.1 fruit 테이블에 컬럼 추가fruit 테이블에 판매여부 값을 넣을 컬럼(soldout, 매진여부)을 추가한다.bool 타입을 지원한다고 하는데, 사실상 tinyint(1)으로 저장된다기에 처음부터 tinyint(1) 형식으로 만듦처음 입고된 시점에는 soldout 되었을 리 없으므로, 0(false)를 기본값으로 넣었다.alter table `fruit` add column `soldout` tinyint(1) default 0;기본값을 0으로 설정했기에, 그 전에 들어있던 데이터들도 해당 컬럼에 0으로 들어가 있는 것을 확인할 수 있다.2.2 StoreController : sellFruit()예외처리도 배웠겠다, 해당 id의 상품이 없으면 예외처리 하란 얘기렸다?사실 sql 문으로 없으면 false를 내뱉도록 짤까 생각했지만, (이건 간단하지만) 그런 자잘한 쿼리 하나하나가 DB에 부담을 줄 것 같아서 배운대로 했다.일단은 isEmpty()를 활용했는데, 주말에는 이것 외에 다른 방법은 없는지 좀 더 공부해보자.판매 시 호출하는 함수이므로, soldout = ? 할 필요 없이 바로 soldout = 1로 주었다. //2. 팔린 과일 정보 저장 @PutMapping("/api/v1/fruit") public void sellFruit(@RequestParam long id){ // 해당 id의 상품 존재 여부 파악 String selectSql = "SELECT * FROM fruit WHERE id = ?"; boolean fruitNotExist = jdbcTemplate.query(selectSql, (rs, rowNum) -> 0, id).isEmpty(); if(fruitNotExist){throw new IllegalArgumentException();} // 판매여부 데이터 업데이트 String updateSql = "UPDATE fruit SET soldout = 1 WHERE id = ?"; jdbcTemplate.update(updateSql, id); } 2.3 결과예시에서 1, 3번이 팔렸으므로 DB 조회 결과예외 처리 결과 문제 33.1 price 수정예제의 가격이 달라서 price 수정함update fruit set price = 3000 where id = 1; update fruit set price = 4000 where id = 2; update fruit set price = 3000 where id = 3;3.2 StoreController시간이 없어서 일단 된 곳까지 제출함근데 포스트맨으로 결과 내고나서 문제지랑 비교하니까.. 아 결과를 잘못 냈다..HTTP 응답 형식 맞게 다시 만들어야지ㅠㅠ//3. 판매/미판매 금액 조회 @GetMapping("/api/v1/fruit/stat") public List descStoreInfo(){ String sql = "SELECT f.soldout, sum(f.price) as amt FROM fruit f GROUP BY f.soldout"; return jdbcTemplate.query(sql, (rs,rowNum) -> { int soldout = rs.getInt("soldout"); long amount = rs.getLong("amt"); if(soldout==1){} return new FruitStatsResponse(soldout,amount); }); } 3.3 FruitStatsResponsepublic class FruitStatsResponse { private int soldout; private long amount; public FruitStatsResponse(int soldout, long amount) { this.soldout = soldout; this.amount = amount; } public int getSoldout() { return soldout; } public long getAmount() { return amount; } } 3.4 현재 결과ㅠㅠㅠㅠ 고쳐야 함..
백엔드
・
인프런워밍업클럽
・
인프런워밍업클럽BE
・
과제4
2024. 02. 21.
0
[인프런워밍업클럽][BE] 과제 3 | Lambda 식
1. 람다식(Lambda Expression) 이란?: 익명함수를 생성하기 위한 식 (Annoymous Function, 익명함수)1.1 람다식의 등장 배경- 복잡한 요구사항을 처리하기 위해 기존 Java 문법으로는 Method 사용이 늘어나는 등 코드의 복잡도가 높아짐- 메소드의 제한적 사용 - 객체를 통한 접근만을 허용 - 메소드 자체를 변수로 사용 불가 1.2 람다식 특징- 익명 함수 : 식별자없이 실행가능한 함수 (메소드명이 없음)- 간결한 문법- 함수형 인터페이스 지원1.3 람다식의 장/단점(1) 장점- 코드의 간결성 : 불필요한 반복문의 삭제 가능- 지연연산 수행 : 불필요한 연산 최소화- 병렬처리 기능 : 멀티쓰레드 활용- 가독성 향상 : 코드가 실제로 수행하고자 하는 로직이 추상적으로 드러남(2) 단점- 호출을 위해 직접 메소드를 불러야 함 : 람다식 생성 및 전달이 간결한 것과는 달리, 람다식 실행 시 인터페이스에 선언된 메소드 호출이 필요- 재귀 람다식 호출의 어려움 2. 람다식의 사용2.1 람다식 기본기본 형태 : 인터페이스 객체 변수명 = (매개변수, ..., 매개변수) -> {함수몸체;}구성요소매개변수 : 메소드 매개변수(parameter)하나일 경우 매개변수 또는 매개변수를 감싸는 () 생략 가능 (둘 다 생략은 안됨)화살표 : 코드 블럭을 실행(호출)메소드 구현부 (함수몸체) : {}함수몸체가 단일 실행문이면 {} 생략 가능단, 함수몸체가 return 문으로만 구성되어 있으면 {} 생략 불가 2.2 람다식 예제(추가 필요) 2.3 람다식 해석(1) 13강. GET API 람다 식 적용 전RowMapper = PreparedStatement + ResultSetJdbcTemplate.query()와 연동하여 사용SQL문의 결과값 각 행을 원하는 자료형으로 변환 : 즉, 각 행의 각 열(column)과 java 코드의 변수를 매핑시켜 줌.아래 코드에서 함수의 흐름은 다음과 같다각각 다음의 형식으로 매핑시킴long id : id bigintString name : name varchar(20)int age : age intreturn 시에는 method에서 반환값을 List로 정의했으므로 UserResponse 생성자를 이용하여 구성 @GetMapping("/user") public List getUsers(){ //1. SQL 조회 String sql = "SELECT * FROM users"; //2. JDBC 연결, 처리 return jdbcTemplate.query(sql, new RowMapper() { @Override public UserResponse mapRow(ResultSet rs, int rowNum) throws SQLException { long id = rs.getLong("id"); String name = rs.getString("name"); int age = rs.getInt("age"); return new UserResponse(id, name, age); } }); } (2) 13강. GET API 람다 식 적용 후람다식 적용전에 비해 짧아졌으며, 중요한 부분 (매핑되는 부분)이 강조되어 보임.람다식매개변수 : rs (=ResultSet), rowNum함수본체 : 각각 java 변수와 sql 결과를 매핑시킴그러나 여전히 rs = ResultSet 이고, RowMapper 인스턴스를 사용한다는 걸 어떻게 인지하는 건지 모르겠음. @GetMapping("/user") public List getUsers(){ String sql = "SELECT * FROM user"; return jdbcTemplate.query(sql, (rs, rowNum) -> { long id = rs.getLong("id"); String name = rs.getString("name"); int age = rs.getInt("age"); return new UserResponse(id, name, age); }); } 참고자료Lambda https://blog.naver.com/hj_kim97/222318922263https://blog.naver.com/it_jh/223356024460https://blog.naver.com/krkarma777/223278551937RowMapperhttps://blog.naver.com/3723578/223258910909https://mincanit.tistory.com/13
인프런워밍업클럽
・
인프런워밍업클럽BE
・
java
・
lambda식
2024. 02. 19.
0
[인프런워밍업클럽][BE] 과제 1 | Annotation
[질문]어노테이션을 사용하는 이유 (효과) 는 무엇일까?나만의 어노테이션은 어떻게 만들 수 있을까?1. Annotation1.1 Annotation어노테이션(Annotation) 이란?프로그래밍 언어에는 영향을 미치지 않으면서 프로그램에게소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함시키기 위해 추가이 속성/클래스의 용도/역할/기능을 부여컴파일러에게 코드 문법 에러를 체크할 수 있도록 정보 제 어노테이션(Annotation)의 사용 이유구성/설정 정보를 외부 XML 설정 파일에 명시하는 기존 자바 웹 애플리케이션 구조 하에서는 규모가 커지거나 코드의 수정이 이뤄짐에 따라 수 많은 재 설정이 필요했음어노테이션은 어노테이션이 붙은 클래스/함수 등의 메타데이터를 간단한 @어노테이션명 형식으로 명시함으로써, 해당 기능을 간단하게 설정하여 수행토록 함 어노테이션의 특징간결함 : 비즈니스 로직에 영향을 주지 않으면서 실행 흐름을 변경시킬 수 있는 코딩이 가능해클래스, 메서드, 변수, 인자에 추가 가능 대표적인 어노테이션@Controller@Override 1.2 Custom Annotation사용자가 직접 정의하여 사용하는 어노테이션프레임워크나 API 등을 만들어 사용할 때 주로 사용(1) Custom Annotation 정의하기@interface 를 통해 해당 클래스를 어노테이션으로 정의어노테이션 내부에 값을 가지거나 설정할 수 있음(참고한 블로그에서는 다른 어노테이션이 더 붙으나 아직 이해하지 못해서 아래 코드에는 넣지 않음)import java.lang.annotation.*; public @interface CustomApplication{ String bookName(); int price() default 10000; //값 설정 시 default 형태로 설정해야 함 } (2) Custom Annotation 사용하기import java.lang.annotation.*; @CustomAnnotation(bookName = "일리아스") class BookInfo { } 참고자료https://ittrue.tistory.com/158https://data-study-clip.tistory.com/130https://kkminseok.github.io/posts/2023-01-26-Annotation_Ad01/https://seongeun-it.tistory.com/142https://ggop-n.tistory.com/88https://advenoh.tistory.com/21
백엔드
・
인프런워밍업클럽
・
과제1