![]() |
|
The symfony and Doctrine bookChương 2 - Kết nối |
|
You are currently reading "The symfony and Doctrine book" which is licensed under the GFDL license.

Trong chương này chúng ta sẽ đề cập về kết nối trong Doctrine, cách cấu hình nhiều kết nối, liên kết với model, cách tạo và xóa database.
File cấu hình mặc định config/databases.yml thường như sau:
all:
propel:
class: sfPropelDatabase
param:
dsn: mysql:host=localhost;dbname=dbname
username: user
Chỉ có một sự khác nhau giữa cấu hình Propel và Doctrine là ta dùng class sfDoctrineDatabase thay cho sfPropelDatabase và tên connection là doctrine thay vì propel. Cả Doctrine và Propel đều dùng PHP Data Objects (PDO) cho tầng database abstraction.
Trong khi Propel yêu cầu ít nhất phải có một connection có tên
propel, với Doctrine điều này không bắt buộc và bạn có thể đặt tùy thích.
Bạn có thể cấu hình connection trong config/databases.yml thông qua lệnh configure:database
$ ./symfony configure:database --name=doctrine --class=sfDoctrineDatabase "mysql:host=localhost;dbname=dbname" user secret
Một connection mới được tạo:
doctrine:
class: sfDoctrineDatabase
param:
dsn: 'mysql:host=localhost;dbname=dbname'
username: user
password: secret
Bạn cần xóa bỏ tất cả những thứ liên quan đến propel trong
config/databases.ymlnếu bạn đã disable sfPropelPlugin.
Doctrine hỗ trợ tất cả các driver có hỗ trợ PDO. PHP phải bật extention PDO và PDO_* ứng với driver bạn muốn dùng. Dưới đây là danh sách các database PDO .
| Tên | Mô tả |
|---|---|
| MS SQL Server | Microsoft SQL Server & Sybase Functions (PDO_DBLIB) |
| Firebird/Interbase | Firebird/Interbase Functions (PDO_FIREBIRD) |
| IBM | IBM Functions (PDO_IBM) |
| Informix | Informix Functions (PDO_INFORMIX) |
| MySQL | MySQL Functions (PDO_MYSQL) |
| Oracle | Oracle Functions (PDO_OCI) |
| ODBC and DB2 | ODBC & DB2 Functions (PDO_ODBC) |
| PostgreSQL | PostgreSQL Functions (PDO_PGSQL) |
| SQLite | SQLite Functions (PDO_SQLITE) |
Bạn có thể tìm hiểu thêm về PDO tại http://www.php.net/pdo.
Doctrine cung cấp 2 cách để khai báo thông tin về DSN. Bạn có thể viết theo cách của Doctrine hoặc dùng theo cách viết của PDO.
Doctrine có cấu trúc DSN dựa trên PEAR MDB2.
all:
doctrine:
class: sfDoctrineDatabase
param:
dsn: driver://username:password@host/database_name
Bạn có thể khai báo thông tin về DSN theo cấu trúc của PDO.
all:
doctrine:
class: sfDoctrineDatabase
param:
dsn: driver:dbname=database_name;host=localhost
username: username
password: password
Cấu trúc của PDO thường mềm dẻo hơn và có thể cung cấp các thông tin non-standard về connection của bạn với PDO. Ví dụ, khi cần cung cấp thông tin về đường dẫn unix_socket hoặc cổng (port) dùng để kết nối, cấu trúc theo kiểu PDO dễ viết hơn. Lệnh
configure:databasetạo ra thông tin theo cấu trúc của PDO.
Doctrine có thể tạo ra file schema config/doctrine/schema.yml từ database có sẵn. Hãy cấu hình Doctrine connection tới database bạn muốn import và chạy lệnh sau.
$ ./symfony doctrine:build-schema
>> doctrine generating yaml schema from database
Doctrine cũng hỗ trợ khả năng chuyển file schema của Propel sang Doctrine.
Bây giờ file config/doctrine/schema.yml đã chứa thông tin về database theo cấu trúc yaml. Trong ví dụ này chúng ta có một bảng user.
CREATE TABLE user (id BIGINT AUTO_INCREMENT, username VARCHAR(255), password VARCHAR(255), PRIMARY KEY(id)) ENGINE = INNODB;
Bảng trên sẽ tạo ra file yaml schema tương ứng trong config/doctrine/schema.yml
User:
tableName: user
columns:
id:
type: integer(8)
primary: true
autoincrement: true
username: string(255)
password: string(255)
Doctrine hỗ trợ multiple connection. Đầu tiên, chúng ta cần thêm multiple connection với lệnh configure:database:
$ ./symfony configure:database --name=master --class=sfDoctrineDatabase "mysql:host=localhost;dbname=master" user secret
$ ./symfony configure:database --name=client --class=sfDoctrineDatabase "mysql:host=localhost;dbname=client" user secret
File config/databases.yml trở thành:
all:
master:
class: sfDoctrineDatabase
param:
dsn: 'mysql:host=localhost;dbname=master'
username: user
password: secret
client:
class: sfDoctrineDatabase
param:
dsn: 'mysql:host=localhost;dbname=client'
username: user
password: secret
Bây giờ chúng ta có một Client model và chúng ta muốn sử dụng master database. Bạn có thể thực hiện điều này đơn giản bằng cách xác định model như bên dưới. YAML code trong file config/doctrine/schema.yml
Client:
connection: master
columns:
name: string(255)
username: string(255)
password: string(255)
Bây giờ mỗi Client có thể có Stores được lưu trong các cơ sở dữ liệu riêng biệt ở Clients.
Store:
connection: client
attributes:
export: tables
columns:
name: string(255)
description: string(500)
client_id: integer
relations:
Client:
foreignAlias: Stores
Bởi vì các bảng nằm trong các cơ sở dữ liệu khác nhau nên dữ liệu chỉ có thể load lazy. Doctrine hiện tại không hỗ trợ câu sql để joining các bảng ở các cơ sở dữ liệu khác nhau. Also, notice the export attribute being set to tables. This tells Doctrine to only export the create table statement and not any foreign key constraints.
sfDoctrinePlugin cho phép bạn xác định connection attributes trực tiếp trong file config/databases.yml:
doctrine:
class: sfDoctrineDatabase
param:
dsn: 'mysql:host=localhost;dbname=dbname'
username: user
password: secret
attributes:
use_dql_callbacks: true
Attributes được xác định ở trên sẽ được thiết lập trên Doctrine_Connection instances khi kết nối được tạo.
Attributes trong Doctrine dùng cho tính năng cấu hình và điều khiển. Bạn có thể tìm hiểu thêm về attributes trong Doctrine documentation.
Bây giờ, chúng ta đã có kết nối và file schema, chúng ta có thể build mọi thứ với lệnh sau:
$ ./symfony doctrine:build-all-reload
This command will remove all data in your database.
Are you sure you want to proceed? (y/N)
y
>> doctrine dropping databases
>> doctrine creating databases
>> doctrine generating model classes
>> doctrine generating sql for models
>> doctrine generating form classes
>> doctrine generating filter form classes
>> doctrine created tables successfully
>> doctrine loading data fixtures from "/Us...ymfony12doctrine/data/fixtures"
Chạy lệnh trên tương đương với chạy tuần tự các lệnh sau:
$ ./symfony doctrine:drop-db
This command will remove all data in your database.
Are you sure you want to proceed? (y/N)
y
>> doctrine dropping databases
$ ./symfony doctrine:build-db
>> doctrine creating databases
$ ./symfony doctrine:build-model
>> doctrine generating model classes
$ ./symfony doctrine:build-sql
>> doctrine generating sql for models
$ ./symfony doctrine:build-form
>> doctrine generating form classes
$ ./symfony doctrine:build-filters
>> doctrine generating filter form classes
$ ./symfony doctrine:insert-sql
>> doctrine created tables successfully
$ ./symfony doctrine:data-load
>> doctrine loading data fixtures from "/Us...ymfony12doctrine/data/fixtures"
Bạn có thể xem các file model được tạo ra từ file YAML schema trong thư mục lib/model/doctrine và lib/model/doctrine/base. Những file nằm trong thư mục base bị thay thế mỗi khi bạn build lại model. Bạn có thể chỉnh sửa các file trong thư mục lib/model/doctrine.
Đây là nội dung của file lib/model/doctrine/base/BaseClient.class.php.
<?php // Connection Component Binding Doctrine_Manager::getInstance()->bindComponent('Client', 'master'); /** * This class has been auto-generated by the Doctrine ORM Framework */ abstract class BaseClient extends sfDoctrineRecord { public function setTableDefinition() { $this->setTableName('client'); $this->hasColumn('name', 'string', 255, array('type' => 'string', 'length' => '255')); $this->hasColumn('username', 'string', 255, array('type' => 'string', 'length' => '255')); $this->hasColumn('password', 'string', 255, array('type' => 'string', 'length' => '255')); } public function setUp() { $this->hasMany('Store as Stores', array('local' => 'id', 'foreign' => 'client_id')); } }
Trong thực tế lệnh
./symfony doctrine:build-all-reload-test-allhay được sử dụng trong quá trình phát triển. Nó sẽ tạo lại toàn bộ cho môi trường của bạn và chạy đầy đủ bộ test. Đây là lệnh nên chạy trước khi commit mã nguồn mới để đảm bảo không có regression mới nào xảy ra.
Bạn có thể tìm hiểu thêm về connections trong Doctrine Manual ở đây.
If you find a typo or an error, please register and open a ticket.
If you need support or have a technical question, please post to the official user mailing-list.