기본 관계
Doctrine ORM은 내부적으로 DBAL을 사용한다. 다만, 각각 독립적으로도 사용할 수 있다.
계층 구조
graph TB A[애플리케이션] --> B[Doctrine ORM] A --> C[Doctrine DBAL] B --> C C --> D[데이터베이스] style B fill:#bbf,stroke:#333,stroke-width:2px style C fill:#bfb,stroke:#333,stroke-width:2px
사용 방식 비교
1. DBAL만 사용하는 경우
// DBAL 직접 사용
$connection = DriverManager::getConnection($connectionParams);
// SQL에 가까운 형태로 작업
$queryBuilder = $connection->createQueryBuilder();
$users = $queryBuilder
->select('u.*')
->from('users', 'u')
->where('u.active = :active')
->setParameter('active', true)
->executeQuery()
->fetchAllAssociative();2. ORM을 사용하는 경우
// Entity 클래스 정의
/** @Entity */
class User
{
/** @Id @GeneratedValue @Column(type="integer") */
private $id;
/** @Column(type="string") */
private $name;
/** @Column(type="boolean") */
private $active;
}
// ORM을 통한 객체 지향적 접근
$entityManager = EntityManager::create($connectionParams, $config);
$users = $entityManager->getRepository(User::class)
->findBy(['active' => true]);각각의 사용 시나리오
DBAL 단독 사용이 좋은 경우
- 단순한 데이터베이스 작업
- 복잡한 SQL 쿼리가 필요한 경우
- 성능이 중요한 경우
- 기존 데이터베이스와의 통합이 필요한 경우
graph LR A[복잡한 SQL 필요] --> B[DBAL 사용] C[성능 중요] --> B D[기존 DB 통합] --> B
ORM 사용이 좋은 경우
- 객체 지향적인 설계가 중요한 경우
- 복잡한 도메인 로직이 있는 경우
- 데이터베이스 스키마 자동 관리가 필요한 경우
- 타입 안정성이 중요한 경우
graph LR A[객체 지향 설계] --> B[ORM 사용] C[복잡한 도메인 로직] --> B D[스키마 자동화] --> B
함께 사용하는 경우의 예시
class UserService
{
private $entityManager;
private $connection;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
// ORM에서 DBAL Connection 가져오기
$this->connection = $entityManager->getConnection();
}
// ORM 사용 - 일반적인 CRUD
public function findActiveUsers()
{
return $this->entityManager
->getRepository(User::class)
->findBy(['active' => true]);
}
// DBAL 사용 - 복잡한 통계 쿼리
public function getUserStatistics()
{
return $this->connection
->executeQuery('
SELECT
COUNT(*) as total,
SUM(CASE WHEN active = 1 THEN 1 ELSE 0 END) as active_count
FROM users
')
->fetchAssociative();
}
}선택 가이드
DBAL 선택
- 단순한 CRUD 작업이 대부분인 경우
- SQL 쿼리의 완전한 제어가 필요한 경우
- 최적의 성능이 필요한 경우
ORM 선택
- 복잡한 비즈니스 로직이 있는 경우
- 객체 지향적 설계가 중요한 경우
- 유지보수성이 중요한 경우
함께 사용
- 대부분의 작업은 ORM으로 처리
- 복잡한 쿼리나 성능이 중요한 부분만 DBAL 사용
결론
Doctrine ORM과 DBAL은 각각 독립적으로 사용할 수 있지만, 함께 사용할 때 더 큰 시너지를 낼 수 있다. ORM이 제공하는 객체 지향적 접근과 DBAL이 제공하는 유연성을 상황에 맞게 적절히 조합하여 사용하는 것이 권장된다.