# Introduction

Create repositories using the repository factory:

```php
use Objectiphy\Objectiphy\Factory\RepositoryFactory;
use MyProject\Contact;

$pdo = new \PDO(
    'mysql:host=localhost;dbname=test', 
    getenv('DB_USER'), 
    getenv('DB_PASS')
);

$factory = new RepositoryFactory($pdo);
$repository = $factory->createRepository(Contact::class);
```

You can use simple criteria in an array to load entities:

```php
// Load all staff in Sales department:
$criteria = ['department.name' => 'Sales'];
$contacts = $repository->findBy($criteria);
```

Or use more complex criteria to limit which properties of which records are returned using the object-oriented query builder, which closely resembles standard SQL syntax (but using classes and properties instead of tables and columns):

```php
// Get just the name for permanent staff in Sales and 
// Finance who have a car (even if the Contact entity 
// does not have a vehicle property)
$criteria = ['departments' => ['Sales', 'Finance']];
$query = QB::create()
         ->select('firstName', 'lastName')
         ->from(Contact::class)
         ->innerJoin(Vehicle::class, 'v')
             ->on('id', '=', 'v.ownerContactId')
             ->and('v.type', '=', 'car')
         ->where('department.name', 'IN', ':departments')
         ->and('isPermanent', '=', true)
         ->buildSelectQuery($criteria);
 $contacts = $repository->findBy($query);
```

Inserting or updating entities is also very easy (Objectiphy keeps track of changes to entities that it loaded, so will only save the things that have changed):

```php
$repository->saveEntity($contact);
```

Mapping information is typically specified using [mapping definitions](https://docs.objectiphy.net/annotations). You can use entities with [Objectiphy](https://docs.objectiphy.net/annotations/objectiphy-annotations) or [Doctrine](https://docs.objectiphy.net/annotations/doctrine-annotations) attributes or annotations (some features of Objectiphy that are not present in Doctrine require Objectiphy attributes, but you can mix both types).

## Features

* [one-to-one](https://docs.objectiphy.net/defining-relationships/one-to-one), [many-to-one](https://docs.objectiphy.net/defining-relationships/many-to-one), [one-to-many](https://docs.objectiphy.net/defining-relationships/one-to-many), and [many-to-many](https://docs.objectiphy.net/defining-relationships/many-to-many) relationships
* [lazy or eager](https://docs.objectiphy.net/late-binding-and-lazy-loading#lazy-loading-vs-eager-loading) loading
* [filter based on properties](https://docs.objectiphy.net/basic-usage) of both parent and child objects (even one-to-many)
* filter using [complex criteria](https://docs.objectiphy.net/query-builder/criteria)
* easily write [custom queries](https://docs.objectiphy.net/query-builder)
* [pagination](https://docs.objectiphy.net/pagination-and-sorting#pagination)
* [iterable results](https://docs.objectiphy.net/streaming-results) for streaming
* option of fetching unbound (scalar) results
* [custom repositories](https://docs.objectiphy.net/custom-repositories)
* limit hydration using [serialization groups](https://docs.objectiphy.net/serialization-groups)
* automatic or manual control of [transactions](https://docs.objectiphy.net/basic-saving#transactions)
* [select](https://docs.objectiphy.net/query-builder/select-queries), [insert](https://docs.objectiphy.net/query-builder/insert-queries), [update](https://docs.objectiphy.net/query-builder/update-queries), and [delete](https://docs.objectiphy.net/query-builder/delete-queries) records
* [cascade deletes](https://docs.objectiphy.net/deleting#cascade-deletes) and [orphan removal](https://docs.objectiphy.net/deleting#orphan-removal)
* [embedded](https://docs.objectiphy.net/embedded-value-objects) value objects
* perform [scalar joins](https://docs.objectiphy.net/defining-relationships/scalar-joins) (retrieve a single value from a joined table without needing a new entity or custom query)
* use aggregate functions to populate [properties](https://docs.objectiphy.net/annotations/objectiphy-annotations#aggregate-function-column-annotations) or as [filter criteria](https://docs.objectiphy.net/query-builder/criteria/filtering-by-aggregates)
* use any MySQL function you like in custom queries
* mark properties as read only
* [manually override](https://docs.objectiphy.net/mapping-overrides) mapping definitions (useful for unit testing)
* custom collection classes (for collections of child objects)
* handles recursive object relationships

{% hint style="danger" %}
This library has the ability to insert, update, and delete records in your database. Use with care!
{% endhint %}
