Updating the Getting Started guide's documentation
This commit is contained in:
parent
9cfdf1ef81
commit
b446afd937
@ -14,7 +14,7 @@ Guide Assumptions
|
||||
-----------------
|
||||
|
||||
This guide is designed for beginners that haven't worked with Doctrine ORM
|
||||
before. There are some prerequesites for the tutorial that have to be
|
||||
before. There are some prerequisites for the tutorial that have to be
|
||||
installed:
|
||||
|
||||
- PHP (latest stable version)
|
||||
@ -118,8 +118,8 @@ Add the following directories:
|
||||
Obtaining the EntityManager
|
||||
---------------------------
|
||||
|
||||
Doctrine's public interface is the EntityManager, it provides the
|
||||
access point to the complete lifecycle management of your entities
|
||||
Doctrine's public interface is through the ``EntityManager``. This class
|
||||
provides access points to the complete lifecycle management for your entities,
|
||||
and transforms entities from and back to persistence. You have to
|
||||
configure and create it to use your entities with Doctrine 2. I
|
||||
will show the configuration steps and then discuss them step by
|
||||
@ -150,8 +150,8 @@ step:
|
||||
// obtaining the entity manager
|
||||
$entityManager = EntityManager::create($conn, $config);
|
||||
|
||||
The first require statement sets up the autoloading capabilities of Doctrine
|
||||
using the Composer autoload.
|
||||
The require_once statement sets up the class autoloading for Doctrine and
|
||||
its dependencies using Composer's autoloader.
|
||||
|
||||
The second block consists of the instantiation of the ORM
|
||||
``Configuration`` object using the Setup helper. It assumes a bunch
|
||||
@ -159,8 +159,8 @@ of defaults that you don't have to bother about for now. You can
|
||||
read up on the configuration details in the
|
||||
:doc:`reference chapter on configuration <../reference/configuration>`.
|
||||
|
||||
The third block shows the configuration options required to connect
|
||||
to a database, in my case a file-based sqlite database. All the
|
||||
The third block shows the configuration options required to connect to
|
||||
a database. In this case, we'll use a file-based SQLite database. All the
|
||||
configuration options for all the shipped drivers are given in the
|
||||
`DBAL Configuration section of the manual <http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/>`_.
|
||||
|
||||
@ -170,15 +170,10 @@ factory method.
|
||||
Generating the Database Schema
|
||||
------------------------------
|
||||
|
||||
Now that we have defined the Metadata mappings and bootstrapped the
|
||||
EntityManager we want to generate the relational database schema
|
||||
from it. Doctrine has a Command-Line Interface that allows you to
|
||||
access the SchemaTool, a component that generates the required
|
||||
tables to work with the metadata.
|
||||
|
||||
For the command-line tool to work a cli-config.php file has to be
|
||||
present in the project root directory, where you will execute the
|
||||
doctrine command. Its a fairly simple file:
|
||||
Doctrine has a command-line interface that allows you to access the SchemaTool,
|
||||
a component that can generate a relational database schema based entirely on the
|
||||
defined entity classes and their metadata. For this tool to work, a
|
||||
cli-config.php file must exist in the project root directory:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
@ -188,40 +183,38 @@ doctrine command. Its a fairly simple file:
|
||||
|
||||
return \Doctrine\ORM\Tools\Console\ConsoleRunner::createHelperSet($entityManager);
|
||||
|
||||
You can then change into your project directory and call the
|
||||
Doctrine command-line tool:
|
||||
Change into your project directory and call the Doctrine command-line tool:
|
||||
|
||||
::
|
||||
|
||||
$ cd project/
|
||||
$ vendor/bin/doctrine orm:schema-tool:create
|
||||
|
||||
At this point no entity metadata exists in `src` so you will see a message like
|
||||
"No Metadata Classes to process." Don't worry, we'll create a Product entity and
|
||||
corresponding metadata in the next section.
|
||||
Since we haven't added any entity metadata in `src` yet, you'll see a message
|
||||
stating "No Metadata Classes to process." In the next section, we'll create a
|
||||
Product entity along with the corresponding metadata, and run this command again.
|
||||
|
||||
You should be aware that during the development process you'll periodically need
|
||||
to update your database schema to be in sync with your Entities metadata.
|
||||
|
||||
You can easily recreate the database:
|
||||
Note that as you modify your entities' metadata during the development process,
|
||||
you'll need to update your database schema to stay in sync with the metadata.
|
||||
You can rasily recreate the database using the following commands:
|
||||
|
||||
::
|
||||
|
||||
$ vendor/bin/doctrine orm:schema-tool:drop --force
|
||||
$ vendor/bin/doctrine orm:schema-tool:create
|
||||
|
||||
Or use the update functionality:
|
||||
Or you can use the update functionality:
|
||||
|
||||
::
|
||||
|
||||
$ vendor/bin/doctrine orm:schema-tool:update --force
|
||||
|
||||
The updating of databases uses a Diff Algorithm for a given
|
||||
Database Schema, a cornerstone of the ``Doctrine\DBAL`` package,
|
||||
Database Schema. This is a cornerstone of the ``Doctrine\DBAL`` package,
|
||||
which can even be used without the Doctrine ORM package.
|
||||
|
||||
Starting with the Product
|
||||
-------------------------
|
||||
Starting with the Product Entity
|
||||
--------------------------------
|
||||
|
||||
We start with the simplest entity, the Product. Create a ``src/Product.php`` file to contain the ``Product``
|
||||
entity definition:
|
||||
@ -257,9 +250,9 @@ entity definition:
|
||||
}
|
||||
}
|
||||
|
||||
Note that all fields are set to protected (not public) with a
|
||||
mutator (getter and setter) defined for every field except $id.
|
||||
The use of mutators allows Doctrine to hook into calls which
|
||||
When creating entity classes, all of the fields should be protected or private
|
||||
(not public), with getter and setter methods for each one (except $id).
|
||||
The use of mutators allows Doctrine to hook into calls which
|
||||
manipulate the entities in ways that it could not if you just
|
||||
directly set the values with ``entity#field = foo;``
|
||||
|
||||
@ -274,9 +267,10 @@ language. The metadata language describes how entities, their
|
||||
properties and references should be persisted and what constraints
|
||||
should be applied to them.
|
||||
|
||||
Metadata for entities are configured using a XML, YAML or Docblock Annotations.
|
||||
This Getting Started Guide will show the mappings for all Mapping Drivers.
|
||||
References in the text will be made to the XML mapping.
|
||||
Metadata for an Entity can be configured using DocBlock annotations directly
|
||||
in the Entity class itself, or in an external XML or YAML file. This Getting
|
||||
Started guide will demonstrate metadata mappings using all three methods,
|
||||
but you only need to choose one.
|
||||
|
||||
.. configuration-block::
|
||||
|
||||
@ -332,27 +326,28 @@ References in the text will be made to the XML mapping.
|
||||
The top-level ``entity`` definition tag specifies information about
|
||||
the class and table-name. The primitive type ``Product#name`` is
|
||||
defined as a ``field`` attribute. The ``id`` property is defined with
|
||||
the ``id`` tag, this has a ``generator`` tag nested inside which
|
||||
defines that the primary key generation mechanism automatically
|
||||
uses the database platforms native id generation strategy (for
|
||||
example AUTO INCREMENT in the case of MySql or Sequences in the
|
||||
the ``id`` tag. It has a ``generator`` tag nested inside, which
|
||||
specifies that the primary key generation mechanism should automatically
|
||||
use the database platform's native id generation strategy (for
|
||||
example, AUTO INCREMENT in the case of MySql, or Sequences in the
|
||||
case of PostgreSql and Oracle).
|
||||
|
||||
Now that we have defined our first entity, let's update the database:
|
||||
Now that we have defined our first entity and its metadata,
|
||||
let's update the database schema:
|
||||
|
||||
::
|
||||
|
||||
$ vendor/bin/doctrine orm:schema-tool:update --force --dump-sql
|
||||
|
||||
Specifying both flags ``--force`` and ``--dump-sql`` prints and executes the DDL
|
||||
statements.
|
||||
Specifying both flags ``--force`` and ``--dump-sql`` will cause the DDL
|
||||
statements to be executed and then printed to the screen.
|
||||
|
||||
Now create a new script that will insert products into the database:
|
||||
Now, we'll create a new script to insert products into the database:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// create_product.php
|
||||
// create_product.php <name>
|
||||
require_once "bootstrap.php";
|
||||
|
||||
$newProductName = $argv[1];
|
||||
@ -372,22 +367,19 @@ Call this script from the command-line to see how new products are created:
|
||||
$ php create_product.php ORM
|
||||
$ php create_product.php DBAL
|
||||
|
||||
What is happening here? Using the ``Product`` is pretty standard OOP.
|
||||
What is happening here? Using the ``Product`` class is pretty standard OOP.
|
||||
The interesting bits are the use of the ``EntityManager`` service. To
|
||||
notify the EntityManager that a new entity should be inserted into the database
|
||||
you have to call ``persist()``. To initiate a transaction to actually perform
|
||||
the insertion, You have to explicitly call ``flush()`` on the ``EntityManager``.
|
||||
notify the EntityManager that a new entity should be inserted into the database,
|
||||
you have to call ``persist()``. To initiate a transaction to actually *perform*
|
||||
the insertion, you have to explicitly call ``flush()`` on the ``EntityManager``.
|
||||
|
||||
This distinction between persist and flush is allows to aggregate all writes
|
||||
(INSERT, UPDATE, DELETE) into one single transaction, which is executed when
|
||||
flush is called. Using this approach the write-performance is significantly
|
||||
better than in a scenario where updates are done for each entity in isolation.
|
||||
This distinction between persist and flush is what allows the aggregation of
|
||||
all database writes (INSERT, UPDATE, DELETE) into one single transaction, which
|
||||
is executed when ``flush()`` is called. Using this approach, the write-performance
|
||||
is significantly better than in a scenario in which writes are performed on
|
||||
each entity in isolation.
|
||||
|
||||
Doctrine follows the UnitOfWork pattern which additionally detects all entities
|
||||
that were fetched and have changed during the request. You don't have to keep track of
|
||||
entities yourself, when Doctrine already knows about them.
|
||||
|
||||
As a next step we want to fetch a list of all the Products. Let's create a
|
||||
Next, we'll fetch a list of all the Products in the database. Let's create a
|
||||
new script for this:
|
||||
|
||||
.. code-block:: php
|
||||
@ -404,10 +396,10 @@ new script for this:
|
||||
}
|
||||
|
||||
The ``EntityManager#getRepository()`` method can create a finder object (called
|
||||
a repository) for every entity. It is provided by Doctrine and contains some
|
||||
finder methods such as ``findAll()``.
|
||||
a repository) for every type of entity. It is provided by Doctrine and contains
|
||||
some finder methods like ``findAll()``.
|
||||
|
||||
Let's continue with displaying the name of a product based on its ID:
|
||||
Let's continue by creating a script to display the name of a product based on its ID:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
@ -425,9 +417,13 @@ Let's continue with displaying the name of a product based on its ID:
|
||||
|
||||
echo sprintf("-%s\n", $product->getName());
|
||||
|
||||
Updating a product name demonstrates the functionality UnitOfWork of pattern
|
||||
discussed before. We only need to find a product entity and all changes to its
|
||||
properties are written to the database:
|
||||
Next we'll update a product's name, given its id. This simple example will
|
||||
help demonstrate Doctrine's implementation of the UnitOfWork pattern. Doctrine
|
||||
keeps track of all the entities that were retrieved from the Entity Manager,
|
||||
and can detect when any of those entities' properties have been modified.
|
||||
As a result, rather than needing to call ``persist($entity)`` for each individual
|
||||
entity whose properties were changed, a single call to ``flush()`` at the end of a
|
||||
request is sufficient to update the database for all of the modified entities.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
@ -455,9 +451,8 @@ product name changed by calling the ``show_product.php`` script.
|
||||
Adding Bug and User Entities
|
||||
----------------------------
|
||||
|
||||
We continue with the bug tracker domain, by creating the missing classes
|
||||
``Bug`` and ``User`` and putting them into ``src/Bug.php`` and
|
||||
``src/User.php`` respectively.
|
||||
We continue with the bug tracker example by creating the ``Bug`` and ``User``
|
||||
classes. We'll store them in ``src/Bug.php`` and ``src/User.php``, respectively.
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
@ -561,14 +556,15 @@ We continue with the bug tracker domain, by creating the missing classes
|
||||
}
|
||||
}
|
||||
|
||||
All of the properties discussed so far are simple string and integer values,
|
||||
for example the id fields of the entities, their names, description, status and
|
||||
change dates. Next we will model the dynamic relationships between the entities
|
||||
by defining the references between entities.
|
||||
All of the properties we've seen so far are of simple types (integer, string,
|
||||
and datetime). But now, we'll add properties that will store objects of
|
||||
specific *entity types* in order to model the relationships between different
|
||||
entities.
|
||||
|
||||
References between objects are foreign keys in the database. You never have to
|
||||
(and never should) work with the foreign keys directly, only with the objects
|
||||
that represent the foreign key through their own identity.
|
||||
At the database level, relationships between entities are represented by foreign
|
||||
keys. But with Doctrine, you'll never have to (and never should) work with
|
||||
the foreign keys directly. You should only work with objects that represent
|
||||
foreign keys through their own identities.
|
||||
|
||||
For every foreign key you either have a Doctrine ManyToOne or OneToOne
|
||||
association. On the inverse sides of these foreign keys you can have
|
||||
@ -602,6 +598,7 @@ domain model to match the requirements:
|
||||
<?php
|
||||
// src/User.php
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
|
||||
class User
|
||||
{
|
||||
// ... (previous code)
|
||||
@ -616,12 +613,13 @@ domain model to match the requirements:
|
||||
}
|
||||
}
|
||||
|
||||
You use Doctrine's ArrayCollections in your Doctrine models, rather
|
||||
than plain PHP arrays, so that Doctrine can watch what happens with
|
||||
them and act appropriately. Note that if you dump your entities,
|
||||
you'll see a "PersistentCollection" in place of your ArrayCollection,
|
||||
which is just an
|
||||
internal Doctrine class with the same interface.
|
||||
.. note::
|
||||
|
||||
Whenever an entity is created from the database, a ``Collection``
|
||||
implementation of the type ``PersistentCollection`` will be injected into
|
||||
your entity instead of an ``ArrayCollection``. This helps Doctrine ORM
|
||||
understand the changes that have happened to the collection that are
|
||||
noteworthy for persistence.
|
||||
|
||||
.. warning::
|
||||
|
||||
@ -644,24 +642,22 @@ able to work with Doctrine 2. These assumptions are not unique to
|
||||
Doctrine 2 but are best practices in handling database relations
|
||||
and Object-Relational Mapping.
|
||||
|
||||
|
||||
- In a one-to-one relation, the entity holding the foreign key of
|
||||
the related entity on its own database table is *always* the owning
|
||||
side of the relation.
|
||||
- In a many-to-one relation, the Many-side is the owning side by
|
||||
default because it holds the foreign key. Accordingly, the One-side
|
||||
is the inverse side by default.
|
||||
- In a many-to-one relation, the One-side can only be the owning side if
|
||||
the relation is implemented as a ManyToMany with a join table, and the
|
||||
One-side is restricted to allow only UNIQUE values per database constraint.
|
||||
- In a many-to-many relation, both sides can be the owning side of
|
||||
the relation. However, in a bi-directional many-to-many relation,
|
||||
only one side is allowed to be the owning side.
|
||||
- Changes to Collections are saved or updated, when the entity on
|
||||
the *owning* side of the collection is saved or updated.
|
||||
- Saving an Entity at the inverse side of a relation never
|
||||
triggers a persist operation to changes to the collection.
|
||||
- In a one-to-one relation the entity holding the foreign key of
|
||||
the related entity on its own database table is *always* the owning
|
||||
side of the relation.
|
||||
- In a many-to-many relation, both sides can be the owning side of
|
||||
the relation. However in a bi-directional many-to-many relation
|
||||
only one is allowed to be.
|
||||
- In a many-to-one relation the Many-side is the owning side by
|
||||
default, because it holds the foreign key.
|
||||
- The OneToMany side of a relation is inverse by default, since
|
||||
the foreign key is saved on the Many side. A OneToMany relation can
|
||||
only be the owning side, if its implemented using a ManyToMany
|
||||
relation with join table and restricting the one side to allow only
|
||||
UNIQUE values per database constraint.
|
||||
|
||||
.. note::
|
||||
|
||||
@ -686,13 +682,13 @@ the bi-directional reference:
|
||||
protected $engineer;
|
||||
protected $reporter;
|
||||
|
||||
public function setEngineer($engineer)
|
||||
public function setEngineer(User $engineer)
|
||||
{
|
||||
$engineer->assignedToBug($this);
|
||||
$this->engineer = $engineer;
|
||||
}
|
||||
|
||||
public function setReporter($reporter)
|
||||
public function setReporter(User $reporter)
|
||||
{
|
||||
$reporter->addReportedBug($this);
|
||||
$this->reporter = $reporter;
|
||||
@ -717,15 +713,15 @@ the bi-directional reference:
|
||||
{
|
||||
// ... (previous code)
|
||||
|
||||
protected $reportedBugs = null;
|
||||
protected $assignedBugs = null;
|
||||
protected $reportedBugs;
|
||||
protected $assignedBugs;
|
||||
|
||||
public function addReportedBug($bug)
|
||||
public function addReportedBug(Bug $bug)
|
||||
{
|
||||
$this->reportedBugs[] = $bug;
|
||||
}
|
||||
|
||||
public function assignedToBug($bug)
|
||||
public function assignedToBug(Bug $bug)
|
||||
{
|
||||
$this->assignedBugs[] = $bug;
|
||||
}
|
||||
@ -741,7 +737,7 @@ You can see from ``User#addReportedBug()`` and
|
||||
``User#assignedToBug()`` that using this method in userland alone
|
||||
would not add the Bug to the collection of the owning side in
|
||||
``Bug#reporter`` or ``Bug#engineer``. Using these methods and
|
||||
calling Doctrine for persistence would not update the collections
|
||||
calling Doctrine for persistence would not update the Collections'
|
||||
representation in the database.
|
||||
|
||||
Only using ``Bug#setEngineer()`` or ``Bug#setReporter()``
|
||||
@ -749,7 +745,7 @@ correctly saves the relation information.
|
||||
|
||||
The ``Bug#reporter`` and ``Bug#engineer`` properties are
|
||||
Many-To-One relations, which point to a User. In a normalized
|
||||
relational model the foreign key is saved on the Bug's table, hence
|
||||
relational model, the foreign key is saved on the Bug's table, hence
|
||||
in our object-relation model the Bug is at the owning side of the
|
||||
relation. You should always make sure that the use-cases of your
|
||||
domain model should drive which side is an inverse or owning one in
|
||||
@ -758,7 +754,7 @@ or an engineer is assigned to the bug, we don't want to update the
|
||||
User to persist the reference, but the Bug. This is the case with
|
||||
the Bug being at the owning side of the relation.
|
||||
|
||||
Bugs reference Products by an uni-directional ManyToMany relation in
|
||||
Bugs reference Products by a uni-directional ManyToMany relation in
|
||||
the database that points from Bugs to Products.
|
||||
|
||||
.. code-block:: php
|
||||
@ -771,7 +767,7 @@ the database that points from Bugs to Products.
|
||||
|
||||
protected $products = null;
|
||||
|
||||
public function assignToProduct($product)
|
||||
public function assignToProduct(Product $product)
|
||||
{
|
||||
$this->products[] = $product;
|
||||
}
|
||||
@ -783,7 +779,7 @@ the database that points from Bugs to Products.
|
||||
}
|
||||
|
||||
We are now finished with the domain model given the requirements.
|
||||
Lets add metadata mappings for the ``User`` and ``Bug`` as we did for
|
||||
Lets add metadata mappings for the ``Bug`` entity, as we did for
|
||||
the ``Product`` before:
|
||||
|
||||
.. configuration-block::
|
||||
@ -890,13 +886,13 @@ For the "created" field we have used the ``datetime`` type,
|
||||
which translates the YYYY-mm-dd HH:mm:ss database format
|
||||
into a PHP DateTime instance and back.
|
||||
|
||||
After the field definitions the two qualified references to the
|
||||
After the field definitions, the two qualified references to the
|
||||
user entity are defined. They are created by the ``many-to-one``
|
||||
tag. The class name of the related entity has to be specified with
|
||||
the ``target-entity`` attribute, which is enough information for
|
||||
the database mapper to access the foreign-table. Since
|
||||
``reporter`` and ``engineer`` are on the owning side of a
|
||||
bi-directional relation we also have to specify the ``inversed-by``
|
||||
bi-directional relation, we also have to specify the ``inversed-by``
|
||||
attribute. They have to point to the field names on the inverse
|
||||
side of the relationship. We will see in the next example that the ``inversed-by``
|
||||
attribute has a counterpart ``mapped-by`` which makes that
|
||||
@ -907,7 +903,7 @@ holds all products where the specific bug occurs. Again
|
||||
you have to define the ``target-entity`` and ``field`` attributes
|
||||
on the ``many-to-many`` tag.
|
||||
|
||||
The last missing definition is that of the User entity:
|
||||
Finally, we'll add metadata mappings for the ``User`` entity.
|
||||
|
||||
.. configuration-block::
|
||||
|
||||
@ -934,13 +930,13 @@ The last missing definition is that of the User entity:
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="Bug", mappedBy="reporter")
|
||||
* @var Bug[]
|
||||
* @var Bug[] An ArrayCollection of Bug objects.
|
||||
**/
|
||||
protected $reportedBugs = null;
|
||||
|
||||
/**
|
||||
* @OneToMany(targetEntity="Bug", mappedBy="engineer")
|
||||
* @var Bug[]
|
||||
* @var Bug[] An ArrayCollection of Bug objects.
|
||||
**/
|
||||
protected $assignedBugs = null;
|
||||
|
||||
@ -996,10 +992,7 @@ means the join details have already been defined on the owning
|
||||
side. Therefore we only have to specify the property on the Bug
|
||||
class that holds the owning sides.
|
||||
|
||||
This example has a fair overview of the most basic features of the
|
||||
metadata definition language.
|
||||
|
||||
Update your database running:
|
||||
Update your database schema by running:
|
||||
::
|
||||
|
||||
$ vendor/bin/doctrine orm:schema-tool:update --force
|
||||
@ -1008,7 +1001,8 @@ Update your database running:
|
||||
Implementing more Requirements
|
||||
------------------------------
|
||||
|
||||
For starters we need to create user entities:
|
||||
So far, we've seen the most basic features of the metadata definition language.
|
||||
To explore additional functionality, let's first create new ``User`` entities:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
@ -1032,23 +1026,22 @@ Now call:
|
||||
|
||||
$ php create_user.php beberlei
|
||||
|
||||
We now have the data to create a bug and the code for this scenario may look
|
||||
like this:
|
||||
We now have the necessary data to create a new Bug entity:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// create_bug.php
|
||||
// create_bug.php <reporter-id> <engineer-id> <product-ids>
|
||||
require_once "bootstrap.php";
|
||||
|
||||
$theReporterId = $argv[1];
|
||||
$theDefaultEngineerId = $argv[2];
|
||||
$reporterId = $argv[1];
|
||||
$engineerId = $argv[2];
|
||||
$productIds = explode(",", $argv[3]);
|
||||
|
||||
$reporter = $entityManager->find("User", $theReporterId);
|
||||
$engineer = $entityManager->find("User", $theDefaultEngineerId);
|
||||
$reporter = $entityManager->find("User", $reporterId);
|
||||
$engineer = $entityManager->find("User", $engineerId);
|
||||
if (!$reporter || !$engineer) {
|
||||
echo "No reporter and/or engineer found for the input.\n";
|
||||
echo "No reporter and/or engineer found for the given id(s).\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -1070,22 +1063,17 @@ like this:
|
||||
|
||||
echo "Your new Bug Id: ".$bug->getId()."\n";
|
||||
|
||||
Since we only have one user and product, probably with the ID of 1, we can call this script with:
|
||||
Since we only have one user and product, probably with the ID of 1, we can
|
||||
call this script as follows:
|
||||
|
||||
::
|
||||
|
||||
php create_bug.php 1 1 1
|
||||
|
||||
This is the first contact with the read API of the EntityManager,
|
||||
showing that a call to ``EntityManager#find($name, $id)`` returns a
|
||||
single instance of an entity queried by primary key. Besides this
|
||||
we see the persist + flush pattern again to save the Bug into the
|
||||
database.
|
||||
|
||||
See how simple relating Bug, Reporter, Engineer and Products is
|
||||
done by using the discussed methods in the "A first prototype"
|
||||
section. The UnitOfWork will detect this relationship when flush is
|
||||
called and relate them in the database appropriately.
|
||||
See how simple it is to relate a Bug, Reporter, Engineer and Products?
|
||||
Also recall that thanks to the UnitOfWork pattern, Doctrine will detect
|
||||
these relations and update all of the modified entities in the database
|
||||
automatically when ``flush()`` is called.
|
||||
|
||||
Queries for Application Use-Cases
|
||||
---------------------------------
|
||||
@ -1094,7 +1082,7 @@ List of Bugs
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Using the previous examples we can fill up the database quite a
|
||||
bit, however we now need to discuss how to query the underlying
|
||||
bit. However, we now need to discuss how to query the underlying
|
||||
mapper for the required view representations. When opening the
|
||||
application, bugs can be paginated through a list-view, which is
|
||||
the first read-only use-case:
|
||||
@ -1225,7 +1213,7 @@ write scenarios:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// show_bug.php
|
||||
// show_bug.php <id>
|
||||
require_once "bootstrap.php";
|
||||
|
||||
$theBugId = $argv[1];
|
||||
@ -1300,7 +1288,7 @@ and usage of bound parameters:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// dashboard.php
|
||||
// dashboard.php <user-id>
|
||||
require_once "bootstrap.php";
|
||||
|
||||
$theUserId = $argv[1];
|
||||
@ -1366,7 +1354,7 @@ should be able to close a bug. This looks like:
|
||||
.. code-block:: php
|
||||
|
||||
<?php
|
||||
// close_bug.php
|
||||
// close_bug.php <bug-id>
|
||||
require_once "bootstrap.php";
|
||||
|
||||
$theBugId = $argv[1];
|
||||
|
Loading…
x
Reference in New Issue
Block a user