우리FISA

[우리FISA] 클라우드 서비스 개발 9주차 회고 📑

yunieyunie 2024. 1. 21. 22:13

1. 이번 주 학습 내용 📖

데이터 모델링, 정규화

현실에 존재하는 데이터를 데이터베이스에 적용하는 데이터 모델링을 배웠다.

ER모델을 통한 개념 모델링과 각 테이블 간의 관계 구분 및 정규화를 통한 논리 모델링 실습을 하면서 데이터베이스를 구축할 때는 고려할 사항들이 생각보다 많음을 느꼈다.

정보처리기사 공부할 때 열심히 외웠던 정규화가 왜 필요한 지에 대해 알 수 있었다.

실습한 것을 기반으로 신용등급에 따라 대출 상품 추천 목록을 조회하는 프로젝트를 수행했다.

실제 서비스라 생각하고 ERD 구축 실습을 해보면서 각 테이블에 필요한 컬럼들을 생각해보고 관계를 정의해보는 과정이 재밌었다.

 

 

JDBC API

데이터베이스에 저장된 데이터를 Java에서 활용하기 위한 java api인 JDBC에 대해 배웠다.

동작 흐름은 대략 다음과 같았다.

 

1. JDBC 드라이버 로딩 : 사용하고자 하는 JDBC 드라이버를 DriverManager 클래스를 통해 로딩한다.
2. Connection 객체 생성 : JDBC 드라이버가 로딩되면 DriverManager를 통해 데이터베이스와 연결되는 세션인 Connection 객체를 생성한다.
3. Statement 객체 생성 : Statement 객체는 작성된 SQL 쿼리문을 실행하기 위한 객체로  SQL 쿼리 문자열을 입력값으로 가진다.
4. Query 실행 : 생성된 Statement 객체에 들어간 SQL 쿼리를 실행한다.
5. ResultSet 데이터 조회 : 실행된 SQL 쿼리문에 대한 결과 데이터 셋을 조회한다.

6. 객체 Close : JDBC API를 통해 사용된 ResultSet, Statement, Connection 객체들을 사용한 순서의 역순으로 Close 한다.

 

그런데 java7 이후에 등장한 try-with-resources 문법에서는 자동으로 자원 해제를 처리해주는 기능을 제공했기에 굳이 close를 해줄 필요가 없었다.

// Java 7 이후 - try-with-resources 문법
  public List<Todo> findAll() throws SQLException {
      List<Todo> todos = new ArrayList<Todo>();

      String selectQuery = "SELECT * FROM todo";
      Connection connection = DBUtil.getConnection();
      Statement statement = connection.createStatement();
      ResultSet resultSet = statement.executeQuery(selectQuery);

      // DBMS에게 쿼리(SQL)를 전달할 객체 생성
      try (connection; statement; resultSet) {

          while(resultSet.next()) {
              int id = resultSet.getInt("id");
              String title = resultSet.getString("title");
              String description = resultSet.getString("description");

              //java.sql.Date
              Date date = resultSet.getDate("due_date");
              LocalDate dueDate = date.toLocalDate();

              boolean isCompleted = resultSet.getBoolean("is_completed");
              todos.add(new Todo(id, title, description, dueDate, isCompleted));
          }

      } catch (SQLException e) {
          e.printStackTrace();
      } 

      return todos;
  }

 

실습 프로젝트에서 직접 db를 구축하고 jdbc로 연결해 java로 sql 쿼리를 실행하며 데이터 CRUD를 수행했다.

이론으로만 알고 있던 JDBC를 직접 사용해볼 수 있어 좋았다.

 

 

Servlet

웹페이지를 동적으로 생성하는 서버 사이드 프로그램인 Servlet에 대해 배웠다.

servlet을 구동하기 위한 컨테이너 역할을 수행하는 tomcat도 같이 사용했다.

다음과 같은 코드로 servlet의 라이프 사이클을 알아보았다. 

package dev.syntax.step02servletprocess;

  import java.io.IOException;
  import javax.servlet.ServletConfig;
  import javax.servlet.ServletException;
  import javax.servlet.annotation.WebServlet;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;

  @WebServlet("/LifeCycleServlet")
  public class LifeCycleServlet extends HttpServlet {
      private static final long serialVersionUID = 1L;

      public LifeCycleServlet() {
          super();
          System.out.println("LifeCycleServlet() called");
      }

      public void init(ServletConfig config) throws ServletException {
          System.out.println("init() called");
      }

      public void destroy() {
          super.destroy();
          System.out.println("destroy() called");
      }

      protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          System.out.println("service() called");
          super.service(request, response);
      }

      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          System.out.println("doGet() called");
          response.getWriter().append("Served at: ").append(request.getContextPath());
      }


  }

 

서블릿의 생명 주기는 init(), service(), destroy() 메서드 호출 순서로 진행된다.

서블릿이 처음 로드될 때, 즉 웹 애플리케이션 시작 또는 첫 요청이 있을 때 LifeCycleServlet() 생성자가 호출되고 이후 init() 메서드가 호출된다.
클라이언트로부터 HTTP 요청이 오면 service() 메서드가 호출되고 이 메서드 내에서는 HTTP 요청 방식(GET, POST, PUT, DELETE 등)에 따라 적절한 메서드(doGet(), doPost() 등)를 호출한다.
이후 웹 애플리케이션을 종료하면 destroy() 메서드가 호출되는 것이다.

따라서 다음과 같은 순서로 출력됨을 알 수 있었다.

LifeCycleServlet() called
init() called
service() called
doGet() called
destroy() called

 

 

쿠키와 세션

쿠키와 세션에 직접 데이터를 저장하고 불러와보는 실습도 했다.

쿠키는 클라이언트, 즉 웹 브라우저에 저장되어 개발자 도구에서 확인이 가능하다.

반면 세션은 서버 측에 저장되며 서버가 가진 특정 객체에 저장이 된다.

이 쿠키와 세션을 사용하는 이유는 HTTP 프로토콜이 가진 비연결성과 비상태성이라는 특징 때문이었다.

모든 사용자의 요청마다 연결과 해제를 하기 때문에 연결 상태가 유지되지 않고 상태 정보가 저장되지 않기에 웹 사이트 재방문 시 효율적으로 서비스를 제공하기 위해 사용한다는 것이다.

세션에 아이디와 비밀번호를 저장하고 로그인, 로그아웃을 하는 간단한 기능 구현을 실습했다.

@WebServlet("/login")
  public class LoginServlet extends HttpServlet {

      @Override
      protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          resp.setContentType("text/html;charset=UTF-8");
          PrintWriter out = resp.getWriter();

          String id = req.getParameter("id");
          String pwd = req.getParameter("pwd");

          if (id.isEmpty() || pwd.isEmpty()) {
              out.print("아이디 및 비밀번호를 입력해주세요");
              return;
          }

          HttpSession session = req.getSession();
          if (session.isNew() || session.getAttribute("id") == null) {
              session.setAttribute("id", id); // id라는 이름의 키값에 사용자의 id값을 value로 설정
              out.print("로그인 완료");
          } else {
              out.print("이미 로그인 중입니다.");
          }
          out.close();
      }

  }

 

@WebServlet("/logout")
  public class LogoutServlet extends HttpServlet {
      @Override
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          response.setContentType("text/html;charset=UTF-8");
          PrintWriter out = response.getWriter();

          HttpSession session = request.getSession();
          if (session != null && session.getAttribute("id") != null) {
              session.invalidate();
              out.print("로그아웃 완료");
          } else {
              out.print("로그인 상태가 아닙니다");
          }

          out.close();
      }
  }

 

cs스터디에서 이론상으로만 공부했던 쿠키와 세션을 직접 실습해보며 왜 쿠키와 세션을 사용하는지에 대해 이해할 수 있었다.

 

 

2. CS 스터디 📔

화요일 저녁, 네트워크라는 큰 주제 안에서 각자 맡은 키워드에 대해 조사한 내용을 공유했다.

각 키워드에서 궁금한 점들을 질문하고 토론하며 부족했던 지식들을 채워가는 과정이 재밌었다.

몰랐던 부분에 대해 새로 알게되고 헷갈렸던 개념을 다시 정리하며 cs 지식을 쌓아가니 정말 개발자로서의 뇌(?)를 갖춰가는 기분이 들었다.🧠

특히 쿠키와 세션, TCP가 연결을 수립하고 해제하는 3-way handshaking과 4-way handshaking에 대해 깊게 이해할 수 있었다.

열심히 얘기하다보니 예상보다 시간이 꽤 많이 소요되었고 오히려 시간이 부족했다. 😮

내가 맡았던 부분은 http, https, http 메소드, 로드밸런싱이었는데 시간이 부족해 결국 나는 다음 주에 발표하게 되었다.

cs스터디가 끝나고 나니 정말 피곤했지만 스터디 시간은 재밌었다.😀

다음 주는 데이터베이스를 주제로 스터디할 예정인데 벌써부터 또 어떤 새로운 것을 배울 지 기대된다.😆

 

 

3. 알고리즘 스터디 💻

목요일 저녁, 알고리즘 스터디를 진행했다.

이번 주는 BFS가 주제였다.

사실 영화 웡카 시사회에 당첨되어 스터디를 빠지고 영화보러 가고싶었지만 BFS에 자신이 없었기에 영화보단 스터디를 택했다. 😥

DFS는 재귀식이라면 BFS는 queue를 사용해 푸는 방식이다.

기본 틀을 외우고 문제마다 응용하는 것이 필요한데 응용이 왜이렇게 어렵게 느껴지는지 모르겠다.. 😂

아직 연습이 많이 필요한 것 같다.

원래 주말에 주로 알고리즘 문제를 푸는 편인데 2주 연속 필기 시험 준비에 신경쓰다보니 우선순위에서 밀려 지난 주부터 알고리즘 문제 풀이에 다소 소홀했다.

다음 주부터는 다시 열심히!!!💪

 

 

4. 이번 주 음식 🍚🥘🥣🍲