서버 개발 발 들이기 3

바람찬허파·2023년 9월 4일
0

지난 API에 이어서 오늘은 mysql을 통해 DB를 사용해보았다.

DB가 왜 필요한가?

서버를 열고, 가입한 회원의 정보를 GET API로 받아보았다.

List < User > users = new ArrayList<>();

회원 정보를 담는 리스트이고, GET API는 users에 담긴 User 객체를 가져와 출력한다.
그러나, 해당 데이터들은 메모리(RAM)에 담겨있다. 때문에 서버가 종료하면 -> 다! 사라지는 것이다.

위와 같은 그림에서 서버가 종료된다면, RAM에 있는 정보, 유저 정보가 모두 사라진다.
=> CPU - RAM - DISK 이 관계에서 RAM에 있는 회원 정보 데이터들을 DISK 에 저장해야 한다.
서버 어플리케이션은 DB를 사용해 데이터를 저장한다.

MySQL

관계형 데이터베이스 관리 시스템이다.

설치 과정

재수강했던 데이터베이스 기초 수업 때부터 냄새를 맡았다..
내 맥북에서는 sql을 사용할 수 없다는 걸..

homebrew로 수도 없이 깔고, 지우고, 구글링하고, 스택 오버플로우도 찾아보았지만 계속해서 오류가 발생했다. 결국 homebrew 사용하지 않고 mysql community server를 설치하였다.

DDL, DML

이전 수업에서는 SQL Developer를 사용하였기에, terminal에서 한 줄씩 SQL문을 작성하는 게 신기하다.

Spring에서 DB 사용하기

Spring 서버가 Mysql DB에 접속할 수 있도록 한다.

 //resources/application.yml
 spring :
  datasource:
    url: "jdbc:mysql://localhost/library" // 스프링이 접근할 데이터베이스 
    username: "root" 
    password : ""
    driver-class-name : com.mysql.cj.jdbc.Driver //데이터베이스에 접근할 프로그램

User 테이블 생성하기

user 데이터가 저장될 user 테이블을 생성한다

JdbcTemplete

기존에는 List 형태로 User 데이터를 저장/불러왔지만 <-> JdbcTemplete을 활용하여 데이터 베이스에 접근할 수 있도록 한다.

jdbcTemplete으 사용하면 -> sql을 MySQL에 날릴 수 있다.

package com.group.libraryapp.controller.user;

import com.group.libraryapp.dto.user.request.UserRequest;
import com.group.libraryapp.dto.user.response.UserResponse;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

@RestController
public class UserController {

    private final JdbcTemplate jdbcTemplate;

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

    @PostMapping("/user")
    void storeUser(@RequestBody UserRequest userRequest) {

        String sql = "insert into user (name, age) values (?, ?)"; //sql 
        jdbcTemplate.update(sql, userRequest.getName(), userRequest.getAge()); 
        // ? 부분에 각각 getName(), getAge()가 들어간다

    }


//기존 코드
/*
@GetMapping("/user")
    List<UserResponse> getUser() {
        String sql = "select * from user";
        return jdbcTemplate.query(sql, new RowMapper<UserResponse>() {
            @Override
            public UserResponse mapRow(ResultSet rs, int rowNum) throws SQLException {
                long id = rs.getInt("id");
                String name = rs.getString("name");
                int  age = rs.getInt("age") ;
                return new UserResponse((int) id, name, age);

            }
        });
    }

*/

//lambda로 수정한 코드
    @GetMapping("/user")
    List<UserResponse> getUser() {
        String sql = "select * from user";
        return jdbcTemplate.query(sql, (rs, rowNum) -> {
        // rs에 값을 담아와서, 이를 userResponse 객체에 집어넣음
        // 이 과정을 rowNum만큼 수행
       
            long id = rs.getInt("id");
            String name = rs.getString("name");
            int  age = rs.getInt("age") ;
            return new UserResponse((int) id, name, age);

        });
    }
}

아마 RowMapper<>의 경우 RN에서 forEach와 비슷하다는 생각이 들었다.

어제 진행했던 API 제작 + mySQL 연동 과정을 다시 지우고, 스스로 코드를 작성했다.
강의를 들을 때는 생각하지 못했던, 디렉토리에서 dto는 어느 위치에 와야 하는지, controller와 user 중 어떤 디렉토리가 상위 개념인지, 왜 필드가 유사한 User, UserRequest, UserResponse 클래스가 각각 있어야 하는지를 스스로 궁금증을 떠올리고, 해소할 수 있었다.

사실, 코드를 지울 때만 해도 내가 잘 떠올릴 수 있을까..? 하는 의문이었지만,
막상 코드를 지우고 나니, 수업 순서가 아닌 내가 필요하다고 생각하는 로직에 맞추어 클래스를 생성해나갈 수 있었다. 시간이 오래걸리긴 했지만, 그보다 많은 개념과 왜! 를 알 수 있었다.

조그맣지만 웹에서 서비스가 있고, 서비스를 사용하였을 때 (회원가입을 했을 때), 내가 개발자의 입장에서 새로운 데이터가 추가된 DB를 볼 수 있다는 게 너무 재미있었다. !
실제 서비스라면, 많은 실제 유저들의 데이터를 볼 수 있다는 점이 기대된다.

0개의 댓글