Posts da Tag: ORM - Blog da TreinaWeb

PHP

Primeiros passos com Doctrine ORM

O Doctrine ORM é um dos projetos mais importantes do conjunto de projetos Doctrine. Ele é um ORM implementado usando o padrão Data Mapper e pode ser usado desde pequenos projetos até grandes aplicações. Pode ser usado em conjunto com grandes frameworks PHP como Symfony, Laravel, Zend, Slim e outros.

Quando falamos de Doctrine a maioria das pessoas já pensa no ORM, porém o Doctrine é um conjunto de projetos para PHP. Temos um post falando sobre os principais projetos do Doctrine, aconselho a leitura antes de prosseguir com este.

Doctrine ORM - Fundamentos
Curso de Doctrine ORM - Fundamentos
CONHEÇA O CURSO

Funcionamento e Bancos suportados

O Doctrine ORM funciona sobre outro projeto, o Doctrine DBAL. O DBAL é uma camada de abstração escrita sobre o PDO, ela adiciona uma série de recursos e permite a escrita de código interoperável entre diferentes sistemas gerenciadores de banco de dados.

O Doctrine ORM tira proveito da interoperabilidade do DBAL e da parte de baixo nível do PDO. Essa estrutura permite ao Doctrine ORM suportar os principais gerenciadores de banco de dados:

  • MySQL
  • PostgreSQL
  • SQL Server
  • Oracle
  • SQLite

Mapeamento do banco de dados

Quando vamos usar um ORM a primeira coisa que precisamos fazer é realizar o mapeamento entre as tabelas do modelo relacional para o modelo orientado a objetos. No Doctrine ORM temos 4 opções de notações para descrever as características do banco de dados.

Em aplicações legadas provavelmente encontrará a maioria dos mapeamentos usando XML. Em aplicações mais novas o mapeamento mais utilizado é o através de annotations (comentários que são lidos pelo doctrine).

Entidade

As entidades são usadas para realizar o mapeamento entre o modelo orientado a objetos e o modelo relacional. Por meio delas conseguimos representar exatamente a estrutura do nosso banco de dados. É possível definir nome de tabelas, colunas, chave primária e relacionamentos.

Na imagem abaixo, podemos ver a representação entre o modelo orientado a objetos a esquerda e o modelo relacional a direita:

Modelo de representação ORM

No projeto as entidades são representadas por classes PHP onde declaramos as propriedades de acordo com a tabela do banco de dados. A entidade produto do exemplo acima, poderia ser representada conforme abaixo:

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
 */
class Product
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $nome;

    /**
     * @ORM\Column(type="decimal")
     */
    private $preco;

    /**
     * @ORM\Column(type="text")
     */
    private $descricao;

    public function getId()
    {
        return $this->id;
    }

    public function setNome()
    {
        $this->nome = $nome;
    }

    public function getNome()
    {
        return $this->nome;
    }

    public function setPreco()
    {
        $this->preco = $preco;
    }

    public function getPreco()
    {
        return $this->preco;
    }

    public function setDescricao()
    {
        $this->descricao = $descricao;
    }

    public function getDescricao()
    {
        return $this->descricao;
    }
}

Note que os comentários na classe acima iniciam com @ORM. Esses comentário são as informações de mapeamento definidas através de annotations.

PHP - Fundamentos
Curso de PHP - Fundamentos
CONHEÇA O CURSO

Entity Manager

Se verificar novamente a entidade que mapeamos, verá que ela não estende nenhuma classe da estrutura do Doctrine, ela é apenas uma classe do PHP. Desse modo, para que possamos através dela manipular qualquer informação no banco de dados precisamos de uma classe específica do Doctrine, a Entity Manager.

A Entity Manager ou em português gerenciador de entidades, é a classe do doctrine responsável por gerenciar o estado das entidades e realizar as escritas no banco de dados. Ela implementa um padrão chamado Unit of Work ou em português unidade de trabalho, esse padrão mantém uma lista das alterações realizadas nas entidades monitoradas pelo Entity Manager em memória e organiza a parte de escrita dessas alterações no banco de dados de forma consistente, quando solicitado.

Obtendo a instância do Entity Manager

O processo de obtenção da instância da classe Entity Manager vai depender muito de onde está usando o Doctrine. Abaixo alguns links de referência para alguns frameworks:

Se estiver usando o Doctrine sem nenhum Framework terá algo parecido com isso:

require_once "vendor/autoload.php";

use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

$paths = [__DIR__."/src/Entities"];
$isDevMode = true;
$config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode, null, null, false);

//aqui configuramos a conexão com banco de dados
$params = [
    'url' => "mysql://usuario:senha@servidor/nome-banco"
];

//Obter a instância da classe Entity Manager
$entityManager = EntityManager::create($params, $config);

Lembrando que para o exemplo acima funcionar é necessário instalar o pacote do Doctrine ORM usando o composer:

composer require doctrine/orm

Persistindo dados

Usamos o Entity Manager para persistir informações no banco de dados. Vamos criar um novo registro no banco de dados através da entidade que defimos chamada produto.

Primeira coisa precisamos criar uma instância e definir os dados do produto:

$produto = new Produto;

$produto->setNome('Bicicleta');
$produto->setPreco(800);
$produto->setDescricao('Engrenagem fixa, azul, rápida')

Veja que estamos usando métodos setters. Isso porque nossas propriedades da entidade são sempre privadas, com isso precisamos usar os métodos setters e getters para conseguir manipular os valores.

Agora com a instância da entidade produto já definida, podemos indicar ao Entity Manager que ela deve ser persistida no banco de dados:

$entityManager->persist($produto);

No exemplo a instância da classe Entity Manager está dentro da variável $entityManager, mas poderia ser qualquer nome, dependendo de onde está usando. O importante é entender o que o método persist está fazendo, indicando que a instância deve ser monitorada.

Por fim, precisamos pedir para o Entity Manager realizar as alterações no banco de dados, pois até agora os dados estão apenas em memória. Para isso usamos o método flush:

$entityManager->flush();

Pronto! Se tiver a tabela corretamente criada e os parâmetros de conexão estiverem certos, verá o registro no banco de dados.

Considerações Finais

O Doctrine é um ORM extremamente poderoso com dezenas de recursos. Nos próximos posts vamos aprender os diferentes modos de consultar informações no banco de dados e também como configurar relações.

Desenvolvedor PHP
Formação: Desenvolvedor PHP
Nesta formação você aprenderá todos os conceitos da linguagem PHP, uma das mais utilizadas no mercado. Desde de conceitos de base, até características mais avançadas, como orientação a objetos, práticas de mercado, integração com banco de dados. Ao final, você terá conhecimento para desenvolver aplicações PHP usando as práticas mais modernas do mercado.
CONHEÇA A FORMAÇÃO

PHP

Conheça os principais projetos do Doctrine

Ao falar em Doctrine é normal pensarmos diretamente no ORM, porém o Doctrine é um conjunto de projetos em PHP voltados para trabalhar com banco de dados e outros recursos.

Projetos do Doctrine

O objetivo do doctrine inicialmente era construir um projeto único para garantir o acesso a dados de forma eficiente assim como em outras linguagens de programação, também no PHP. Com o tempo o projeto foi sendo melhorado e nesses processos os desenvolvedores começaram a observar que poderia separar o projeto em pequenos projetos que pudessem ser reutilizados, tanto dentro do próprio Doctrine quanto em outros projetos PHP, mesmo que a aplicação não utilize o Doctrine ORM em si.

Doctrine ORM - Fundamentos
Curso de Doctrine ORM - Fundamentos
CONHEÇA O CURSO

Baseado nessa filosofia hoje o Doctrine conta com mais de 15 projetos. Os principais são:

DBAL

É uma camada de abstração de acesso a dados construída sobre o PDO. Conta com recursos importantes que permitem executar queries parametrizadas, construir consultas através do query builder, além de ferramentas para ler e alterar a estrutura do banco de dados.

ORM

O Doctrine ORM é um Object Relational Mapper que implementa o padrão Data Mapper. Seu principal objetivo é facilitar o mapeamento entre o banco de dados relacional e o modelo orientado a objetos, diminuindo a complexidade do acesso aos dados.

Commom

Agrupa recursos em comum que são compartilhados por diferentes projetos do Doctrine. O objetivo principal dele é evitar que trechos de códigos com recursos comuns tenham de ser duplicados dentro dos diversos projetos do Doctrine.

Migrations

Permite a definição da estrutura do banco de dados através de arquivos dentro da aplicação, facilitando a criação do banco de dados em novos ambientes e também o versionamento da estrutura do banco.

Annotations

No PHP é comum usarmos um padrão chamado DocBlock para documentarmos nossas aplicações. As annotations nada mais são do que informações que definimos dentro desses blocos de comentários, mas que são lidas pela aplicação, ao invés de ignoradas como os demais comentários. O projeto annotation consistem em um parser (leitor) que consegue obter essas informações de forma simples.

PHP Avançado
Curso de PHP Avançado
CONHEÇA O CURSO

Collections

Projeto consiste em uma biblioteca que adiciona funcionalidades bastante úteis para o tratamento de conjuntos de informações. Podemos pensar de forma muito simplista nas collections como sendo funcionalidades adicionais sobre os arrays nativos do PHP.

Cache

Projeto muito utilizado na comunidade PHP para realização de cache. Por padrão possui drivers que permitem utilizá-lo com diferentes meios de armazenamento, como, redis, memcache e outros.

Event Manager

É um gerenciador de eventos usado em vários projetos do próprio Doctrine e também da comunidade em geral.

MongoDB Abstraction Layer

O projeto consiste em uma camada adicional de abstração que adiciona funcionalidades a extensão PHP Mongo disponível no PECL.

Mongo ODM

O Mongo ODM (Object Document Mapper) é um projeto da mesma categoria que o ORM, com a diferença que ele faz o mapeamento entre o modelo de documentos do banco de dados NoSQL Mongo para o modelo de orientado a objetos.

Outros projetos

O Doctrine ainda conta com outros projetos fora os especificados neste post. A lista completa pode ser acessada no site do Doctrine: https://www.doctrine-project.org/projects.html

Considerações finais

O doctrine conta com projetos de alta qualidade que podem ser usados em qualquer aplicação PHP, mesmo que não utilize os projetos principais como DBAL e ORM. Assim como conhecer os principais componentes do Symfony pode te ajudar na hora da escolha das bibliotecas, os projetos do Doctrine também são extremamente importantes para seu repertório.

Desenvolvedor Symfony Full-Stack
Formação: Desenvolvedor Symfony Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Symfony com desenvoltura. Ao final desta formação, terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso usando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

PHP

O que é ORM?

Object-Relational Mapping (ORM), em português, mapeamento objeto-relacional, é uma técnica para aproximar o paradigma de desenvolvimento de aplicações orientadas a objetos ao paradigma do banco de dados relacional. O uso da técnica de mapeamento objeto-relacional é realizado através de um mapeador objeto-relacional que geralmente é a biblioteca ou framework que ajuda no mapeamento e uso do banco de dados.

Laravel - Eloquent ORM
Curso de Laravel - Eloquent ORM
CONHEÇA O CURSO

Problema da impedância de dados

Quando estamos trabalhando com aplicações orientadas a objetos que utilizam banco de dados relacionais para armazenamento de informações, temos um problema chamado impedância objeto-relacional devido às diferenças entre os 2 paradigmas.

O banco de dados relacional trabalha com tabelas e relações entre elas para representar modelos da vida real. Dentro das tabelas temos várias colunas e a unidade que temos para representação no modelo relacional é uma linha:

Tabela ORM

O paradigma orientado a objetos possui um modo um pouco diferente de trabalhar. Nele nós temos diversos elementos como classes, propriedades, visibilidade, herança e interfaces. A unidade quando falamos de orientação a objetos é o objeto que representa algo do mundo real, seja abstrato ou concreto:

Imagem Objeto

As principais dificuldades que essas diferenças entre paradigmas causa:

  • Representação dos dados e do modelo, já que as estruturas são distintas;
  • Mapeamento entre os tipos de dados da linguagem de programação e do banco de dados;
  • Modelo de integridade relacional do banco relacional;

O ORM

Pensando nos problemas descritos acima, o ORM define uma técnica para realizar a conciliação entre os 2 modelos. Uma das partes centrais é através do mapeamento de linhas para objetos:

Imagem Mapeamento ORM

As bibliotecas ou frameworks ORM definem o modo como os dados serão mapeados entre os ambientes, como serão acessados e gravados. Isso diminui o tempo de desenvolvimento, uma vez que não é necessário desenvolver toda essa parte. Outra vantagem está na adaptação de novos membros na equipe, como muitos projetos comerciais utilizam a mesma ferramenta, é possível encontrar membros que já estão acostumados com o padrão de trabalho.

Padrões utilizados no mercado

Independente da linguagem de programação que o ORM é implementado, geralmente ele segue um padrão bem definido. No mercado existem dois padrões que são amplamente utilizados, o Data Mapper e o Active Record. Ambos os padrões foram definidos por Martin Fowler em seu livro Padrões de Arquitetura de Aplicações Corporativas.

Node.js Completo
Curso de Node.js Completo
CONHEÇA O CURSO

Data Mapper

Nesse padrão a classe que representa a tabela do banco de dados não deve conhecer os recursos necessário para realizar as transações com banco de dados: inserir, atualizar e apagar informações. Esses recursos ficam em uma classe própria do ORM, garantindo que as classes que representam a tabela tenha uma única responsabilidade:

data mapper

(Imagem do livro “Padrões de Arquitetura de Aplicações Corporativas”)

Na prática, para a maioria dos ORMs do mercado que implementam o padrão Data Mapper, independente da linguagem, vamos ter um código muito parecido com abaixo:

EntityManager entityManager = Persistence.createEntityManagerFactory("persistente-unit");

entityManager.getTransaction().begin();

Pessoa pessoa = new Pessoa();
pessoa.setId(1);
pessoa.setSobrenome("Silva");
pessoa.setPrenome("João");
pessoa.setNumeroDeDependentes(2);

entityManager.persist(pessoa);
entityManager.getTransaction().commit();

O código acima é um exemplo do Hibernate para Java.

Active Record

Nesse padrão, diferentemente do anterior, a classe que representa a tabela conhece os recursos necessários para realizar as transações no banco de dados, geralmente ela herda uma classe com todos esses comportamentos. Veja abaixo um diagrama retirado do livro “Padrões de Arquitetura de Aplicações Corporativa”:

active record

Na maioria dos ORM que implementam o padrão Active Record teremos um código muito parecido com esse:

pessoa = pessoa.new
pessoa.sobrenome = "Silva"
pessoa.prenome = "João"
pessoa.numeroDeDependentes = 2

pessoa.save()

O código é válido para o ORM do Ruby On Rails.

Principais ORMs do mercado

Java

  • Hibernate
  • EclipseLink
  • ActiveJPA

Kotlin

  • Exposed

C#

Node

  • Sequelize

PHP

Ruby

  • Ruby On Rails ActiveRecord
  • Datamapper

Python

  • DjangoORM
  • SqlAlchemy

Considerações finais

Existem muitas discussões entre usar um ORM que implementa Data Mapper ou Active Record. Muitos desenvolvedores defendem um ou outro com unhas e dentes, porém, na realidade, como quase tudo na nossa área, não existe bala de prata. Se tiver a oportunidade aconselho estudar ORMs da sua linguagem que trabalha em ambos os padrões, assim você terá um conhecimento maior para escolher entre um ou outro dependendo dos requisitos do seu projeto.

Desenvolvedor Laravel Full-Stack
Formação: Desenvolvedor Laravel Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Laravel com maestria. Ao final desta formação, você terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso utilizando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

Python

O que é o SQLAlchemy?

Desenvolvido para a linguagem de programação Python, o SQLAlchemy é um framework de mapeamento objeto-relacional SQL (ORM) de código aberto sobre a licença MIT.

Mas afinal, o que é o ORM?

Mapeamento objeto-relacional ou simplesmente ORM é uma técnica de programação que auxilia na conversão de dados entre banco de dados relacionais e linguagens de programação que são orientadas à objetos.

A utilização deste Framework faz com que o programador reduza a programação de acesso ao banco de dados, desta forma, obtendo uma produtividade significativa no desenvolvimento de suas aplicações.

Ou seja, ORM trata-se de um Framework que visa auxiliar na redução da impedância, realizando todas as conversões necessárias entre o modelo relacional e o modelo orientado a objetos de maneira automática, geralmente da seguinte forma:

  • Cada classe é interpretada com uma tabela;
  • Cada linha de uma determinada tabela, junto com seu relacionamento é tratada como instância do objeto relacionado à tabela em questão.

Sua utilização também visa retirar a necessidade do desenvolvedor de software em se preocupar com a linguagem SQL (geração dos comandos SQL) e com as conversões necessárias entre os diferentes tipos de dados, já que tudo isto fica a cargo do Framework ORM.

Conseguimos utilizar banco de dados relacionais por meio de objetos escritos em Python, não se preocupando em como este BD está funcionando (relações, campos, etc), apenas mapeando sua estrutura.

Python - SQLAlchemy ORM
Curso de Python - SQLAlchemy ORM
CONHEÇA O CURSO

Voltando ao SQLAlchemy…

Lançado em fevereiro de 2006 tendo como autor Michael Bayer, o SQLAlchemy encontra-se na versão 1.3.6 liberada em 21 de julho de 2019. É um Framework multiplataforma que rapidamente se tornou umas das ferramentas de mapeamento objeto-relacional mais utilizada na comunidade Python, linguagem para qual foi desenvolvida.

O SQLAlchemy é um ORM completo, criado com Python para desenvolvedores de aplicativos, que fornece flexibilidade total do SQL, obtendo um conjunto completo de padrões de persistência de nível corporativo bem conhecidos, que são projetados para acesso a banco de dados eficientes e de alto desempenho.

Com ele, o desenvolvedor não necessita se preocupar com a utilização de códigos SQL no desenvolvimento de aplicações, já que todo acesso ao banco de dados é feito utilizando código Python.

Além disso, o SQLAlchemy possui todas as garantias de segurança necessárias para proteger as aplicações de ataques ao seus bancos de dados, garantindo, assim, a criação de aplicativos simples e seguros.

Aqui no blog possuímos um artigo sobre “Principais tipos de ataques a aplicações web”.

Exemplos de consultas com SQLAlchemy

Como dito anteriormente, com o SQLAlchemy não precisamos nos preocupar com a criação de códigos SQL, já que tudo é feito inteiramente utilizando Python tornando, assim, a aplicação mais simples, como podemos ver nos exemplos abaixo:

Consulta de dados:

alldata = session.query(Filme).all()

O código acima pode ser convertido na seguinte instrução SQL:

SELECT * FROM Filme

Inserção de dados:

f1 = Filme("Star Trek", 2009)
session.add(f1)

O código acima pode ser convertido na seguinte instrução SQL:

INSERT INTO Filme (nome, ano) VALUES ("Star Trek", 2009)

Com isso, podemos ver o quão simples e legível se torna nosso código, não misturando comandos SQL com código Python e mantendo a leitura muito mais eficiente.

Maiores informações sobre sua documentação, download e notícias podem ser encontradas no próprio site do SQLAlchemy.

Desenvolvedor Python
Formação: Desenvolvedor Python
Aprenda os principais conceitos do Python (uso de variáveis, estruturas condicionais e estruturas de decisão), como trabalhar com orientação à objetos (métodos, construtores, destrutores, classes, herança, polimorfismo e duck-typing), estruturas de dados (Listas, Filas, Pilhas, Árvores Binárias, Dicionários, Conjuntos, Tabelas de Espalhamento e Mapas), banco de dados relacionais (DB API e SQLAlchemy) e como criar aplicações desktop com o Kivy.
CONHEÇA A FORMAÇÃO