Application 개발에 있어서 가장 대표적인 아키텍처는 Layered Architecture이다.
- 애플리케이션을 논리적으로 분리된 계층(layers)으로 나누어 설계하는 방법이다.
- 각 계층은 특정 역할과 책임을 가지며, 계층 간 상호작용은 명확히 정의된 인터페이스를 통해 이루어진다.
Layered Architecture로 개발을 하다 보면, n-tier(application을 물리적 또는 논리적 계층으로 나누기)로 구성을 하게 되는데, 흔히 3-tier 혹은 4-tier로 구성을 한다.
- 3-tier : Presentation Tier (UI Layer) - Application Tier (Business Logic Layer) - Data Tier (Database Layer)
- 4-tier : Presentation Tier (UI Layer) - Application Tier (Business Logic Layer) - Persistence Tier (Repository/DAO Layer) - Database Tier (Database Layer)
+) tier 별 간략한 설명
- Presentation Tier : 클라이언트의 요청을 받고 응답하는 계층이다.
- 클라이언트의 요청에 어떻게 응답할 지 관심 있는 계층
- 클라이언트가 어떤 데이터를 요청했는지 처리 방법에는 관여하지 않고, 요청을 Application Tier로 전달
- Application Tier : 비즈니스 로직을 담당하는 계층이다.
- 클라이언트의 요청을 실제로 처리하는 부분이다.
- 비즈니스 규칙과 워크플로 처리에 관심 있는 계층
- 클라이언트가 웹이든 앱이든, 혹은 데이터베이스의 종류와 관계없이 비즈니스 요구사항에 따라 로직을 처리
- 데이터 접근은 Persistence Tier에게 넘긴다.
- Persistence Tier : DB 접근 계층이다.
- 데이터베이스와 직접 상호작용하는 계층
- 데이터베이스 접근 캡슐화 및 쿼리 실행에 관심이 있는 계층이다.
- Business 요청에 따라 DB 저장, 조회, 삭제, 수정 등 로직을 수행
- 데이터에 영속성을 부여해주는 계층이다.
- Database Tier : DB 계층이다.
- 실제 데이터를 저장하는 물리적 또는 논리적 데이터베이스 계층
- Persistence Tier의 요청에 따라 데이터베이스에서 데이터를 저장하거나 반환한다.
- 데이터의 저장 및 관리에 관심 있는 계층
3-tier라면, Persistence Tier가 수행하는 역할은 Data Tier에서 처리하거나, 일부를 Application Tier에서 직접 호출하여 수행한다.
그리고 Persistence Tier에서 Persistence Framework를 사용한다.
- 데이터베이스와 애플리케이션 사이에서 데이터를 주고받을 때, 개발자가 직접 SQL 쿼리를 작성하거나 데이터베이스 연결을 관리하지 않도록 도와주는 도구이다.
Persistence Framework에는 2가지가 있다.
- ORM(Object Relational Mapping)
- 객체(Object)와 관계형 데이터베이스(RDBMS)을 매핑하여 데이터베이스를 객체지향적으로 사용할 수 있도록 도와주는 기술이다.
- SQL문을 직접 작성하지 않아도 되며, 대신 ORM이 제공하는 API나 메서드를 호출하여 데이터를 조작할 수 있다.
- ex. Hibernate, JPA
- SQL Mapper
- 객체와 SQL 문을 매핑하여, SQL 실행 결과를 객체화해주는 기술입니다.
- ORM과는 달리 객체와 관계형 데이터베이스 간의 매핑보다는 SQL 질의와 객체 간의 매핑에 초점이 맞춰져 있습니다.
- SQL문을 직접 작성해야 한다.
- ex. MyBatis, JdbcTemplate
이제 JDBC, MyBatis, Hibernate에 대해서 알아보자.
| JDBC
JDBC는 자바 프로그래밍 언어를 사용해 데이터베이스에 접근할 수 있도록 하는 자바 API이다.
이를 통해 우리는 데이터베이스에 접속하고, SQL을 실행하고, 이를 통해 데이터를 가져오거나 삭제하는 등 데이터를 다룰 수 있게 된다.
JDBC가 등장하게 된 이유는 데이터베이스 접근의 표준화를 위해서이다.
데이터베이스는 다양한 종류가 있으며, JDBC를 사용하지 않을 경우 각 데이터베이스의 고유한 API를 직접 사용해 상호작용해야 한다.
- 이에 따라 개발자는 기존의 데이터베이스를 다른 데이터베이스로 교체해야 하는 경우에는 코드를 수정해야 했다.
- 따라서, 표준이라는 것이 필요했으며, JDBC의 표준 인터페이스 덕분에 개발자는 데이터베이스를 쉽게 변경할 수 있게 되었고 변경에 유연하게 대처할 수 있게 되었다.
사실, JDBC는 출시된 지도 매우 오래된 기술이며 사용하는 방법도 많이 복잡하다.
따라서, JDBC를 직접 사용하기보다는 데이터베이스 접근을 더 편리하게 하고 개발 생산성을 높이기 위한 기술인 SQL Mapper나 ORM을 주로 사용한다.
- SQL Mapper나 ORM은 JDBC를 기반으로 동작한다. JDBC의 기능과 개념을 내부적으로 활용하여 데이터베이스와의 상호작용을 처리한다.
| JDBC 동작 흐름
JDBC API를 사용하기 위해서는 JDBC 드라이버를 먼저 로딩한 후 데이터베이스와 연결해야 한다.
- JDBC 드라이버는 JDBC 인터페이스를 구현한 구현체이다.
- JDBC가 제공하는 DriverManager가 드라이버들을 관리하고 Connection을 획득하는 기능을 제공한다.
- 이 획득한 Connection을 통해서 데이터베이스에 SQL을 실행하고 결과를 응답받을 수 있다.
- DriverManager를 통해서 Connection 획득
- Connection을 통해 Statement 생성
- 질의 수행 및 Statement를 통해 ResultSet 생성
- ResultSet을 통해 데이터 획득
- 리소스 정리
더 자세한 내용은 다음의 글을 참고하길 바란다. 참고
| MyBatis
MyBatis는 SQL Mapper이다.
- SQL Mapper는 직접 작성한 SQL문과 필드를 매핑하고 조회 결과의 행들을 객체화해주는 프레임워크이다.
MyBatis는 더 나아가서 프로그램 코드와 SQL의 분리에 집중한다.
- XML 파일이나 어노테이션에 SQL 정의하여 비즈니스 로직과 SQL을 분리할 수 있다.
- JdbcTemplate과 달리 동적 쿼리를 쉽게 작성할 수 있다.
하지만, SQL Mapper의 특성처럼 SQL 중심의 개발을 해야한다.
- 개발자가 비즈니스 로직보다는 SQL 작성이나 수정에 많은 시간을 사용해야 한다.
- 반복적인 CRUD SQL을 작성해야 한다.
- 객체 필드가 변경될 때마다 SQL을 수정해야 한다.
- 객체와 관계형 데이터베이스 간의 차이점 때문에 객체 필드가 변경되면 관련 SQL을 수정해야 하는 패러다임 불일치가 발생한다.
+) JdbcTemplate
JdbcTemplate도 스프링 데이터에서 제공해주는 SQL Mapper이다.
- 기존에 JDBC의 작업을 단순화하였다.
- 또한, JDBC API를 사용할 때 발생하는 코드 중복 문제와 리소스 관리를 자동으로 처리한다.
- RowMapper와 같은 함수형 인터페이스를 제공해서 재사용이 가능하다.
| Hibernate
Hibernate는 자바 언어를 위한 ORM 프레임워크이다. JPA의 구현체로 JPA 인터페이스 내부를 구현하며, 내부적으로 JDBC API를 사용한다.
Hibernate의 장점
- SQL 반복 작업 제거 : SQL을 직접 사용하지 않고, 메서드 호출만으로 쿼리가 수행된다.
- DAO와 테이블 간 매핑 유지보수 용이 : 테이블 컬럼이 변경되었을 때, 테이블과 관련된 DAO의 파라미터, 결과, SQL 등을 대신 수행해준다.
- 데이터 베이스 독립성 : JPA가 제공하는 추상화된 데이터 접근 계층 덕분에 특정 DBMS에 종속되지 않다. 설정 파일에서 데이터베이스 정보를 변경하기만 하면 쉽게 다른 DBMS로 전환할 수 있다.
- 패러다임 불일치 해결 : 상속, 연관 관계 등 객체와 관계형 데이터베이스와의 패러다임 불일치를 해결할 수 있다.
Hibernate의 단점
- 메서드 호출만으로 쿼리를 수행하는 것은 직접 SQL을 작성하는 것보다는 성능상 좋지 않다.
- 메서드 호출만으로 DB 데이터를 조작하기에는 한계가 있다. 따라서 이를 보완하기 위해 JPQL 또는 Native Query를 직접 작성해야 한다.
주로 JPA를 사용했기 때문에, JPA를 통한 개발을 하면서 JPA의 편리함도 있었지만, JPA의 단점도 있었다. (동적 쿼리 처리 불편함, N+1, ...)
뭐든 상황에 맞는 최적의 선택을 하는 것이 좋은 것 같다.
'🔍 CS > 데이터베이스' 카테고리의 다른 글
12/18 - TIL : Driving, Driven (1) | 2024.12.18 |
---|---|
11/30 - TIL : MongoDB (0) | 2024.11.30 |
11/24 - TIL : NoSQL과 Redis (0) | 2024.11.24 |
동시성 제어하기 - 07. 읽기와 쓰기의 트레이드 오프 (0) | 2023.06.07 |
동시성 제어하기 - 04. 낙관적 락 (0) | 2023.06.07 |