Doctrine for Dummies

40

Transcript of Doctrine for Dummies

Page 1: Doctrine for Dummies
Page 2: Doctrine for Dummies

Bacharel em Informática com ênfase em Análise de Sistemas pela Unisinos, cursou mestrado em Engenharia Informática e de Computadores pelo Instituto Superior Técnico da Universidade Técnica de Lisboa (Portugal), perito judicial ad hoc especializado em TI (mantenedor do site PERITO.inf.br), Zend Certified Engineer (PHP 5.3), Zend Certified PHP Engineer (PHP 5.5) e Zend Framework 2 Certified Architect (ZFCA) #ZEND004019, Certified ScrumMaster pela Scrum Alliance #203613, Microsoft Certified Professional (MCP), idealizador do projeto Certificamp, consultor web e PHP evangelist.

Ari Stopassola Junior

Page 3: Doctrine for Dummies

Dummy≠

Dumb

Page 4: Doctrine for Dummies

Mapeamento Objeto Relacional (ORM)

• Persistir o objeto numa estrutura de dados relacional• Tradução para tabelas, campos, linhas e relacionamentos• Conversões de tipo•ORM mascara detalhes obscuros•Overhead• Requer aprendizagem de outras tencnologias. Ex.: DQL (Doctrine), Propel, Eloquent etc. htt

p://

ww

w.e

dzyn

da.c

om/u

se-la

rave

ls-el

oque

nt-o

rm-o

utsid

e-of

-lara

vel/

Page 5: Doctrine for Dummies
Page 7: Doctrine for Dummies

Ferramentas de Object-relational mapping

Page 8: Doctrine for Dummies

https://github.com/guilhermeblanco

Page 9: Doctrine for Dummies

DoctrineVantagens

•Estabilidade•Comunidade• Integração com os principais frameworks

Desvantagens•Curva de aprendizado•Performance

Page 10: Doctrine for Dummies

Roadmap• Modelo de domínio• Database Abstraction Layer (DBAL)• Object Relational Mapping (ORM)• Entities• Entity manager• Mapping• Repositories• Life cicle events • Query Builder• Caching• Proxies• Event subsystem

Page 11: Doctrine for Dummies

Passeios

NomeDescriçãoPreçoDistância

...

Objetos Base relacional

Nome Descrição Preço Distância

Classe Passeios Tabela Passeios

ORM

Page 12: Doctrine for Dummies

composer require doctrine/orm

Page 14: Doctrine for Dummies

PDO x DBALData-access Layer

• Permite a troca de banco de dados utlizando as mesmas chamadas de métodos• Não reescreve SQL• Tão pouco emula

funcionalidades inexistentes

Database Abstraction Layer

• Agnóstico• Manipulação por meio de

uma API Orientada à Objetos• Traz maior consistência na

manipulação do BD• Doctrine usa DBAL, mas você

pode usar DBAL sem Doctrine• DBAL utiliza PDO

internamente

Page 15: Doctrine for Dummies

Exemplo de D

BAL<?phpinclude __DIR__ . '/doctrine_autoloader.php';

use Doctrine\DBAL\Configuration;use Doctrine\DBAL\DriverManager;

//Obtém a conexão$dbParams = include __DIR__ . '/database.params.php';$conn = DriverManager::getConnection($dbParams, new Configuration());

$sql = "SELECT * FROM orcamentos WHERE sobrenome = ?";$stmt = $conn->prepare($sql);$stmt->execute(array('STOPASSOLA'));//OU utilizando QueryBuilder$qb = $conn->createQueryBuilder();$qb->select('*')->from('orcamentos')->where('sobrenome = :name');$data = array(':name' => 'STOPASSOLA');

while ($tupla = $stmt->fetch()) { var_dump($tupla);}

Page 16: Doctrine for Dummies

Mapeandos os tipos de dadosTipos do Doctrine Tipos SQL Tipos PHP

string VARCHAR stringinteger INT integersmallint SMALLINT integerbigint BIGINT string

boolean BOOLEAN booleandecimal DECIMAL double

date DATETIME DateTimetime TIME DateTime

datetime DATETIME/TIMESTAMP DateTimetext CLOB string

Page 17: Doctrine for Dummies

Eloquent implementa Active Record

class Passeios extends Eloquent {

}

$passeio = Passeios::find(32);$passeio->name = "Tour Uva e Vinho";$passeio->save();

Fonte: http://www.martinfowler.com/eaaCatalog/activeRecord.html

Page 18: Doctrine for Dummies

Doctrine 2 implementa Data Mapper

Fonte: http://martinfowler.com/eaaCatalog/dataMapper.html

Page 19: Doctrine for Dummies

<?php/** * @Entity * @Table(name="passeios") */class Passeio{ /** * @Id * @GeneratedValue(strategy="AUTO") * @Column(type="integer") */ private $id; /** * @Column(type="string", length=255, nullable=true) */ private $nome;}

Page 20: Doctrine for Dummies
Page 21: Doctrine for Dummies

Annotations• Instruções declarativas dentro de blocos de documentação• Doctrine usa anotações para definir o mapeamento objeto-relacional• Annotations são metadados que descrevem a entidade, como ela

deve ser armazenada, que tipo de colunas serão usadas etc.• Inspirado no PHPDocumentor www.phpdoc.org • Definida sempre acima do nome da classe e de cada atributo• Entre /** xxx */ e começam com o simbolo @

/** * Produto * * @Entity * @Table(name="produtos") */

Page 22: Doctrine for Dummies

Anotações obrigatórias

"Learning Doctrine" by Doug Bierer (O'Reilly)

Page 23: Doctrine for Dummies

@ORM\Column(Type="xxxx")• smallint, integer, bigint• decimal, float• string, text, guid• binary, blob, boolean• date, date time, datetimez, time• array, simple_array, json_array, object

http://doctrine-dbal.readthedocs.io/en/latest/reference/types.html

Page 24: Doctrine for Dummies

SchemaLaravel ➡ Migrations

public function up(){

Schema::create('passeios', function(Blueprint $table){

$table->increments('id');$table->string('nome');$table->text('descricao');$table->timestamps();

});}

$ php artisan migrate

$ php artisan make:migration create_passeios_table --create="passeios"

Page 25: Doctrine for Dummies

Entity Manager

$passeio = new Passeio;$passeio->setName("Tour Itaimbezinho");EntityManager::persist($passeio);EntityManager::flush();

Page 26: Doctrine for Dummies

Entity Manager

$passeio = new Passeio;$passeio->setName("Tour Itaimbezinho");EntityManager::persist($passeio);EntityManager::flush();

Page 27: Doctrine for Dummies

Foto

http

s://

ww

w.fl

ickr

.com

/pho

tos/

prag

dave

/173

6404

62

Page 28: Doctrine for Dummies

Unit of Work

Fonte: http://martinfowler.com/eaaCatalog/unitOfWork.html

• Estratégia transactional write-behind• Retarda a execução de cláusulas SQL para executá-las posteriormente de forma mais eficiente• Executa numa ordem tal de modo a liberar o mais rápido possível as tabelas em questão (write locks), ao fim da transação

Page 29: Doctrine for Dummies

Doctrine Query Language – DQL

$query = EntityManager::createQuery("select p from VendaBalcao\Entities\Passeios p where p.preco >= 90 AND p.preco <= 150");

$passeios = $query->getResult();

Page 30: Doctrine for Dummies

Lab: https://github.com/stopassola/doctrine_lab

Page 31: Doctrine for Dummies

Herança: estratégia Single Table

/** * @Entity * @InheritanceType("SINGLE_TABLE") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"person"="Usuario","employee"="Colaborador"}) */

Revi

sta

php|

arch

itect

, edi

ção

mar

ço/2

016.

Page 32: Doctrine for Dummies

Herança: estratégia Class Table

/** * @Entity * @InheritanceType("TABLE_PER_CLASS") * @DiscriminatorColumn(name="discr", type="string") * @DiscriminatorMap({"person"="Usuario","employee"="Colaborador"}) */

Revista php|architect, edição março/2016.

Page 33: Doctrine for Dummies

Hidratação

$produto = $entityManager->find('Produto', 5);

Page 34: Doctrine for Dummies

Possível workflow1) Crie as entidades com suas respectivas annotations2) Verifique incoerências das classes mediante o BD:

$ vendor/bin/doctrine orm:validate-schema

3) Realize a varredura nas annotations e crie as respectivas tabelas:$ vendor/bin/doctrine orm:schema-tool:update --force

Page 35: Doctrine for Dummies

Relação 1:1 (lê-se um-para-um)“cada colaborador trabalha para uma empresa

parceira”Colaborador

$id$parceiro

Parceiro

$id

Owning side Inverse side

/** * @OneToOne(targetEntity="Parceiro") * @JoinColumn(name="parceiro", referencedColumnName="id") */protected $parceiro;

Page 36: Doctrine for Dummies

Hóspede

$id$nome

Hóspede

$id$nome

Hotel

$id$hospedes[]

Hóspede

$id$hotel

Owning side Inverse side/** * @var \Doctrine\Common\Collections\Collection * @OneToMany(targetEntity="Hospede", mappedBy="hotel") */protected $hospedes;

Relação 1:N (um-para-ene)

“Um hotel hospeda vários hóspedes”

Page 37: Doctrine for Dummies

id nome preco duracao

1 Tour Uva e Vinho 99 12

2 Noite Gaúcha 110 4

3 Alpen Park 30 3

4 Canyon Itaimbezinho 99 10

5 Parques de Gramado 35 5pacotes_id passeios_id

1 1

1 2

2 3

2 4

3 3

4 1

4 5

Passeios

Relação N:M (ene-para-eme)“Pacotes têm passeios e o mesmo passeio compõe vários pacotes”

id nome

1 Serra Gaúcha Tradicional

2 Aventura

3 Serra com as Crianças

4 Italiana e Alemã

Paco

tes

Page 38: Doctrine for Dummies

Pacote

$id$passeios[]

Pacote

$id$passeios[]

Hóspede

$id$nome

Hóspede

$id$nome

Pacote

$id$passeios[]

Passeio

$id$pacotes[]

Owning side Inverse side/** * @ManyToMany(targetEntity="Passeio", mappedBy="pacotes") * @JoinTable(name="pacotes_has_passeios", * joinColumns={@JoinColumn(name="pacotes_id", "id")}, * inverseJoinColumns={@JoinColumn(name="passeios_id", "id")}) */protected $passeios;

Relação N:M (ene-para-eme)“Pacotes têm passeios e o mesmo passeio compõe vários pacotes”

Page 39: Doctrine for Dummies

Referências

Page 40: Doctrine for Dummies

E-mail:[email protected]

Twitter: @stopassolaSkype: stopassolaLinkedIn:

http://pt.linkedin.com/in/stopassola

Facebook:http://www.facebook.com/arijunior

Sites:http://slideshare.net/arijuniorhttp://www.perito.inf.brhttp://www.certificamp.com http://www.rumoacertificacaophp.com

Contatos