지나공 : 지식을 나누는 공간

Exposed 란? (+ JDBC, ORM) 본문

Tech

Exposed 란? (+ JDBC, ORM)

해리리_ 2024. 10. 13. 23:54

JDBC란?


Java Database Connectivity. 자바에서 DB에 접속하고 SQL 쿼리를 실행하며 결과를 처리할 수 있게 하는 표준 API로, JDBC 드라이버를 통해 특정 데이터베이스(MySQL, Postgre SQL 등)와 자바 애플리케이션 간의 통신을 가능하게 한다. 커넥션을 얻어 DB에 연결하고 명령어를 실행해서 결과를 처리한 뒤, Statement, ResultSet, Connection 객체를 닫아서 자원을 해제한다.

// 연결
Connection conn = DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/mydb",
    "username",
    "password"
);

// 명령 실행
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM Users");

// 자원 해제
rs.close();
stmt.close();
conn.close();

 

장점은,

  • 표준화된 API라 다양한 데이터베이스에 대해 호환 가능한 것
  • 쿼리를 직접 작성해서 세밀하게 제어할 수 있는 것

단점은,

  • 연결 설정이나 자원 해제 같이 반복적인 코드 작성이 필요함.
  • ORM 이 지원되지 않아 객체지향적 설계에 부합하지 않는다.

 

객체 지향적 설계에 부합하지 않는다?


위 문장을 조금 더 보충설명하자면, 객체지향프로그래밍과 관계형DB 간 불일치하는 데에서 오는 문제점이라고 보면 된다. 

  1. 데이터 표현 방식이 다름.
    1. OOP는 객체를 통해 데이터와 메소드를 정의하지만 DB는 row와 column으로 표현
  2. 연관관계 처리 방식이 다름.
    1. OOP는 객체 간 관계를 한 객체가 다른 객체를 필드로 가지는 방식으로 표현하지만,
    2. 관계형DB는 테이블 간 관계를 외래키를 통해서 표현한다.

ORM은 위와 같은 문제를 해결해준다. 예를 들어 User와 Order가 1:N 관계라고 할 때, User는 List<Order>를 필드로 가져서 참조할 수 있게 하고, 이 필드 위에 어노테이션 @OneToMany를 선언해두면 객체 간의 참조관계를 RDB에서의 테이블 관계로 자동 매핑해준다. 이 기능을 통해 데이터베이스 의존성을 감소시키면서 DB 테이블과 객체 간 매핑 작업을 자동으로 해준다.

 

ORM 이란?


ORM(Object Relational Mapping)은 객체 지향 프로그래밍 언어의 객체와 데이터베이스 테이블 간의 매핑을 의미한다. ORM 프레임워크는 DB와 상호작용할 때 SQL을 직접 작성하는 대신 객체지향적으로 데이터를 다룰 수 있게 해주는 도구다. 주요 ORM 프레임워크로는 Hibernate, JPA, Django ORM, Exposed 등이 있다.

 

Exposed란?


Kotlin 용 JDBC 드라이버 위에 구축된 경량의 SQL 라이브러리다. DB 접근을 위해 두가지 방식을 제공하는데, 하나는 도메인 특화 언어(DSL)고, 하나는 데이터 접근 객체(DAO)다.

  1. DSL (Domain Specific Language) API:
    SQL 과 유사한 형태로 쿼리를 작성할 수 있어서 익숙한 SQL 개념을 사용하면서도 kotlin 이 제공하는 타입 안정성의 이점을 얻을 수 있다.
  2. DAO (Data Access Object) API:
    전통적인 ORM 프레임워크인 Hibernate와 유사하게 객체지향적 접근 방식을 제공한다.객체 중심으로 DB 엔티티를 다루고, 테이블을 클래스로 표현하므로 DB 레코드를 직접 객체로 매핑할 수 있다. 
// DSL 방식
val users = UsersTable.select { UsersTable.age greater 20 }

// DAO 방식
val user = User.findById(1)

 

이처럼 Exposed는 프로젝트의 요구사항에 가장 적합한 방식을 선택할 수 있는 유연한 라이브러리다... 라고 docs에서 말한다. ㅎㅎ DSL API를 쓰면 SQL의 직접적 제어가 가능하고, DAO API를 사용하면 더 높은 수준의 추상화를 통해 간편하게 DB와 상호작용할 수 있다.

 

Exposed 만의 차별화된 특징을 생각해보면,

  • kotlin 타입 활용 가능하여 컴파일 시점에 타입 오류를 알 수 있다.
  • DSL, DAO 를 모두 제공해서 용도에 맞게 적합한 것을 선택할 수 있다.
  •  코루틴 호환성: 비동기 프로그래밍을 지원해서 블로킹 작업을 효율적으로 처리할 수 있다. (이건 다음 포스팅에 더 자세히..)
    • Exposed는 내부적으로 JDBC를 사용해서 DB와 통신하고, JDBC는 전통적인 blocking API 이므로 DB 작업을 수행할 때 해당 작업이 완료될 때까지 스레드가 블로킹된다. 따라서 Exposed 자체는 non-blocking API를 제공하지 않지만 코루틴과 함께 사용할 경우 코루틴의 Dispatcher를 활용해서 블로킹 작업을 적절한 스레드 풀에서 실행하도록 관리할 수 있고, 이를 통해 메인 스레드를 차단하지 않고도 DB 작업을 할 수 있다.
728x90
Comments