A free and open-source book on ZF3 for beginners

Translation into this language is not yet finished. You can help this project by translating the chapters and contributing your changes.

12.7. Sobre el Administrador de Entidades

El Administrador de entidades es el punto de acceso primario a la característica de ORM que provee Doctrine.

El EntityManager es una clase de Doctrine que se encuentra en el namespace Doctrine\ORM y se usa para recuperar entidades de nuestros repositorios usando un criterio de búsqueda y, además, guarda entidades en la base de datos.

El EntityManager se registra como un servicio en el administrador de servicios de Zend Framework 3. Desde nuestra clase factory recuperamos el EntityManager del administrador de servicios de la siguiente manera (si necesitamos una conexión diferente a la orm_default, solamente reemplazamos orm_default con el nombre de la conexión a la base de datos adecuada):

// Get Doctrine entity manager
$entityManager = $container->get('doctrine.entitymanager.orm_default');

Los métodos más usados provistos por la clase EntityManager se listan en la tabla 12.4 que se muestra abajo:

Table 12.4. Métodos del EntityManager
Método Descripción
persist($entity) Coloca una nueva entidad dentro del administrador de entidades (se hace manejable).
remove($entity) Remueve una entidad de la base de datos.
flush() Purga todos los cambios del objeto que están en cola hasta ahora hacia la base de datos.
createQuery($dql) Crea un nuevo objeto Query.
getRepository($entityName) Traer un repositorio para una clase de tipo entidad.

Vamos a revisar los métodos de la tabla 12.4.

Para agregar una entidad creada recientemente al administrador de entidades (haciendo a la entidad "administrada") usamos el método persist(). Para remover una entidad de la base de datos usamos el método remove() del administrador de eventos.

Cuando llamamos a persist() o remove() el EntityManager recuerda nuestros cambios en memoria pero no aplica los cambios en la base de datos automáticamente (por razones de rendimiento). Para aplicar los cambios en la base de datos, en una única transacción, usamos el método flush().

Por ejemplo, el código de ejemplo de abajo muestra como crear una instancia de la entidad Post y como guardarla en la base de datos:

// Create new Post entity.
$post = new Post();
$post->setTitle('Top 10+ Books about Zend Framework 3');
$post->setContent('Post body goes here');
$post->setStatus(Post::STATUS_PUBLISHED);
$currentDate = date('Y-m-d H:i:s');
$post->setDateCreated($currentDate);

// Add the entity to entity manager.
$entityManager->persist($post);

// Apply changes to database.
$entityManager->flush();

El método createQuery() del administrador de entidades esta diseñado para crear una consulta desde un cadena de caracteres DQL. Este regresa un objeto Query. Luego, se ejecuta la consulta y regresa los resultados (un arreglo de entidades que concuerda con las condiciones de búsqueda).

El método getRepository() del administrador de entidades esta diseñado para traer el repositorio a partir del nombre de la clase de tipo entidad. Podemos ver abajo, por ejemplo, como se trae el repositorio para la entidad Post:

$repository = $entityManager->getRepository(Post::class);

12.7.1. Repositorios de Entidades

Conceptualmente cada clase de tipo entidad tiene su propio repositorio. El repositorio provee métodos para recuperar entidades de la base de datos. El repositorio puede ser considerado como la colección de todas las entidades disponibles de determinada clase. Por ejemplo, existen repositorios para las entidades Post, Comment y Tag.

Para cargar datos desde la base de datos recuperamos una entidad de su repositorio. Cuando pedimos el repositorio para una entidad se cargan los datos desde la tabla asociada a la entidad y se asignan los campos de la entidad a los datos.

La clase Doctrine\ORM\EntityRepository implementa el repositorio por defecto. Si lo necesitamos, podemos crear nuestro propio repositorio extendiendo la clase EntityRepository. Mostraremos esto más adelante.

Los métodos más usado que provee la clase EntityRepository se listan en la tabla 12.5:

Table 12.5. Métodos del EntityRepository
Métodos Descripción
findAll() Busca todas las entidades en el repositorio.
find($id) Busca a una entidad a partir de su identificador.
findBy($criteria, $orderBy, $limit, $offset) Busca una entidad a partir de un conjunto de criterios.
findOneBy($criteria, $orderBy) Busca una sola entidad a partir de un conjunto de criterios.
createQueryBuilder($alias) Crea una nueva instancia del QueryBuilder que es prepoblada con la entidad.

El método findAll() trae todas las entidades desde el repositorio. Un ejemplo simple sobre como usarla se muestra abajo:

// Find all posts from repository
$posts = $entityManager->getRepository(Post::class)->findAll();

El método find() es el método más simple para buscar una entidad. Este recupera una entidad a partir de su ID (llave primaria).

En el ejemplo de abajo seleccionamos la publicación con ID = 1.

// Find post by primary key (ID)
$post = $entityManager->getRepository(Post::class)->find(1);

El método findBy() toma un argumento como criterio de búsqueda (y opcionalmente uno de ordenamiento y un límite) y regresa una colección de entidades que coinciden con el criterio. El método findOneBy() es muy similar al método findBy(), pero este solo regresa la primera entidad que se ajusta al criterio de búsqueda.

En el código de abajo usamos el método findBy() para seleccionar las 50 publicaciones publicadas más recientes:

// Find 50 most recent published posts
$posts = $entityManager->getRepository(Post::class)->findBy(
           ['status'=>Post::STATUS_PUBLISHED],
           ['dateCreated'=>'DESC'], 50);

Para nuestra conveniencia la clase EntityRepository provee además métodos mágicos que nos permiten consultar entidades mediante el nombre del atributo, es decir, con los métodos findByX y FindOneByX (donde X debe reemplazarse con el nombre del atributo):

// Query a single post by ID attribute
$post = $entityManager->getRepository(Post::class)->findOneById(1);

// Query posts by status attribute
$posts = $entityManager->getRepository(Post::class)
        ->findByStatus(Post::STATUS_PUBLISHED);

Y el método de búsqueda más complejo es createQueryBuilder(). Este método permite crear consultas DQL complejas.

Si los métodos estándar no son suficientes (o si tenemos criterios de búsqueda complejos y consultas DQL) podemos crear nuestro propio repositorio extendiendo la clase estándar EntityRepository y encapsular la lógica de la búsqueda allí. Mostraremos como hacer esto luego cuando implementemos la característica tag cloud para nuestro Blog de ejemplo.


Top