지나공 : 지식을 나누는 공간
Exposed 란? (+ JDBC, ORM) 본문
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 간 불일치하는 데에서 오는 문제점이라고 보면 된다.
- 데이터 표현 방식이 다름.
- OOP는 객체를 통해 데이터와 메소드를 정의하지만 DB는 row와 column으로 표현
- 연관관계 처리 방식이 다름.
- OOP는 객체 간 관계를 한 객체가 다른 객체를 필드로 가지는 방식으로 표현하지만,
- 관계형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)다.
- DSL (Domain Specific Language) API:
SQL 과 유사한 형태로 쿼리를 작성할 수 있어서 익숙한 SQL 개념을 사용하면서도 kotlin 이 제공하는 타입 안정성의 이점을 얻을 수 있다. - 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 작업을 할 수 있다.
'Tech' 카테고리의 다른 글
Response already committed. broken pipe. (0) | 2024.05.26 |
---|---|
Redis 이모저모 (2) | 2023.12.10 |
Nginx와 Apache의 등장과 구조, Nginx.conf 파일 [1] (0) | 2022.07.23 |
Web Server, WAS, Nginx [0] (0) | 2022.07.10 |
나 보려고 만드는 IntelliJ 단축키 (mac) (0) | 2022.04.07 |