Databases and Symfony: Difference between revisions
No edit summary |
|||
| Line 114: | Line 114: | ||
The preferred way to generate changes that can be applied to a production environment is with [http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html migrations] which generate SQL statements that are stored in migration classes. | The preferred way to generate changes that can be applied to a production environment is with [http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html migrations] which generate SQL statements that are stored in migration classes. | ||
== | == Repository classes == | ||
Repository classes isolate custom queries so the can be more easily and reliably reused and tested.<ref>[http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes Custom Repository Classes], Symfony documentation</ref> | Repository classes isolate custom queries so the can be more easily and reliably reused and tested.<ref>[http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes Custom Repository Classes], Symfony documentation</ref> | ||
=== Mapping repository classes === | |||
To map an entity class to a repository class, add the name of the repository class to the mapping definition in the entity class: | To map an entity class to a repository class, add the name of the repository class to the mapping definition in the entity class: | ||
| Line 134: | Line 136: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Automatically generating repository classes === | |||
Doctrine can generate the repository class for you by running the same command used earlier to generate the missing getter and setter methods: | |||
<syntaxhighlight lang="bash"> | |||
$ php app/console doctrine:generate:entities AppBundle | |||
</syntaxhighlight> | |||
'''''Note''' that this command uses the project's database settings to connect. If the server is set to `localhost` in `parameters.yml` and the command is run from another machine, the database connection won't be correct.'' | |||
=== Adding custom queries to repository classes === | |||
== Committing object data to a database == | == Committing object data to a database == | ||
Revision as of 18:09, 1 February 2015
Overview
Symfony standard edition comes bundled with Doctrine, a library that provides ORM and reading/writing to databases.[1]
Symfony, however, is not tied to Doctrine.
The important thing to keep in mind with Doctrine is that you're working with the entity classes, not directly with database objects. Doctrine results are entity classes, not rows in tables.
Configuring database connections
The actual database connection property values are stored in app/config/parameters.yml, which are in turn referenced in the app's main configuration file, app/config/config.yml:[2]
# app/config/config.yml
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
Using the Symfony configuration, a database can be created with
$ php app/console doctrine:database:create
Entity classes
Entity classes define the basic mapping to a table in the database.
Configuring entity classes
Classes that represent table data go in the Entity directory inside of AppBundle.[3]
Columns are represented by properties of the class. Typically these are protected and accessed with public "getter" and "setter" functions.
// src/AppBundle/Entity/Product.php
namespace AppBundle\Entity;
class Product
{
protected $id;
protected $name;
protected $description;
public function getId()
{
return ($this->id);
}
public function setID($id)
{
$this->id = $id;
}
/* etc... */
}
The getter and setter routines can be generated with
$ php app/console doctrine:generate:entities AppBundle/Entity/Product
Mapping information
Mapping metadata can be specified with YAML, XML, or directly in the entity class via annotations:[4],[5]
// src/AppBundle/Entity/Product.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="product")
*/
class Product
{
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string")
*/
protected $name;
/* etc... */
}
Generating database tables and/or schema
Doctrine can create and update tables in the database using the entity classes as templates with:
$ php app/console doctrine:schema:update --force
Changes to the properties and mapping of the entity class will cause updates that will attempt to preserve the existing data.
The preferred way to generate changes that can be applied to a production environment is with migrations which generate SQL statements that are stored in migration classes.
Repository classes
Repository classes isolate custom queries so the can be more easily and reliably reused and tested.[6]
Mapping repository classes
To map an entity class to a repository class, add the name of the repository class to the mapping definition in the entity class:
// src/AppBundle/Entity/Product.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="AppBundle\Entity\ProductRepository")
*/
class Product
{
//...
}
Automatically generating repository classes
Doctrine can generate the repository class for you by running the same command used earlier to generate the missing getter and setter methods:
$ php app/console doctrine:generate:entities AppBundle
Note that this command uses the project's database settings to connect. If the server is set to localhost in parameters.yml and the command is run from another machine, the database connection won't be correct.
Adding custom queries to repository classes
Committing object data to a database
The logic to commit object data to a database is place in a controller:[7]
// src/AppBundle/Controller/DefaultController.php
// ...
use AppBundle\Entity\Product;
use Symfony\Component\HttpFoundation\Response;
// ...
public function createAction()
{
$product = new Product();
$product->setName('A Foo Bar');
$product->setPrice(19.95);
$product->setDescription('Lorem ipsum dolor');
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
return new Response('Created product id '.$product->getId());
}
Retrieving data
Retrieving a single record
Repositories are used for queries for particular types of objects.[8]
$product = $this->getDoctrine()
->getRepository('AppBundle:Product')
->find($id);
if (!$product) {
throw $this->createNotFoundException(
'No product found for id '.$id
);
}
AppBundle::Product is shorthand for any class under the Entity namespace of the bundle.
Alternatively in a controller, the @ParamConverter annotation can be used to automatically load up an object using the value of an $id parameter passed to the controller.[9]
findBy(), findOneBy(), and findBy[COLUMN_NAME] are repsoitory methods used to filter queries.
Notes
- ↑ Doctrine, Symfony documentation]
- ↑ Configuring the Database, Symfony documentation
- ↑ Doctrine Documentation, Symfony Documentation, "The Book"
- ↑ Doctrine Property Mapping
- ↑ Doctrine Field Types Reference
- ↑ Custom Repository Classes, Symfony documentation
- ↑ Persisting Objects to the Database, Doctrine documentation at Symphony documentation, "The Book"
- ↑ Fetching Objects From the Database, Symfony documentation
- ↑ FrameworkExtraBundle documentation, Symfony documentation