The symfony and Doctrine book

Chương 2 - Kết nối

You are currently browsing
the website for symfony 1

Visit the Symfony2 website


About

You are currently reading "The symfony and Doctrine book" which is licensed under the GFDL license.

Master symfony

Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).
trainings.sensiolabs.com

Books on symfony

Learn more about symfony with the official guides.
books.sensiolabs.com

L'audit Qualité par SensioLabs

200 points de contrôle de votre applicatif web.
audit.sensiolabs.com

Chapter Content

Giới thiệu

Các Driver Doctrine hỗ trợ

Data Source Name(DSN)

Doctrine Style

PDO Style

Import từ Database

Nhiều kết nối

Connection Attributes

Build Everything

symfony training
Be trained by symfony experts
May 29: Paris (Web Development with Symfony2 - Français)
May 31: Paris (Mastering Symfony2 - Français)
Jun 06: Paris (Introduction to Symfony2 - Français)
Jun 06: Paris (Introduction to Symfony2 - English)
Jun 06: Paris (Going Further with Symfony2 - English)
and more...

Search


powered by google
You are currently browsing "The symfony and Doctrine book" in for the 1.2 version - Switch to language:
This work is licensed under a GFDL license.
This version of symfony is not maintained anymore.
If some of your projects still use this version, consider upgrading as soon as possible.

Giới thiệu

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.yml nếu bạn đã disable sfPropelPlugin.

Các Driver Doctrine hỗ trợ

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.

Data Source Name(DSN)

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 Style

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

PDO Style

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:database tạo ra thông tin theo cấu trúc của PDO.

Import từ Database

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)

Nhiều kết nối

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.

Connection Attributes

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.

Build Everything

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-all hay đượ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.

Chương 3 - Cấu hình »
« Chương 1 - Mở đầu

Questions & Feedback

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.