Doctrine for Dummies

Post on 16-Apr-2017

123 views 0 download

Transcript of 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

Dummy≠

Dumb

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/

Ferramentas de Object-relational mapping

https://github.com/guilhermeblanco

DoctrineVantagens

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

Desvantagens•Curva de aprendizado•Performance

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

Passeios

NomeDescriçãoPreçoDistância

...

Objetos Base relacional

Nome Descrição Preço Distância

Classe Passeios Tabela Passeios

ORM

composer require doctrine/orm

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

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);}

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

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

Doctrine 2 implementa Data Mapper

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

<?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;}

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") */

Anotações obrigatórias

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

@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

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"

Entity Manager

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

Entity Manager

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

Foto

http

s://

ww

w.fl

ickr

.com

/pho

tos/

prag

dave

/173

6404

62

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

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();

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

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.

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.

Hidratação

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

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

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;

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”

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

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”

Referências

E-mail:arijunior@gmail.com

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