Lean Mapper Query is a concept of a query object for Lean Mapper library which helps to build complex queries using automatic joins (idea taken from NotORM library). Look at the suggested base classes. For Czech documentation have a look at the wiki.
SQL preprocessor, hence most SQL expressions are available@book.tags.name)It can be installed via Composer.
composer require mbohuslavek/leanmapper-query
Suppose we have the following repositories:
class BaseRepository extends LeanMapperRepository
{
public function find(Query $query)
{
$this->createEntities($query
->applyQuery($this->createFluent(), $this->mapper)
->fetchAll()
);
}
}
class BookRepository extends BaseRepository
{
}and the following entities:
/**
* @property int $id
* @property string $name
*/
class Tag extends LeanMapperEntity
{
}
/**
* @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 LeanMapperEntity
{
}
/**
* @property int $id
* @property string $name
* @property Book[] $books m:belongsToMany
*/
class Author extends LeanMapperEntity
{
}We build a query:
$query = new LeanMapperQueryQuery;
$query->where('@author.name', 'Karel');Now, if we want to get all books whose author's name is Karel, we have to do this:
$bookRepository = new BookRepository(...);
$books = $bookRepository->find($query);The database query will look like this:
SELECT [book].*
FROM [book]
LEFT JOIN [author] ON [book].[author_id] = [author].[id]
WHERE ([author].[name] = 'Karel')You can see it performs automatic joins via the dot notation. It supports all relationship types known to Lean Mapper.
It is very easy to use SQL functions. We can update query like this:
$query->where('DATE(@pubdate) > %d', '1998-01-01');
$books = $bookRepository->find($query);which changes the database query into the following:
SELECT [book].*
FROM [book]
LEFT JOIN [author] ON [book].[author_id] = [author].[id]
WHERE ([author].[name] = 'Karel') AND (DATE([book].[pubdate]) > '1998-01-01')You can extend the Query class and define your own methods.
class BookQuery extends LeanMapperQueryQuery
{
public function restrictAvailable()
{
$this->where('@available', true)
->orderBy('@author.name');
return $this;
}
}
/////////
$query = new BookQuery;
$query->restrictAvailable();
$books = $this->bookRepository->find($query);It is also possible to query an entity property (currently only those properties with
BelongsToMany or HasMany relationships). Let's make the BaseEntity class:
class BaseEntity extends LeanMapperQueryEntity
{
protected static $magicMethodsPrefixes = ['find'];
protected function find($field, Query $query)
{
$entities = $this->queryProperty($field, $query);
return $this->entityFactory->createCollection($entities);
}
}
/*
* ...
*/
class Book extends BaseEntity
{
}Note that BaseEntity must extend LeanMapperQueryEntity to make the following possible.
We have defined the find method as protected because by specifying the method name in the
$magicMethodsPrefixes property, you can query entities like this:
$book; // previously fetched instance of an entity from a repository
$query = new LeanMapperQuery;
$query->where('@name !=', 'ebook');
$tags = $book->findTags($query);The magic method findTags will eventually call your protected method find with 'tags' as
the 1st argument.
The resulting database query looks like this:
SELECT [tag].*
FROM [tag]
WHERE [tag].[id] IN (1, 2) AND ([tag].[name] != 'ebook')The first condition in the where clause, [tag].[id] IN (1, 2), is taken from the entity
traversing (tags are queried against this particular book entity's own tags).
If we slightly modify BaseRepository and BaseEntity, we can simplify working with query objects.
To achieve this look at the suggested base classes. It makes
the following possible.
$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
Licensed under the MIT license.