
PHP 프레임워크 – Symfony – 모델과 데이터베이스
안녕하세요 여러분 😊
이번 시간에는 Symfony에서 **데이터베이스와 모델(엔티티)**을 어떻게 연동하고 사용하는지 알아볼게요!
Laravel에서는 Eloquent ORM을 많이 사용하지만, Symfony는 Doctrine ORM을 주로 사용합니다.
Doctrine은 마치 데이터와 PHP 객체 사이를 자연스럽게 이어주는 통역사라고 할 수 있어요 📦🗣️
데이터를 저장하는 ‘서랍’이 데이터베이스라면,
Doctrine은 ‘그 서랍을 자동으로 열고 닫아주는 도우미’ 역할을 해요!
1. Doctrine이란?
**Doctrine ORM(Object-Relational Mapping)**은 PHP 객체와 관계형 데이터베이스(MySQL, PostgreSQL 등)를 연결해주는 라이브러리입니다.
특징
- SQL을 직접 작성하지 않고 PHP 객체로 데이터 다룸
- 마이그레이션 기능 제공
- 관계형 매핑(OneToOne, OneToMany 등)을 지원
- 데이터베이스 구조를 자동으로 생성/변경 가능
2. Doctrine 설치하기
Symfony에는 기본적으로 Doctrine이 포함되어 있지만, 없는 경우 아래 명령어로 설치해요:
composer require symfony/orm-pack
composer require --dev symfony/maker-bundle
orm-pack
: Doctrine ORM 관련 모든 구성 포함maker-bundle
: 엔티티/컨트롤러 등 자동 생성 도구
3. 데이터베이스 설정
.env
또는 .env.local
파일을 열어서 아래처럼 수정합니다:
DATABASE_URL="mysql://db_user:db_pass@127.0.0.1:3306/my_database?serverVersion=8.0"
db_user
: DB 사용자명db_pass
: 비밀번호my_database
: 데이터베이스 이름
PostgreSQL이라면
pgsql://
형식으로 바꿔주면 돼요!
4. 엔티티(Entity) 생성하기
php bin/console make:entity
예시: Product
엔티티 생성
Class name of the entity to create or update (e.g. Product): Product
New field name (press <return> to stop adding fields): name
Field type (enter ? to see all types) [string]: string
Field length [255]: 100
New field name: price
Field type: float
New field name: description
Field type: text
New field name: (엔터 입력 시 완료)
5. 생성된 엔티티 클래스 확인
// src/Entity/Product.php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class Product
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: "integer")]
private ?int $id = null;
#[ORM\Column(type: "string", length: 100)]
private string $name;
#[ORM\Column(type: "float")]
private float $price;
#[ORM\Column(type: "text")]
private string $description;
// getter, setter 생략
}
6. 데이터베이스 테이블 생성
php bin/console doctrine:database:create
설정한 이름의 데이터베이스가 생성돼요.
이후 테이블을 반영하려면 마이그레이션을 생성하고 실행합니다.
php bin/console make:migration
php bin/console doctrine:migrations:migrate
7. 데이터 저장 예제
컨트롤러에서 데이터를 저장하는 예:
use App\Entity\Product;
use Doctrine\ORM\EntityManagerInterface;
#[Route('/product/create', name: 'product_create')]
public function create(EntityManagerInterface $em): Response
{
$product = new Product();
$product->setName('Symfony 책');
$product->setPrice(19900);
$product->setDescription('Symfony 배우기 좋은 책이에요');
$em->persist($product);
$em->flush();
return new Response("상품이 저장되었습니다! ID: " . $product->getId());
}
8. 데이터 조회
use App\Repository\ProductRepository;
#[Route('/product/{id}', name: 'product_show')]
public function show(ProductRepository $repo, int $id): Response
{
$product = $repo->find($id);
if (!$product) {
throw $this->createNotFoundException('상품을 찾을 수 없습니다.');
}
return new Response("상품명: " . $product->getName());
}
기타 조회 메서드
find($id)
findOneBy(['name' => 'A'])
findAll()
findBy(['price' => 19900], ['name' => 'ASC'])
9. 데이터 수정
$product = $repo->find($id);
$product->setPrice(25000);
$em->flush();
10. 데이터 삭제
$product = $repo->find($id);
$em->remove($product);
$em->flush();
11. 관계 설정 (OneToMany 예시)
// Category.php
#[ORM\Entity]
class Category
{
#[ORM\OneToMany(mappedBy: 'category', targetEntity: Product::class)]
private Collection $products;
}
// Product.php
#[ORM\ManyToOne(inversedBy: 'products')]
private Category $category;
- 카테고리 하나에 여러 상품을 연결할 수 있어요.
- 관계를 통해 다양한 DB 구조를 표현할 수 있습니다.
주의할 점 ✅
항목 | 주의사항 |
---|---|
마이그레이션 관리 | DB 스키마가 바뀔 때마다 make:migration 필수 |
flush 주의 | flush() 는 DB에 실제 반영하므로 조심해서 사용 |
타입 일치 | 엔티티 속성과 DB 필드 타입이 반드시 일치해야 함 |
순환 참조 | 양방향 관계 설정 시 순환 참조에 주의해야 함 |
트랜잭션 | 복잡한 처리에는 beginTransaction() 등 활용 |
요약 정리 🎯
작업 | 명령어 |
---|---|
엔티티 생성 | php bin/console make:entity |
DB 생성 | php bin/console doctrine:database:create |
마이그레이션 생성 | php bin/console make:migration |
마이그레이션 실행 | php bin/console doctrine:migrations:migrate |
데이터 저장 | $em->persist(); $em->flush(); |
데이터 조회 | $repo->find($id); |
마무리하며 😊
Symfony에서 Doctrine을 사용하면
객체 지향적인 방식으로 데이터베이스를 손쉽게 관리할 수 있어요.
SQL을 일일이 작성하지 않아도 되고,
ORM을 통해 더 안전하고 깔끔하게 데이터와 소통할 수 있다는 점이 가장 큰 매력이죠!
다음 시간에는 Symfony에서의 폼 처리와 검증에 대해 배워볼게요.
그럼 오늘도 즐거운 Symfony 개발 되세요~ 📚🐘💾