[DDC-246] Added section showing DQL examples when dealing with SINGLE_TABLE and JOINED inheritance since it affects the generated SQL of a DQL query.
This commit is contained in:
parent
cc2d84c992
commit
c7a5a695d3
@ -452,6 +452,123 @@ We will register the function by calling and can then use it:
|
||||
\Doctrine\ORM\Query\Parser::registerNumericFunction('FLOOR', 'MyProject\Query\MysqlFloor');
|
||||
$dql = "SELECT FLOOR(person.salary * 1.75) FROM CompanyPerson person";
|
||||
|
||||
++ Querying Inherited Classes
|
||||
|
||||
This section demonstrates how you can query inherited classes and what type of results
|
||||
to expect.
|
||||
|
||||
+++ Single Table
|
||||
|
||||
[Single Table Inheritance](http://martinfowler.com/eaaCatalog/singleTableInheritance.html) is an inheritance mapping strategy where all classes of a hierarchy are mapped to a single database table. In order to distinguish which row represents which type in the hierarchy a so-called discriminator column is used.
|
||||
|
||||
First we need to setup an example set of entities to use. In this scenario it is a generic
|
||||
Person and Employee example:
|
||||
|
||||
[php]
|
||||
namespace Entities;
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("SINGLE_TABLE")
|
||||
* @DiscriminatorColumn(name="discr", type="string")
|
||||
* @DiscriminatorMap({"person" = "Person", "employee" = "Employee"})
|
||||
*/
|
||||
class Person
|
||||
{
|
||||
/**
|
||||
* @Id @Column(type="integer")
|
||||
* @GeneratedValue
|
||||
*/
|
||||
protected $id;
|
||||
|
||||
/**
|
||||
* @Column(type="string", length=50)
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
*/
|
||||
class Employee extends Person
|
||||
{
|
||||
/**
|
||||
* @Column(type="string", length=50)
|
||||
*/
|
||||
private $department;
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
First notice that the generated SQL to create the tables for these entities looks like
|
||||
the following:
|
||||
|
||||
[sql]
|
||||
CREATE TABLE Person (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(50) NOT NULL, discr VARCHAR(255) NOT NULL, department VARCHAR(50) NOT NULL)
|
||||
|
||||
Now when persist a new `Employee` instance it will set the discriminator value for us
|
||||
automatically:
|
||||
|
||||
[php]
|
||||
$employee = new \Entities\Employee();
|
||||
$employee->setName('test');
|
||||
$employee->setDepartment('testing');
|
||||
$em->persist($employee);
|
||||
$em->flush();
|
||||
|
||||
Now lets run a simple query to retrieve the `Employee` we just created:
|
||||
|
||||
[php]
|
||||
$query = $em->createQuery('select e from Entities\Employee e where e.name = ?1');
|
||||
$query->setParameter('1', 'test');
|
||||
|
||||
If we check the generated SQL you will notice it has some special conditions added to
|
||||
ensure that we will only get back `Employee` entities:
|
||||
|
||||
[php]
|
||||
echo $query->getSql();
|
||||
|
||||
// SELECT p0_.id AS id0, p0_.name AS name1, p0_.department AS department2, p0_.discr AS discr3 FROM Person p0_ WHERE (p0_.name = ?) AND p0_.discr IN ('employee')
|
||||
|
||||
+++ Class Table Inheritance
|
||||
|
||||
[Class Table Inheritance](http://martinfowler.com/eaaCatalog/classTableInheritance.html) is an inheritance mapping strategy where each class in a hierarchy is mapped to several tables: its own table and the tables of all parent classes. The table of a child class is linked to the table of a parent class through a foreign key constraint.
|
||||
Doctrine 2 implements this strategy through the use of a discriminator column in the topmost table of the hierarchy because this is the easiest way to achieve polymorphic queries with Class Table Inheritance.
|
||||
|
||||
The example for class table inheritance is the same as single table, you just need to
|
||||
change the inheritance type from `SINGLE_TABLE` to `JOINED`:
|
||||
|
||||
/**
|
||||
* @Entity
|
||||
* @InheritanceType("JOINED")
|
||||
* @DiscriminatorColumn(name="discr", type="string")
|
||||
* @DiscriminatorMap({"person" = "Person", "employee" = "Employee"})
|
||||
*/
|
||||
class Person
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
Now take a look at the SQL which is generated to create the table, you'll notice some
|
||||
differences:
|
||||
|
||||
[sql]
|
||||
CREATE TABLE Person (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, discr VARCHAR(255) NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB;
|
||||
CREATE TABLE Employee (id INT NOT NULL, department VARCHAR(50) NOT NULL, PRIMARY KEY(id)) ENGINE = InnoDB;
|
||||
ALTER TABLE Employee ADD FOREIGN KEY (id) REFERENCES Person(id) ON DELETE CASCADE
|
||||
|
||||
* The data is split between two tables
|
||||
* A foreign key exists between the two tables
|
||||
|
||||
Now if were to insert the same `Employee` as we did in the `SINGLE_TABLE` example and run
|
||||
the same example query it will generate different SQL joining the `Person` information
|
||||
automatically for you:
|
||||
|
||||
[sql]
|
||||
SELECT p0_.id AS id0, p0_.name AS name1, e1_.department AS department2, p0_.discr AS discr3 FROM Employee e1_ INNER JOIN Person p0_ ON e1_.id = p0_.id WHERE p0_.name = ?
|
||||
|
||||
++ The Query class
|
||||
|
||||
An instance of the `Doctrine\ORM\Query` class represents a DQL query. You create a Query instance be calling `EntityManager#createQuery($dql)`, passing the DQL query string. Alternatively you can create an empty `Query` instance and invoke `Query#setDql($dql)` afterwards. Here are some examples:
|
||||
|
@ -97,7 +97,7 @@ This strategy is very efficient for querying across all types in the hierarchy o
|
||||
++ Class Table Inheritance
|
||||
|
||||
[Class Table Inheritance](http://martinfowler.com/eaaCatalog/classTableInheritance.html) is an inheritance mapping strategy where each class in a hierarchy is mapped to several tables: its own table and the tables of all parent classes. The table of a child class is linked to the table of a parent class through a foreign key constraint.
|
||||
Doctrine 2 implements this strategy through the use of a discriminator column in the topmost table of the hieararchy because this is the easiest way to achieve polymorphic queries with Class Table Inheritance.
|
||||
Doctrine 2 implements this strategy through the use of a discriminator column in the topmost table of the hierarchy because this is the easiest way to achieve polymorphic queries with Class Table Inheritance.
|
||||
|
||||
Example:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user