오랜만에 블로그 글을 쓰게 되었다.. 요즘 시간이 너무 바쁘게 흘러가고 있는지라 블로그 쓸 생각이 나지 않았던 것 같다 사실 귀찮은 것도 아주 컸다

 

스타트업 신입 개발자로 취업한 후기에 대해 작성하려고한다.

 

첫 직장이자 주관적인 내용이 담겨있기 때문에 "그럴 수 있구나"라고만 생각하고 넘어가 주길 바란다. 거시적 관점으로 "진짜 모든 스타트업이 혹은 모든 신입 개발자가 이렇구나?"라는 생각은 안 좋은 것 같다.

 

현재는 지방 파견근무로 업무를 진행하고 있다 처음 면접 때부터 전제조건이 지방 파견근무였기에.. 크게 불편함을 많이 느끼지는 않는 것 같다 업무적인 이야기로 넘어가자면 어떤 기업에 들어가던 처음은 항상 도메인 지식 공부로 시작한다. 내가 학교에서 스프링을 통한 웹페이지를 구성할 때와 조선소에서 사용하는 웹사이트를 구성할 때의 차이점을 생각해보자 특정 도메인에 사용되는 개념들과 수치들을 적절하게 활용하여 API로 제공하는 것과 혹은 웹사이트를 통해 시각화하는 것 등 범용적으로 모든 도메인을 사용할 수 있도록 구성하는 것보다 한 도메인의 초점으로 구성하되 확장성을 고려해 개발해두는 것이 더 맞는 것 같다. 사실상 모든 도메인을 이용할 수 있다는 게 가능한 것인지는 모르겠으나..

 

그리고 현재 나는 솔루션기업에서 근무를 진행중이기에 자사 솔루션 공부도 했었다. 어떤 서비스업에 종사하는 사람이라면 고객의 관점에서도 한번 서비스를 받아보아야 하지 않을까? 이런 느낌을 받았다. 실제로 고객의 입장인 것처럼 솔루션을 이용해보며 무슨 기능이 솔루션에 존재하는지, 어떻게 사용할 수 있는지 등 알아가는 시간이 필요했다.

 

그래서 약 1개월에서 1개월 절반 정도는 이러한 도메인 지식을 완벽하게 알기 위해 학습을 진행했던 것 같다. 이후 나는 API 개발 업무를 맡았으나 당장에는 진행되고 있지 않았기에 웹 개발자라기보다는 데이터 엔지니어의 업무적인 관점에서 데이 터전 처리를 위한 개발을 진행하고 있다

 

업무를 진행하며 느낀 점은 부족한 게 너무나도 많고 모르는 게 너무나도 많다는 것이다.  당연히 신입이기에 그렇겠지만 어느 정도 방향성은 맞춰서 직무를 선택해 입사를 결정하게 되었지만 그럼에도 불구하고 프로젝트를 진행했던 것들도 지금 다시 보면 너무 수박 겉핥기 식으로 스택을 사용했다는 것을 알게 되었다.

 

그래서 현재는 항상 검색하며 공부하면서 업무를 진행하는 게 일반적인 것 같다 진짜 모를 때만 주변 분들께 질문을 가끔 하기도 하고.. 모르는 채로 업무를 포기하거나 미루는 건 안 좋다고 느꼈기 때문이다.

 

그러면서도 또 문득 드는 생각은 내가 발전하고 싶은 방향과 연관이 있는 업무인지를 판단하는 시각이 아직 없는 것 같다 그래서 지금은 어떤 업무던 다 해결해보려고 노력하고 있고 여러 업무를 진행해보며 내가 원하는 방향으로의 업무 시각을 갖춰나가는 것도 중요하다고 생각한다.

'취업 이야기' 카테고리의 다른 글

의도치 않았던 이직  (0) 2023.06.03
SI직무 인턴쉽 후기  (0) 2022.09.08

<!doctype html>

[Java & DataBase] JDBC, JPA, Mybatis 차이점


스프링이나 이클립스를 통한 자바 개발을 진행하는 개발자라면 데이터베이스와 연동하는 과정을 개발해 본 경험이 있을 것입니다.

그중 관계형 데이터베이스(RDBMS)를 이용할 때 JDBC, JPA, Mybatis를 이용해 볼 수 있는데 구체적으로 어떠한 차이점이 있는지 궁금증이 생겨 개념 정리 및 학습을 진행하기 위해 한번 정리해볼까 합니다.

 

순서는 제가 학습했던 순서인 JDBC -> Mybatis -> JPA 순으로 설명하겠습니다

 

1. JDBC(Java Database Connectivity)


 

JDBC는 말 그대로 자바 프로그램이 데이터베이스와 연결할 수 있는 기능을 제공하는 프로그래밍 인터페이스입니다.

 

이러한 JDBC를 이용하기 위해서는 java.sql.Driver, java.sql.Connection, java.sql.Statement, ResultSet, PreparedStatement, CallableStatement 등을 이용 볼 수 있습니다. 실제 개발을 진행할 때는 import java.sql.*; 로 한 번에 가져와서 구현했습니다.

 

간단한 순서는 다음과 같습니다.

  1. Driver Load
  2. Connector Object Create -> Connection
  3. Statement Object Create
  4. Return Value Save Result Set Object
  5. Close

 

import java.sql.*;

public class ConnectDB{
  public static void main(String[] args)
  {
    try{
      //Connection Object Create
      Connection conn = null;

      //Connection
      String url = "jdbc:mysql://localhost/DB_Name";

      conn = DriverManager.getConnection(url, "DB_user", "DB_user_password");
      System.out.println("연결 성공");
    }
    catch(ClassNotFoundException e) // Error Case 1
    {
      System.out.println("Driver Loading Fail");
    }
    catch(SQLException e) // Error Case 2
    {
      System.out.println("Error : " + e);
    }
    finally
    {
      try
      {
        if(conn != null && !conn.isClosed())
        {
          conn.close();
        }
      }
      catch(SQLException e) // Error Case 3
      {
        e.printStackTrace();
      }
    }
   }
}

이러한 불편은 점차 jdbc의 역사가 발전해나가며 SQL Mapper와 ORM을 이용할 경우 코드상 활용하는 방식이 간결해졌습니다

추가로 jdbc를 이용할 때 Driver는 DataBase회사별 다르기 때문에 "com.mysql.jdbc.Driver" 와 같이 직접 찾아서 입력해야 합니다.

 

쿼리를 요청하는 코드를 확인해보겠습니다.

 

import java.sql.*;

public class SelectCase
{
  public static void main(String[] args)
  {
    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;
    
    try{
      // 1. Drvier Load
      Class.forName("com.mysql.jdbc.Driver");
      
      // 2. Connection
      String url = "jdbc:mysql://localhost/DB_Name";
      conn = DriverManager.getConnection(url, "DB_User", "DB_Password");
      
      // 3. Statement Object Create
      stmt = conn.createStatement();
      
      // 4. Write Query
        // 1) Select 할 때 * 로 모든 칼럼을 가져오기보단 특정 컬럼을 가져오는것이 좋다.
        // 2) 원하는 결과는 쿼리로써 정리하고 후작업은 권장되지않음
        // 3) 쿼리를 한 줄로 쓰기 어려운 경우 들여쓰기를 사용해도 되지만 띄어쓰기에 유의해야한다.
      String sql = "SELECT name, owner, data_format(birth, '%Y년%m월%d일' date FROM table)";
      
      // 5. Execute Query
      rs = stmt.executeQuery(sql);
      
      // 6. 실행결과 출력하기
      while(rs.next())
      {
        //Record colunm은 1부터 시작하며 DataType에 맞게 getInt, getString등을 이용
        String name = rs.getString(1);
        String owner = rs.getString(2);
        String date = rs.getString(3);
        
        System.out.println(name + " " + owner + " " + date);
      }
    }
    catch( ClassNotFoundException e){
      System.out.println("드라이버 로딩 실패");
    }
    catch( SQLException e){
      System.out.println("에러 " + e);
    }
    finally // Close Phase
    {
      try
      {
          if( conn != null && !conn.isClosed())
          {
            conn.close();
          }
          if( stmt != null && !stmt.isClosed())
          {
            stmt.close();
          }
          if( rs != null && !rs.isClosed())
          {
            rs.close();
          }
      }
      catch( SQLException e)
      {
        e.printStackTrace();
      }
  }
}

 

 

 

물론 간결하다고 항상 좋은 것은 아니고 장, 단점이 존재합니다

위 코드는 MySQL 일 경우의 과정이고 이 JDBC 역시 Java에서 제공하는 API이기에 개발자 입장에서는 데이터베이스마다 사용 쿼리를 각 DB마다 작성해주어야 합니다(DB의존적인 쿼리문).

 

또한 연결, 연결 해제 등의 과정의 코드를 반복적으로 작성해야 하기에 코드가 많이 길어집니다.

 

이 방식도 역시나 기존 애플리케이션의 디비 연동 과정 보다도 간소화되었지만 여기서 끝이 아닌 새로운 2가지 기술이 또 등장합니다.

 

SQL Mapper , ORM

 

SQL Mapper

SQL Mapper의 대표적인 기술로는 아래에서 설명할 MyBatis가 있으며 쿼리문을 파일로 관리할 수 있다는 점에서 장점이 있습니다.

또 위 JDBC의 단점인 반복적인 코드를 줄이고 응답 결과 자체를 객체로 반환합니다.

 

ORM(Object-Relational Mapping)

ORM은 SQL문을 작성하지 않아도 동적으로 생성해주며 DB마다 다르게 사용하는 SQL도 동일하게 작성 가능합니다.

단점으로는 러닝 커브가 존재하고, SQL 작성이 없지만 테스트 과정이나 기타 여러 상황을 고려해 개발자는 알아야 합니다.

자세한 내용은 밑에 3. JPA에서 더 설명하겠습니다

 

2. Mybatis


 

  • Mybatis는 Persistence framework입니다.
  • MyBatis는 위 사용했던 JDBC를 통해 데이터베이스에 액세스 하는 작업을 캡슐화하고 일반 SQL 쿼리, 저장 프로 시저 및 고급 맵핑을 지원해 중복작업을 제거합니다.
  • 또 SQL Query문은 한 파일에 구성해서 프로그램 코드와 SQL을 분리해 개발할 수 있는 장점이 있습니다.
  • 이렇게 파일에 구성하기 때문에 복잡한 쿼리나 다이내믹한 쿼리에 강하며 단점으로는 비슷한 쿼리가 많아질 수 있는 단점이 있습니다.

 

JDBC와는 다르게 ResultType, ResultClass 등 VO를 사용하지 않고 결과를 DTO, MAP에 맵핑해 사용할 수 있습니다.

mybatis

공식 문서는 다음과 같습니다. - https://mybatis.org/mybatis-3/getting-started.html

 

 

3. JPA


아래 사진은 NoSQL인 MongoDB를 JPA인 MongoRepository를 활용하기 위해 제가 그렸던 Class Diagram입니다.

mongo

사실 간결하게 표현되어 이해하기 어려울 수 있으나 실제 공식문서를 들어가 보면 인터페이스들이 많이 엮여있는 구조로 되어있다는 걸 알 수 있습니다. (비어있는 interface도 존재합니다)

JPA는 위 Mybatis와 JDBC와는 다르게 사용 명세를 많이 참조해야 한다는 단점이 있었습니다.

개인적으로 프로젝트에 적용하기 위해 쿼리문을 작성해보고 이를 함수 명세로 표현하기 위해서 다시 JPA공식문서를 뒤져보는 작업에 시간을 많이 소요했습니다.

이러한 JPA는 익숙해지기에는 시간이 오래 걸렸으나 한번 익숙해진다면 개발 속도는 빨랐기에 저도 가장 많이 사용해보았습니다.

이런 JPA의 특징으로는 ORM 기술 표준의 인터페이스 모음이며 인터페이스이기 때문에 Hibernate, OpenJPA 등이 JPA를 구현합니다.

또 프로젝트의 규모가 커질 경우 속도 저하, 일관성을 무너뜨리는 문제점, 학습 비용이 비싼 점 등이 존재합니다.

추가로 제가 구현할 때 중첩 쿼리문처럼 복잡할 경우에는 @Query 어노테이션으로 직접 Query를 작성할 수 있어 매우 유연한 구현 방식을 제공하고, 팀원들과 협업 시에도 JPA를 이용하기 위한 함수 네이밍 기준이 있어 가독성도 좋았습니다.

 

코드를 하나씩 다 쳐보며 설명하고 싶으나 시간적인 여유가 없어 현재는 특징 정리 정도로만 하고 추후 재 업데이트를 진행할 예정입니다

 

Reference


 

 

'JAVA' 카테고리의 다른 글

Java - Logging 이란?  (1) 2024.11.12
[Java] 언어의 특징  (2) 2022.09.09
[JAVA]직렬화 - Serializable란?  (0) 2022.05.16
[JAVA]DAO, DTO, VO 정리.  (0) 2021.12.25
DataLake, Data Mart, Data Warehouse 이란.md

DataLake, Data Mart, Data Warehouse 이란


일반적으로 데이터베이스에 데이터를 저장하고 우리는 데이터를 가지고와서 활용합니다.


여기서 이 데이터베이스에 저장된 데이터를 목적에 맞게 저장하게되고 이 목적에 따라서 우리는 Data Lake, Mart, Warehouse라는 용어로 부를 수 있습니다.


꼭 데이터베이스가 아니더라도 데이터를 저장하는 공간 자체를 목적에 맞게 부르기때문에 데이터베이스가 절대적인 것 같지는 않습니다 ex) 저같은 경우 Apache Hadoop 을 Data Lake로 생각하고 활용했습니다


그렇다면 각각 어떤목적으로 나누는 걸까요?



1. Data Lake(DL, 데이터 레이크)


  • 데이터 레이크는 말 그대로 "데이터 호수" 즉 원본데이터가 포함되며 아무런 작업이 이루어지지않은 저장소 입니다. 쉽게말해 전처리작업도 데이터 형변환 작업 등 아무런 작업이 일어나지 않은 원시 데이터가 저장되어 있습니다.
  • 비유를 해서 설명해드리자면 우리가 과일을 먹기위해서는 우선 수확이라는 과정이 필요하고 이 과일을 수확해서 농장 창고에 담아두는데 이 창고를 데이터레이크 라고 부를 수 있습니다.



2. Data Warehouse(DW, 데이터 웨어하우스)


  • 데이터 웨어하우스는 데이터레이크에서 얻어진 데이터들을 데이터마트에 저장하기 전 주제별로 저장합니다. 여기서 다시한번 저장하는과정 중 버려지는 데이터가 발생할 수 있습니다.
  • 쉽게생각하면 위에서 수확했던 과일을 각 지역별로 분류해서 저장해두거나 과일의 등급에 맞게 다시한번 더 나누어서 저장해둔 형태 로 생각해볼 수 있습니다.



3. Data Mart(DM, 데이터 마트)


  • 데이터마트는 위 데이터하우스로부터 얻어와 바로 활용할 수 있는 형태로 저장된 방식입니다. 프로그램의 목적에 맞게끔 저장할 수도 있고 아니면 광고를위한 영상일 경우 광고 길이에 맞춰 화질과 길이가 이미 처리된 상태의 영상이 담길수도 있습니다.
  • 말 그대로 마트 라는 의미기에 우리가 쉽게 마트에서 물건을 골라 소비할 수 있다고 생각하시면 좋겠습니다.


오늘은 일반적으로 데이터를 저장하는 목적에 따라서 (실무에서나 토이프로젝트 등) 저장된 공간을 의미하는 개념을 알아보았습니다.



 

Reference

REST API 란?


흔히 웹 개발자라면 REST API , REST ful 이란 말을 들어보셨을 겁니다.

 

 

이 REST API는 명확하게 무엇을 의미할까요?

 

 

REST를 한번 뜯어봅시다.

 

REST : Representational State Transfer API의 뜻으로 2000년대 웹의 장점을 최대한 활용할 수 있는 아키텍처입니다.

 

 

여기서 API는 Application Programming Interface로 애플리케이션에서 프로그래밍을 구축하고 통합하는 정의 및 프로토콜입니다. 흔히 API를 직접 프로젝트에서 활용할 때는 개발자(생산자)와 소비자(클라이언트)가 필요로 하는 호출(Request)과 응답(Response)을 구축합니다. 컴퓨터나 시스템에 사용자가 원하는 정보를 호출 및 응답받을 수 있도록 도와주는 조정자라고 생각하면 좋을 것 같습니다.

 

 

이어서 REST API를 설명하기 전 URI와 URL의 개념을 한번 짚고 넘어갑시다.

 

 

URL, URI 많이 들어봤는데 실제로 명확하게 어떤 차이점이 있을까요?

 

 

URN과 URL은 사실 URI에 포함되어있습니다.

 

 

URI,URL

위 사진을 보면 조금은 감이 오실까요?

 

 

위치는 고정적이며 식별자라고는 말할 수 없기 때문에 URL이며 URL 속 식별자를 이용해 특정 데이터를 지정할 수 있습니다.

 

 

이처럼 REST API를 이용할 때 URI를 통해 특정 데이터를 호출하고 응답받을 수 있습니다.

 

 

REST API 구성요소


 

REST API는 3가지의 구성요소가 있습니다.

  • 자원(RESOURCE) - URI
  • 행위(Verb) - HTTP method
  • 표현(Representations) - Representation of Resource

여기서 자원은 위에서 설명드린 URI개념으로 서버에 특정 자원을 Identifier로 구별하고 호출할 수 있어야 합니다.

 

 

행위(Verb)는 기본적인 HTTP 요청 Method로 Get, Put, Delete, Post, Patch를 통해 서버에 요청을 보낼 수 있어야 합니다. 우리는 흔히 CRUD(Create, Read, Update, Delete 기능을 구현하는 것과 매칭 된다고 보시면 됩니다.) 기능을 구현하고 이를 앞에 메서드에 맞게 구현합니다.

 

 

표현은 위 자원을 나타내는데 이 자원을 주고받기 위한 형식이 일반적으로 JSON, XML 형식이라는 것입니다.

 

 

그래서 이 구성요소로 어떻게 한다는 건데~라고 생각할 수 있는데

 

 

위 구성요소를 활용해 REST API라고 불리는 아키텍처 규칙에 맞게 구현해야 합니다.

 

 

이 설계 규칙을 모두 적절하게 잘 지켰을 경우 우리는 RESTful API라고 말할 수 있습니다.

 

 

이 REST API의 설계 규칙은 다음과 같습니다.

 

 

1) Uniform (유니폼 인터페이스) - 일반성의 원칙을 적용하고 아키텍처를 단순화하고 상호 작용의 가시성을 향상할 수 있다. 즉 리소스(자원)를 간결하고 명확하게 그리고 고유한 표현을 통해 식별할 수 있어야 합니다 ( URI를 조금 더 명확하게 네이밍하고 이용해야 합니다.)


2) Stateless (무상 태성) - 서버는 작업에 따른 상태 데이터를 따로 저장하지 않습니다 그렇기에 구현이 단순합니다. 또 요청 응답 간의 데이터 역시나 저장하지 않으며 사용자에 대한 세션 상태는 완전히 유지해야 합니다.


3) Cacheable (캐시 가능) - REST API는 HTTP의 표준 형식을 이용하기 때문에 캐싱 기능이 존재합니다. 그중에서도 응답에 따라 캐싱 가능과 불가능으로 레이블을 분리하고 캐싱이 가능할 경우 일정 기간 동안 사용자에게 해당 응답 데이터를 재이용할 수 있는 권한을 부여할 수 있습니다. 여기서 사용되는 캐싱 기능 역시 HTTP에 존재하는 캐싱 기능입니다.


4) Self-descriptiveness (자체 표현 구조) - 위 리소스를 특정 고유 표현으로 표현했기 때문에 REST API의 메시지 만으로 어떤 의미에 요청인지를 인지할 수 있는 구조가 되어야 합니다.


5) Client - Server 구조 - 클라이언트와 서버를 명확하게 나누어 확장성을 개선해야 합니다. 클라이언트와 서버가 진화(? 업데이트할 동안) 이 클라이언트 - 서버 간의 인터페이스가 가 깨지지 않도록 합니다.


6) 계층형 구조 - 계층형 구조는 말 그대로 우리가 URI를 참조할 때 ( / ) 표현으로 리소스의 계층을 타고 갈 수 있으며 마지막에는 슬래쉬( / )를 포함하지 않아야 합니다. 또 이 API사이에 보안, 로드밸런싱, 암호화 등의 계층을 추가해 보안성을 강화하거나 Proxy, Gateway 등을 추가해 네트워크의 중간 매체를 사용할 수 있습니다.

 

위 6가지 규칙 중 가장 중요한 것만 기억하자면

URI는 고유명사로 데이터를 명확하게 의미할 수 있어야 하며, 해당 데이터를 활용한 행동은 꼭 HTTP method를 이용해야 한다는 걸 기억하면 좋겠습니다.

 

 

그 밖에도 주의할 점으로는

 

 

( _ ) 표시보다는 ( - ) 하이픈을 사용해야 하고, 파일의 확장자(. jpg )등을 표시하지 않아야 하며, 소문자만을 사용해야 합니다

 

 

저도 역시나 프로젝트를 진행할 때 REST API 아키텍처를 지향하며 설계하고 구성했지만 결과적으로 로컬의 일부 리소스를 끌어다 쓰는 방식의 프로젝트를 종종 사용하곤 했습니다. (동영상, 이미지와 같이 데이터베이스에 담기 껄끄러운 데이터들..) 이럴 때마다 REST API의 설계 규칙에 위배되었다는 것을 오늘 개념을 정리해보며 다시 한번 느끼는 시간이 되었다고 생각합니다.

 

 

Reference


'지식 창고' 카테고리의 다른 글

MSA란 무엇일까?  (0) 2023.01.10
HLS protocol 이란 무엇일까?  (2) 2022.09.11
프레임워크랑 라이브러리는 뭐가 다를까??  (0) 2022.09.03

+ Recent posts