O documento fornece uma introdução sobre o ORM Propel, descrevendo suas principais funcionalidades como mapeamento objeto-relacional, migrations, query builder e geração de código. Também apresenta exemplos básicos de uso do Propel para realizar operações CRUD e transações com bancos de dados.
6. ORM Object-relational mapping
(Mapeamento objeto-relacional)
É uma técnica de desenvolvimento utilizada para
reduzir a impedância da programação orientada aos
objetos utilizando bancos de dados relacionais. As
tabelas do banco de dados são representadas através de
classes e os registros de cada tabela são representados
como instâncias das classes correspondentes.
Com esta técnica, o programador não precisa se
preocupar com os comandos em linguagem SQL; ele irá
usar uma interface de programação simples que faz todo
o trabalho de persistência.
- , WikiPédia
https://pt.wikipedia.org/wiki/Mapeamento_objeto-relacional
3 . 3
7. O que é EXATAMENTE?
É um ORM de Código Aberto que permite acesso ao
banco de dados através de um set de objetos, provendo
assim uma API simplificada para armazenamento e
requisição de dados.
O que o difere de APENAS um ORM é que nativamente
provê Query-builder, Migrations, Engenharia reversa
de um banco já existente e um Gerador de model.
3 . 4
8. Um pouco de Teoria
O Propel 1 nasceu no início dos anos 2000(o primeiro
commit no Git foi em 2005)
O projeto do Propel nasceu baseado no Torque, uma
ferramenta que saiu do Apache Turbine.
Basicamente desde a versão 1 o propel implementa o
Pattern Active Record até metade da versão 2 onde
foram feito experimentos com Data Mapper.
A versão 3, criada em março de 2017, ainda em beta,
implementa tanto Active Record e Data Mapper.
3 . 5
9. Um pouco de Teoria
Um pouco controverso no ponto principal. Onde toda a
relação do banco é escrita via arquivos XML.
Todo o banco é escrito no XML, através de Ferramentas
CLI, é feito o processo de migration e Geração do Código
para as entidades.
Na versão 3, estão sendo feitos experimentos com
Annotations.
3 . 6
10. Do que é composto
XML
Para o esquema
do banco de
dados.
PHP 5.5+
Base de TUDO.
Symfony(Components)
Console
Yaml
Finder
Validator
Filesystem
4
11. Legal!!!
Mas... Por que eu deveria usa Propel, se já possuo
recursos em meu framework?
5 . 1
12. O Propel dá de presente para você, o Desenvolvedor
Web, ferramentas para trabalhar com bancos de dados
da mesma maneira que você trabalha com outras
classes e objetos em PHP sem escrever SQL.
Simples!
É super rápido(mesmo)
Se você usa IDE, ela te agradercerá por isso.
Tem um console muito phodástico.
Outros motivos que podem influenciar...
É bem documentado.
De brinde, existem comportamentos(behaviors)
Não é um casamento
5 . 2
16. <?php
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/generated-conf/config.php';
$author = new DatabaseAuthor();
$author->setFirstName('Rafael');
$author->setLastName('DoGueto');
$author->save();
$q = new DatabaseAuthorQuery();
$primeiro = $q->findPK(1);
print_r($primeiro);
Como utilizar?
6 . 4
17. OK XML feito, como é o fucking código?
<?php
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/generated-conf/config.php';
$book = new Book();
$book->setTitle('Piadas Prontas');
$book->setIsbn('1234566654321');
$author = new Author();
$author->setFirstName('Rafael');
$author->setLastName('Nery');
$book->setAuthor($author);
$book->save();
print_r($book->toArray());
$q = new AuthorQuery();
$primeiro = $q->findPK(1);
print_r($primeiro);
Ainda existe Sandbox ;) - 6 . 5
18. C.R.U.D.
<?php
/* Incializar autoload, Propel, etc. */
$author = new Author();
$author->setFirstName('Rafael');
$author->setLastName('Nery');
$author->save();
Internamente será executado
INSERT INTO author (first_name, last_name) VALUES ('Rafael', 'Nery');
7 . 1
19. C.R.U.D.
<?php
/* Incializar autoload, Propel, etc. */
$q = new DatabaseAuthorQuery();
$primeiro = $q->findPK(1);
Internamente será executado
SELECT author.id, author.first_name, author.last_name
FROM `author`
WHERE author.id = 1
LIMIT 1;
7 . 2
20. C.R.U.D.
<?php
/* Incializar autoload, Propel, etc. */
use PropelRuntimePropel;
use PropelRuntimeFormatterObjectFormatter;
$con = Propel::getWriteConnection(MapBookTableMap::DATABASE_NAME);
$sql = "SELECT * FROM book WHERE id NOT IN "
."(SELECT book_review.book_id FROM book_review"
." INNER JOIN author ON (book_review.author_id=author.ID)"
." WHERE author.last_name = :name)";
$stmt = $con->prepare($sql);
$stmt->execute(array(':name' => 'Rafael'));
$formatter = new ObjectFormatter();
$formatter->setClass('Book'); //Com namespace
$books = $formatter->format($con->getDataFetcher($stmt));
Queryzinha marota na mão grande =)
7 . 3
21. C.R.U.D.
<?php
// primeira vez
$author1 = AuthorQuery::create()->findPk(1);
// SELECT query...
...
// segunda vez
$author2 = AuthorQuery::create()->findPk(1);
// Não roda a query e trás o objeto do author1
Queryzinha marota na mão grande =)
7 . 4
25. Transações
<?php
$con = Propel::getWriteConnection(
BookTableMap::DATABASE_NAME
);
for ($i=0; $i<2002; $i++)
{
$book = new Book();
$book->setTitle($i . ': A Space Odyssey');
$book->save($con);
}
BEGIN;
INSERT INTO book (`ID`,`TITLE`) VALUES (NULL,'0:
COMMIT;
BEGIN;
INSERT INTO book (`ID`,`TITLE`) VALUES (NULL,'1:
COMMIT;
BEGIN;
INSERT INTO book (`ID`,`TITLE`) VALUES (NULL,'2:
COMMIT;
...
<?php
$con = Propel::getWriteConnection(BookTableMap::DATABASE_NAME);
$con->beginTransaction();
for ($i=0; $i<2002; $i++)
{
$book = new Book();
$book->setTitle($i . ': A Space Odyssey');
$book->save($con);
}
$con->commit();
BEGIN;
INSERT INTO book (`ID`,`TITLE`) VALUES (NULL,'0:
INSERT INTO book (`ID`,`TITLE`) VALUES (NULL,'1:
INSERT INTO book (`ID`,`TITLE`) VALUES (NULL,'2:
...
COMMIT;
8 . 2
26. Callbacks
<table name="book">
...
<column name="data_criacao" type="timestamp" />
</table>
<?php
class Book extends BaseBook
{
public function preInsert(ConnectionInterface $con = null)
{
$this->setDataCriacao(time());
return true;
}
}
<?php
$b = new Book();
$b->setTitle('War And Peace');
$b->save();
echo $b->getDataCriacao(); // 1988-10-21 18:14:23
9