> For the complete documentation index, see [llms.txt](https://docs.objectiphy.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.objectiphy.net/master.md).

# 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](/annotations.md). You can use entities with [Objectiphy](/annotations/objectiphy-annotations.md) or [Doctrine](/annotations/doctrine-annotations.md) 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](/defining-relationships/one-to-one.md), [many-to-one](/defining-relationships/many-to-one.md), [one-to-many](/defining-relationships/one-to-many.md), and [many-to-many](/defining-relationships/many-to-many.md) relationships
* [lazy or eager](/late-binding-and-lazy-loading.md#lazy-loading-vs-eager-loading) loading
* [filter based on properties](/basic-usage.md) of both parent and child objects (even one-to-many)
* filter using [complex criteria](/query-builder/criteria.md)
* easily write [custom queries](/query-builder.md)
* [pagination](/pagination-and-sorting.md#pagination)
* [iterable results](/streaming-results.md) for streaming
* option of fetching unbound (scalar) results
* [custom repositories](/custom-repositories.md)
* limit hydration using [serialization groups](/serialization-groups.md)
* automatic or manual control of [transactions](/basic-saving.md#transactions)
* [select](/query-builder/select-queries.md), [insert](/query-builder/insert-queries.md), [update](/query-builder/update-queries.md), and [delete](/query-builder/delete-queries.md) records
* [cascade deletes](/deleting.md#cascade-deletes) and [orphan removal](/deleting.md#orphan-removal)
* [embedded](/embedded-value-objects.md) value objects
* perform [scalar joins](/defining-relationships/scalar-joins.md) (retrieve a single value from a joined table without needing a new entity or custom query)
* use aggregate functions to populate [properties](/annotations/objectiphy-annotations.md#aggregate-function-column-annotations) or as [filter criteria](/query-builder/criteria/filtering-by-aggregates.md)
* use any MySQL function you like in custom queries
* mark properties as read only
* [manually override](/mapping-overrides.md) 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 %}
