Lean Mapper Query es un concepto de objeto de consulta para la biblioteca Lean Mapper que ayuda a crear consultas complejas utilizando uniones automáticas ( idea tomada de la biblioteca NotORM ). Mire las clases base sugeridas. Para obtener documentación checa, consulte la wiki.
SQL
, por lo que la mayoría de las expresiones SQL están disponibles.@book.tags.name
)Se puede instalar a través de Composer.
composer require mbohuslavek/leanmapper-query
Supongamos que tenemos los siguientes repositorios:
class BaseRepository extends LeanMapper Repository
{
public function find ( Query $ query )
{
$ this -> createEntities ( $ query
-> applyQuery ( $ this -> createFluent (), $ this -> mapper )
-> fetchAll ()
);
}
}
class BookRepository extends BaseRepository
{
}
y las siguientes entidades:
/**
* @property int $id
* @property string $name
*/
class Tag extends LeanMapper Entity
{
}
/**
* @property int $id
* @property Author $author m:hasOne
* @property Tag[] $tags m:hasMany
* @property DateTime $pubdate
* @property string $name
* @property bool $available
*/
class Book extends LeanMapper Entity
{
}
/**
* @property int $id
* @property string $name
* @property Book[] $books m:belongsToMany
*/
class Author extends LeanMapper Entity
{
}
Construimos una consulta :
$ query = new LeanMapperQuery Query ;
$ query -> where ( ' @author.name ' , ' Karel ' );
Ahora bien, si queremos obtener todos los libros cuyo nombre de autor sea Karel, tenemos que hacer esto:
$ bookRepository = new BookRepository (...);
$ books = $ bookRepository -> find ( $ query );
La consulta de la base de datos se verá así:
SELECT [book]. *
FROM [book]
LEFT JOIN [author] ON [book].[author_id] = [author].[id]
WHERE ([author].[name] = ' Karel ' )
Puede ver que realiza uniones automáticas mediante la notación de puntos . Admite todos los tipos de relaciones conocidos por Lean Mapper .
Es muy fácil utilizar funciones SQL. Podemos actualizar la consulta como esta:
$ query -> where ( ' DATE(@pubdate) > %d ' , ' 1998-01-01 ' );
$ books = $ bookRepository -> find ( $ query );
que cambia la consulta de la base de datos a lo siguiente:
SELECT [book]. *
FROM [book]
LEFT JOIN [author] ON [book].[author_id] = [author].[id]
WHERE ([author].[name] = ' Karel ' ) AND ( DATE ([book].[pubdate]) > ' 1998-01-01 ' )
Puede ampliar la clase Query
y definir sus propios métodos.
class BookQuery extends LeanMapperQuery Query
{
public function restrictAvailable ()
{
$ this -> where ( ' @available ' , true )
-> orderBy ( ' @author.name ' );
return $ this ;
}
}
/////////
$ query = new BookQuery ;
$ query -> restrictAvailable ();
$ books = $ this -> bookRepository -> find ( $ query );
También es posible consultar una propiedad de entidad ( actualmente solo aquellas propiedades con relaciones BelongsToMany
o HasMany
). Hagamos la clase BaseEntity
:
class BaseEntity extends LeanMapperQuery Entity
{
protected static $ magicMethodsPrefixes = [ ' find ' ];
protected function find ( $ field , Query $ query )
{
$ entities = $ this -> queryProperty ( $ field , $ query );
return $ this -> entityFactory -> createCollection ( $ entities );
}
}
/*
* ...
*/
class Book extends BaseEntity
{
}
Tenga en cuenta que BaseEntity
debe extender LeanMapperQuery Entity
para que lo siguiente sea posible.
Hemos definido el método find
como protected
porque al especificar el nombre del método en la propiedad $magicMethodsPrefixes
, puedes consultar entidades como esta:
$ book ; // previously fetched instance of an entity from a repository
$ query = new LeanMapper Query ;
$ query -> where ( ' @name != ' , ' ebook ' );
$ tags = $ book -> findTags ( $ query );
El método mágico findTags
eventualmente llamará a su método protegido find
con 'etiquetas' como primer argumento.
La consulta de base de datos resultante se ve así:
SELECT [tag]. *
FROM [tag]
WHERE [tag].[id] IN ( 1 , 2 ) AND ([tag].[name] != ' ebook ' )
La primera condición en la cláusula where
, [tag].[id] IN (1, 2)
, se toma de la entidad que atraviesa ( las etiquetas se consultan con las etiquetas propias de esta entidad de libro en particular ).
Si modificamos ligeramente BaseRepository
y BaseEntity
, podemos simplificar el trabajo con objetos de consulta. Para lograr esto, mire las clases base sugeridas . Hace posible lo siguiente.
$ books = $ bookRepository -> query ()
-> where ( ' @author.name ' , ' Karel ' )
-> where ( ' DATE(@pubdate) > ? ' , ' 1998-01-01 ' )
-> find ();
// or...
$ tags = $ book -> queryTags ()
-> where ( ' @name != ' , ' ebook ' )
-> find ();
Copyright (c) 2013 Michal Bohuslávek
Licenciado bajo la licencia MIT.