2014年9月4日 星期四

PHP Doctrine 2.4 reverse engineering mysql database, use xml driver, don't use annotation driver

PHP Doctrine 2.4 reverse engineering mysql database, use xml driver, don't use annotation driver
- generate entities from database


assume your bootstrap.php is located in your application folder
-app/
    -bootstrap.php
    -src/                        - store the xml mapping files (database to entities mapping)
    -entities/                 - store the entities generated by doctrine
    -vender/
         -doctrine-cli.php

0. bootstrap.php

<?php
require_once 'vendor/autoload.php';

use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

$paths = array(__DIR__ . "/entities");
$isDevMode = true;

// the connection configuration
$dbParams = array(
    'driver'   => 'pdo_mysql',
    'user'     => 'root',
    'password' => 'testpwd',
    'dbname'   => 'databasename',
    'host'     => 'localhost',
    'port'     => '3306',
);

//$config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode);  won;t work!
$config = Setup::createXMLMetadataConfiguration($paths, $isDevMode);
$entityManager = EntityManager::create($dbParams, $config);


Please use XMLMetadataConfiguration instead of AnnotationMetadata for reverse engineering! THIS IS VERY IMPORTANT! Especially when you see the

Search Results

This No Metadata Class to process means that the annotation cannot be recognized in the entity class or there are no entity class.



  1. 1. create config file in vendor/doctrine-cli.php 

<?php
// vendor/doctrine-cli.php
use Symfony\Component\Console\Helper\HelperSet,
    Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper,
    Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper,
    Doctrine\ORM\Tools\Console\ConsoleRunner;
require_once __DIR__ . '/../bootstrap.php';

$helperSet = new HelperSet(array(
    'em' => new EntityManagerHelper($entityManager),
    'conn' => new ConnectionHelper($entityManager->getConnection())
));
ConsoleRunner::run($helperSet);


2. reverse engineering - generate xml from database
in the shell or command prompt:
> cd vendor

> php doctrine-cli.php orm:convert-mapping --from-database xml ../src
Now you can see *.dcm.xml are generated in your app/src/ folder

> php doctrine-cli.php orm:generate:entities ../entities --generate-annotations=true
this will generate the entities to the app/entities files

Done!

Doctrine will cache your those. It is important to clear them especially when you relocated your folders of entities or src folder. this is VERT IMPORTANT!
> php doctrine-cli.php orm:clear-cache:metadata


After the reverse engineering, you you may need to change the database schema. It is not advised to change in the database directly! If you change in the database directly, you will end up changing the schema AND reverse engineering AGAIN which will OVERWRITE your entities files!

My approach is to change the xml mapping file, then use doctrine to change the database schema. In this way, everything are synchronized and save your life.
1. change the schema xml file in src/. e.g add <field name = 'newfield' ...... />
go to vendor folder
> cd vendor
> php doctrine-cli.php orm:schema-tool:update --dump-sql
This allows you to see the sql statement of the "alter table ......". If you find those sql dump are correct,
> php doctrine-cli.php orm:schema-tool:update --dump-sql --force
this will send the sql to database.
That's it!

Should you experience any problem, try to clear cache first:
> php doctrine-cli.php orm:clear-cache:metadata

reference:
http://marco-pivetta.com/doctrine2-orm-tutorial
http://doctrine-orm.readthedocs.org/en/latest/tutorials/getting-started.html
http://christoph-burmeister.eu/?p=2268
http://stackoverflow.com/questions/8795338/create-tables-and-entities-with-doctrine2-based-on-schema-declaration