728x90

출처 - https://inf.run/XKQg

 

1. DB

// 데이터베이스 생성
create database test;

// 데이터베이스 사용
use test;

// 테이블 생성
create table fruits (
    id bigint auto_increment,
    name varchar(20) not null,
    warehousingDate date not null,
    price bigint not null,
    isSold boolean default false,
    primary key (id)
);

 

 

2. Controller 코드

@RestController
public class FruitController {
    private final JdbcTemplate jdbcTemplate;

    public FruitController(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @PostMapping("/api/v1/fruit")
    public void insertFruits(@RequestBody FruitRequest fruitRequest) {
        String sql = "INSERT INTO fruits (name, warehousingDate, price) VALUES (?, ?, ?)";
        jdbcTemplate.update(sql, fruitRequest.getName(), 
        fruitRequest.getWarehousingDate(), fruitRequest.getPrice());
    }
 }
  • 생성자를 사용해 JdbcTemplate 객체를 주입 받는다.
  • Post요청으로 RequestBody 어노테이션을 사용하여 HTTP body 에서 과일 데이터(FruitRequest)를 받아온다.
  • 과일에 대한 정보(이름, 등록 날짜, 가격)을 넣어준다.
  • JdbcTemplate의 update메서드를 사용하여 쿼리를 실행한다.

 

3. DTO 코드

import java.time.LocalDate;

public class FruitRequest {
    private long id;
    private String name;
    private LocalDate warehousingDate;
    private long price;

    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public LocalDate getWarehousingDate() {
        return warehousingDate;
    }

    public long getPrice() {
        return price;
    }
}

 

4. 실행 결과

 

 

[질문] - 위 API에서 long 타입을 사용하는 이유는?

자바에서 대표적으로 사용하는 정수형 타입엔 int와 long이 있다. (byte와 short 도 있음)
하지만 여기서 long을 사용하는 이유는 무엇일까?

int형 데이터 타입에 저장 될 수 있는 정수의 범위는 –2,147,483,648 ~ 2,147,483,647으로 약 -21억 ~ 21억이다.
하지만 long 타입은  -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,808이다.

int타입에 비하면 엄청나게 많은 숫자이다.
작은 프로그램을 만들때에는 int형 데이터 타입으로도 충분히 저장 가능하다.

하지만 은행과 같은 숫자를 많이 다루는 대형 프로그램에서는 int형 넘어가는 범위의 숫자가 잘못 저장되는 것을 방지하기 위해
또, 나중에 프로그램이 커질 것을 대비하여 int타입으로 사용하기 보다는 처음부터 long타입으로 지정 하는 것이다.
(나중에 다시 변환하려고 하면 머리 아프니까..)

그렇다고 무조건 long타입이 좋은 것은 아니다 프로젝트 규모에 따라 잘 설계하는 것이 가장 좋은 설계인 것 같다.

 

 

출처 - https://inf.run/XKQg

 

1. Controller 코드

@RestController
public class FruitController {
    private final JdbcTemplate jdbcTemplate;

    public FruitController(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @PutMapping("/api/v1/fruit")
    public void updateFruits(@RequestBody FruitUpdateRequest request) {
        String readSql = "SELECT * FROM fruits WHERE ID = ?";
        boolean isExist = jdbcTemplate.query(readSql, (rs, rowNum) -> rs.getString("id"), request.getId()).isEmpty();
        if (isExist) {
            throw new RuntimeException("존재 하지 않는 과일입니다.");
        }
        String updateSql = "UPDATE fruits SET isSold = true where id = ?";
        jdbcTemplate.update(updateSql, request.getId());
    }
}

 

  • 위 코드는 PUT 메서드로 데이터 수정을 위해 사용하는 HTTP 메서드이다.
  • @RequestBody 어노테이션으로 HTTP Body에서 과일 데이터를 받아온다.
  • 해당 과일 id를 가진 과일이 없다면 "존재하지 않는 과일"이라고 보여준다. (예외를 발생시킨다.)
  • 만약 있다면 해당 id를 가진 과일을 isSold 컬럼을 true로 바꿔준다.

 

2. DTO

public class FruitUpdateRequest {
    private long id;
    private String name;

    public long getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

 

3. 실행 결과

 

[실행 전 데이터]

 

[실행 후 데이터]

  • 1, 3번 데이터를 실행해보겠다. (3번은 생략)

요청 결과 200 반환

 

 

위와 같이 1번, 3번 데이터의 isSold 컬럼이 1로 바뀐 것을 볼 수 있다.

(mysql에서는 1은 true, 0은 false이다. 일반적으로 프로그래밍에서도 동일하다.)

 

출처 - https://inf.run/XKQg

 

1. Controller 코드

@RestController
public class FruitController {
    private final JdbcTemplate jdbcTemplate;

    public FruitController(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    @GetMapping("/api/v1/fruit/stat")
    public FruitResponse selectFruits(@RequestParam String name) {
        String sale = "SELECT SUM(price) as salesAmount FROM fruits 
        				WHERE isSold = true AND name = ?";
        String notSale = "SELECT SUM(price) as notSalesAmount FROM fruits 
        				WHERE isSold = false AND name = ?";

        long salesAmount = jdbcTemplate.queryForObject(sale, (rs, rowNum) 
        					-> rs.getLong("salesAmount"), name);
        long notSalesAmount = jdbcTemplate.queryForObject(notSale, (rs, rowNum) 
        					-> rs.getLong("notSalesAmount"), name);

        return new FruitResponse(salesAmount, notSalesAmount);
    }
}

 

  • HTTP 메서드는 GET 메서드로 name(과일 이름)을 매개변수로 받고 있다.
  • sale은 isSold가 true이면서 매개 변수로 받은 과일 이름과 일치하는 과일의 가격을 더한다.
  • notSale은 isSold가 false이면서 매개 변수로 받은 과일과 일치하는 과일의 가격을 더한다.
  • 그렇게 해서 출력 방식인 salesAmount와 notSaleAmount를 리턴을 한다.

2. 실행 결과

[실행 전 데이터]

 

[실행 후 데이터]

 

 

 

[질문] - SUM과 GROUP BY 키워드

SUM: 주어진 열(컬럼)의 값들을 모두 더하는 SQL 집계 함수이다. 위와 같이 가격을 합산해주는 용도로 사용한다.
GROUP BY: 집계 함수와 함께 사용되고, 특정 열(컬럼)의 값에 따라 결과를 그룹화합한다.

 

 

 

강의 링크 👉 자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]

728x90

+ Recent posts