Database and Doctrine (reproduced from http://www.111cn.net/phper/332/85987.htm), www.111cn. netphper
The most common and challenging task for any application is to read and persist data information from the database. Although the complete symfony framework does not integrate ORM by default, the symfony Standard Edition integrates many programs and a library such as Doctrine, which aims to provide developers with powerful tools, it makes your work easier. In this chapter, you will learn the basic concepts of doctrine and learn how to use databases easily.
Doctrine can be used completely out of symfony and is optional in symfony. This chapter focuses on the Doctrine ORM, which aims to map your object to a database (such as MySQL, PostgreSQL, and Microsoft SQL ). If you like to Use the original database query, it is very easy to know How to Use Doctrine DBAL in cookbook.
You can also use the Doctrine ODM library to persist data to MongoDB. For more information, see DoctrineMongoDBBundle.
A simple example: a product
The simplest way to understand how Doctrine works is to look at a practical application. In this chapter, you need to configure your database, create a Product object, persist it to the database, and fetch it back.
Configure Database
Before you start, you need to configure your database link information. By convention, this information is usually configured in the app/config/parameters. yml file:
# app/config/parameters.ymlparameters: database_driver: pdo_mysql database_host: localhost database_name: test_project database_user: root database_password: password # ...
Defining the configuration information to parameters. yml is just a convention. The configuration information defined in this file will be referenced by the main configuration file during Doctrine installation.
# app/config/config.ymldoctrine: dbal: driver: "%database_driver%" host: "%database_host%" dbname: "%database_name%" user: "%database_user%" password: "%database_password%"
By separating database information into a specific file, you can easily save different versions for each server. You can also easily store database configurations (some sensitive information) outside the project, Just Like apache configuration. For more information, see How to Set external Parameters in the Service Container.
Now Doctrine knows your database configuration. You can use it to create a database.
$ php app/console doctrine:database:create
Set the database to UTF8
Even for experienced programmers, a common mistake is that after the Symfony project begins, they forget to set their database's default Character Set and verification rules, the latin type provided by most databases is used as the default value. They may remember the first operation, but they forgot it after hitting the Common commands related to the two lines.
$ Php app/console doctrine: database: drop -- force
$ Php app/console doctrine: database: create
It is impossible to directly assign the default character set in Doctrine, because doctrine will adapt as many "unknown" situations as possible based on the Environment configuration. One solution is to configure the default information of "server level.
Setting UTF8 to the default Character Set of MySql is very simple. You only need to add a few lines of code in the database configuration file (generally my. cnf file)
[Mysqld]
# Version 5.5.3 introduced "utf8mb4", which is recommended
Collation-server = utf8mb4_general_ci # Replaces utf8_general_ci
Character-set-server = utf8mb4 # Replaces utf8
We recommend that you avoid using Mysql's uft8 character set because it is not compatible with 4-byte unicode characters and will be cleared if such characters exist in the string. However, this problem has been fixed. For more information, see the new utf8mb4 character set.
------------------------------------------- Creating a database is not as convenient as directly operating in mysql -----------------------------------------------
If you want to use SQLite as the database, you need to set the path to your database path.
# app/config/config.ymldoctrine: dbal: driver: pdo_sqlite path: "%kernel.root_dir%/sqlite.db" charset: UTF8
Create an object class
Suppose you create an application, some of which need to be displayed. If you do not consider Doctrine or database, you should also know that you need a Product object to express these products. Create a class under the Entity directory of your AppBundle.
// src/AppBundle/Entity/Product.phpnamespace AppBundle\Entity; class Product{ protected $name; protected $price; protected $description;}
Such a class is often called "Entity", meaning that a base class stores data. They are simple to meet your application's business needs. But now it cannot be saved to the database, because it is just a simple PHP class.
Once you have learned the concepts behind Doctrine, you can use Doctrine to create entity classes for you. He will ask you some questions to create entity:
$ php app/console doctrine:generate:entity
Add ing information
Doctrine allows you to perform database operations in a more interesting way, instead of just getting list-based rows into arrays. Doctrine allows you to save the entire object to the database or retrieve the object from the database. These are implemented by ing the PHP class to a database table, and the PHP class attributes correspond to the columns in the database table.
Because Doctrine can do this, you only need to create a meatdata, or configure how to map the Doctrine Product class and its attributes to the database. These metadata can be defined into various formats, including YAML, XML, or directly defined into the Product class through declaration.
annotations:// src/AppBundle/Entity/Product.phpnamespace 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", length=100) */ protected $name; /** * @ORM\Column(type="decimal", scale=2) */ protected $price; /** * @ORM\Column(type="text") */ protected $description;}
A bundle can only accept one metadata Definition Format. For example, you cannot mix the metadata defined by YAML with the declared PHP Object Class.
The table name is optional. If it is omitted, it is automatically determined based on the name of the entity class.
Doctrine allows you to select different field types. Each field has its own configuration. For Field type information, see Doctrine Field Types Reference.
You can also view all the details about the docing information in the Doctrine official document Basic Mapping Documentation. If you use annotations, you need to have ORM (for example, ORM \ Column () for all annotations. These doctrine templates do not exist. You also need to introduce use Doctrine \ ORM \ Mapping as ORM; declare that it is used to import the ORM registration prefix.
Be careful that your class name and attributes may be mapped to a protected SQL field (such as group and user ). For example, if your entity class is named Group, your table name is group by default, which may cause SQL errors in some engines. Please check the Reserved SQL keywords documentation, which will tell you how to circumvent these names correctly. In addition, you can easily map to different table names and field names to select your database outline. See the Persistent classes and Property Mapping documents of Doctrine.
When other libraries or programs (such as Doxygen) Use annotations, you should add @ IgnoreAnnotation annotations to this class to notify Symfony to ignore them.
For example, to prevent @ fn declaration from throwing an exception, you can:
/** * @IgnoreAnnotation("fn") */class Product// ...
Produce Getters and Setters
Although Doctrine now knows how to persist the Product object to the database, is the class itself useful. Because Product is just a standard PHP class, you need to create getter and setter methods (such as getName () and setName () to access its attributes (because its attribute is protected ), fortunately, Doctrine can do this for us:
$ php app/console doctrine:generate:entities AppBundle/Entity/Product
This command ensures that all getters and setters of the Product class are generated. This is a safe command line. You can run it multiple times. It only generates getters and setters that do not exist and does not replace the existing ones.
Remember that the doctrine entity engine produces simple getters/setters. You should check the generated entity and adjust the getter/setter logic to what you want.
About doctrine: generate: entities command
You can use it to generate getters and setters.
Use it to configure @ ORM \ Entity (repositoryClass = "...") Generate the repository class.
It can be used to generate a suitable constructor for 1: n or n: m.
This command will save a backup Product. php ~ of the original Product. php file ~. In some cases, the error "cannot be declared again" may also occur. You can delete it with confidence to eliminate the error. You can also use the-no-backup option to prevent these configuration files from being generated.
Of course, you do not need to rely on this command line. Doctrine does not rely on code generation. For standard PHP classes, you only need to ensure that its protected/private attributes have the getter and setter methods. It is mainly because it is a common thing to create with the command line.
You can also generate getter and setter for all known entities in a bundle or the entire entity namespace (any PHP class containing the Doctrine ing declaration:
# generates all entities in the AppBundle$ php app/console doctrine:generate:entities AppBundle # generates all entities of bundles in the Acme namespace$ php app/console doctrine:generate:entities Acme
Doctrine does not care whether your attributes are protected or private, or whether these attributes have getter or setter. The getter or setter is generated because you need to communicate with your PHP Object.
Create database tables and modes
Now we have an available Product class and its ing information, so Doctrine knows how to persist it. Of course, there is no corresponding Product database table in the database for the product. Fortunately, Doctrine can automatically create all database tables.
$ php app/console doctrine:schema:update --force
To be honest, this command is surprisingly powerful. It compares the current database based on the entiing information of your entities and generates the update SQL statement for the new database. In other words, if you want to add a new property ing metadata to the Product and run the task, it will generate an alert table statement to add new columns to the existing product table.
Migrations allows you to generate these SQL statements. It is stored in a migration class and can run in your production environment in an organized manner. The system tracks and migrates databases securely and reliably.
Now your database has a full-featured product table, and every column of it will be mapped to the metadata you specified.
Persistent Object to database
Now we have a Product entity and the product database table mapped to it. You can persistently store data in the database. In the Controller, it is very simple. Add the following method to bundultcontroller of bundle.
// 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.99'); $product->setDescription('Lorem ipsum dolor'); $em = $this->getDoctrine()->getManager(); $em->persist($product); $em->flush(); return new Response('Created product id '.$product->getId());}
If you want to demonstrate this case, you need to create a route pointing to this action to let him work.
This document describes how to use the getDoctrine () method in the controller. This method is the most convenient way to obtain the doctrine Service. You can use doctrine to inject the service anywhere in the service.