Nesse artigo vamos falar um pouco sobre a implementação de Herança no Doctrine. Como exemplo didático de herança, temos a épica relação entre DarthVader, Luke Skywalker e Leia Organa no filme Star Wars (Figura 1). Em vista disto, vamos utilizar esta relação entre os personagens para ilustrar a implementação da herança no Doctrine.
Figura: "I am your father".
A herança no Doctrine é especificada através dos atributos:
- @DiscriminatorColumn: utilizado para indicar qual o elemento da hierarquia (classe) a linha da tabela representa.
- @DiscriminatorMap: utilizado para identificar quais os valores que existirão na coluna do discriminador e qual classe da hierarquia está mapeado para cada valor.
- @InheritanceType: representa a estrutura no Banco de Dados que irá armazenar a herança. SINGLE_TABLE indicada que tanto o objeto pai quanto os objetos filhos estarão representados na mesma tabela. JOINED indica que cada classe da hierarquia terá uma tabela própria.
Por exemplo, tendo o mapa:
@DiscriminatorMap({"father" = "DarthVader", "son" = "Luke", "daughter" = "Leia"})
temos que father representa um objeto da classe DarthVader, já son representa um elemento da classe Luke.
A seguir um exemplo de implementação da herança. São especificadas três classes: DarthVader (classe pai), Luke (classe filho) e Leia (classe filho).
Classe DarthVader (pai)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| <?php
/**
* @Entity
* @InheritanceType("SINGLE_TABLE")
* @Table(name="father")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"father" = "DarthVader", "son" = "Luke", "daughter" = "Leia"})
*/
class DarthVader{
/**
* @var integer $id
* @Column(type="integer")
* @Id
* @GeneratedValue(strategy="IDENTITY")
*/
private $id;
public function setId($id){$this->id = $id;}
public function getId(){return $this->id;}
/**
*
* @Column(type="integer")
*
*/
private $atributo_anakin;
public function setAtributoAnakin($atributo){$this->atributo_anakin=$atributo;}
public function getAtributoAnakin(){return $this->atributo_anakin;}
}
|
Classe Luke (filho)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| <?php
/**
*
* @Entity
* @Table(name="son")
*/
class Luke extends DarthVader {
/**
*
* @Column(type="integer")
*
*/
private $atributo_luke;
public function setAtributoLuke($atributo){$this->atributo_luke=$atributo;}
public function getAtributoLuke(){return $this->atributo_luke;}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| <?php
/**
*
* @Entity
* @Table(name="daughter")
*/
class Leia extends DarthVader {
/**
*
* @Column(type="integer")
*
*/
private $atributo_leia;
public function setAtributoLeia($atributo){$this->atributo_leia=$atributo;}
public function getAtributoLeia(){return $this->atributo_leia;}
}
|
A seguir a estrutura gerada no Banco de Dados para cada tipo de herança (InheritanceType).
JOINED
Figura: Tipo de Herança JOINED
SINGLE_TABLE
Figura: Tipo de Herança SINGLE_TABLE
Num próximo artigo vamos falar como ocorre o processo de persistência dos objetos Doctrine no Banco de Dados.