So, lets get to some code. First we are going to configure our doctrine connection so we can connect to our database. In symfony2, there are three different formats for configuration: YAML, PHP and XML. I am going to use YAML for my configuration, routing, etc. You can use whichever one you prefer (refer to the symfony2 project page docs for details). To set the type of configuration you are using, you have to edit the AppKernel.php file in your app folder. YAML is the default format.
好了,讓我們開始寫一些代碼。首先配置doctrine連接配接。在symfony2裡,有三種不同的配置格式:YAML、PHP和XML。我将使用YAML格式來做配置和路由等。當然,您也可以使用任何一種你喜歡的格式。要設定您要用的配置格式,您需要在您的app檔案夾裡編輯Appkenel.php檔案。YAML是預設格式。
// in AppKernel.php...
public function registerContainerConfiguration(LoaderInterface $loader)
{
// use YAML for configuration
// comment to use another configuration format
$loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
// uncomment to use XML for configuration
//$loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.xml');
// uncomment to use PHP for configuration
//$loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.php');
}
Now that we have our configuration format setup, we need to configure our doctrine connection so that we can connect to the application’s database. In the app/config folder open up the config.yml (.php or .xml depending on your format). By default the doctrine section of the config is commented out. Lets uncomment it and add our database connection info, credentials and setup some defaults.
現在,我們已經完成配置格式的設定。我們還需要配置我們的doctrine連接配接,以便連接配接應用程式資料庫。在app/config檔案夾中打開config.yml(.php或.xml有賴于您所設定的配置格式)。預設情況下,配置的doctrine部分是被注釋的。讓我們去除它并添加我們資料庫的連接配接資訊、證書和一些預設設定。
## Doctrine Configuration
doctrine:
dbal:
driver: %database_driver%
host: %database_host%
dbname: %database_name%
user: %database_user%
password: %database_password%
orm:
auto_generate_proxy_classes: %kernel.debug%
auto_mapping: true
All we have done here is tell doctrine how to connect to our database using values from our parameters.ini file. We have specified that we are using mysql (obviously change this if you are using something else), that the database name is blogdb and supplied the necessary credentials to login. We have also specified the default connection and the default entity manager. We will talk about entity managers in more detail later, but basically an entity manager is what you use to persist objects to the database and retrieve them from the database. One other thing to note is the mappings setting in the orm section. Under this section we tell doctrine what bundles to look for entities in.
在這裡,我們所做的就是告訴doctrine如何使用parameters.ini檔案中的參數來進行資料庫連接配接。我們已經指定使用mysql(顯然,如果你使用其它的資料庫,您需要改變它),資料庫名是blogdb并提供了必要的登入證書。我們還指定了預設連接配接和預設的實體管理器。稍後我們還将讨論實體管理器的有關細節,但實體管理器基本上就是用來将對象持久化到資料庫,并在資料庫中進行檢索的。另一個值得注意的是orm部分的映射設定。在這個部分我們将告訴doctrine如何在Bundle中查找實體。
Now that our doctrine connection is setup, we can move on to writing our entity objects. We are going to do things the doctrine2 way and turn plain old PHP objects into entities using annotations. Basically, we will be adding annotations to doc-block comments on our object fields. If this sounds confusing to you right now, don’t worry it is very simple as you will see shortly.
現在,我們的Doctrine連接配接已經設定完成,我們接下來可以去寫我們的實體對象了。我們打算在doctrine2裡使用注釋(annotations),将POPO轉換成實體。基本上,我們會在我們對象範圍的文檔區域注解(comment)中添加注釋(annotations)。如果現在這個聽起來使你困擾,别擔心,您将很快發現它其實非常簡單。
It’s almost time to start writing code, but first lets discuss our database schema. Our blog application will be very simple. We will have posts, users, categories and tags. A User will create a Post. A Post will have one Category and can optionally have many Tags. The following diagrams lays out our schema.
幾乎可以開始寫代碼了,但首先還是讓我們讨論一下我們的資料庫方案(schema,譯者注:這裡采用了Oricle的譯法)。我們的部落格應用程式非常簡單。我們有博文(posts)、使用者、類别和标簽。一個使用者可以建立一篇博文(Post)。一篇博文擁有類别和可選的标簽。下圖就是我們的方案:
<a href="http://blog.51cto.com/attachment/201107/083352947.png" target="_blank"></a>
As I mentioned before, this is a very oversimplified blog setup. Even though this is a simple schema, it will allow us to use many of the different types of annotations available in doctrine2. As you can see from the above diagram, User has a one-to-many relationship with Post, Category has a one-to-many relationship with Post and Post has a many-to-many relationship with Tag. Now its finally time to write some code. Fire up your favorite IDE and lets get going.
正如我先前所說,這是個相當簡化的部落格設定。盡管它是個簡單的方案,但它也允許我們使用doctrine2中的許多不同類型的注釋(annotations)。如上圖所示,User到Post的關系是一到多的,Category到Post的關系也是一到多,而Post與Tag之間的關系則是多到多的。現在到了最終寫代碼的時間了。選一個你喜歡的IDE,讓我們開始吧。
The first thing we need to do is to navigate to the src/Company/BlogBundle folder. Here we can already see the Controller, Resources and Tests folders have been created as well as the BlogBundle.php class file which defines our bundle. The folder names should be self-explanatory so we will skip a long explanation of them right now and come back to that later. Placing your entity classes in the Entity namespace of your bundle is the standard convention for symfony2 bundles. So lets do that now and create a new folder named Entity in this directory. Now we can create our first entity. Create a file named User.php. Here are the most interesting parts of the code for the User class:
我們需要做的第一件事就是去浏覽一下src/Company/BlogBundle檔案夾。我們看到在該檔案夾下已經建立了Controller,Resources和Tests檔案夾,以及定義了我們Bundle的BlogBundle.php類檔案。檔案夾名應該是不言而明的,以便我們現在或今後檢視時可以省下大量的解釋。将實體類放入Bundle的實體命名空間裡是Symfony2中Bundles的一種标準約定。讓我們現在就開始做,在該目錄下建立一個新的名為Entity的檔案夾。這樣我們就可以建立我們的第一個實體了。建立一個名為User.php的檔案。以下是User類,這裡代碼中最有趣的部分:
namespace Company\BlogBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="user")
*/
class User
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*
* @var integer $id
*/
protected $id;
* @orm:Column(type="string", length="255", name="first_name")
* @var string $firstName
protected $firstName;
* @ORM\Column(type="string", length="255", name="last_name")
* @var string $lastName
protected $lastName;
* @ORM\Column(type="string", length="255")
* @var string $email
protected $email;
* @ORM\Column(type="datetime", name="created_at")
* @var DateTime $createdAt
protected $createdAt;
* @ORM\OneToMany(targetEntity="Post", mappedBy="user")
* @ORM\OrderBy({"createdAt" = "DESC"})
* @var ArrayCollection $posts
protected $posts;
//...
* Constructs a new instance of User
public function __construct()
{
$this->posts = new ArrayCollection();
$this->createdAt = new \DateTime();
}
}
To understand the annotation used on the posts field of the User class we need to take a quick look at the Post entity object code. Here is the relevant code that needs explanation from the Post class:
為了了解User類中posts字段所有的注釋,我們需要看一下Post實體對象代碼。以下是來自Post類中,需要說明的相關代碼:
* @ORM\Table(name="post")
* @ORM\HasLifecycleCallbacks
class Post
* @var string $title
protected $title;
* @var string $slug
protected $slug;
* @ORM\Column(type="text")
* @var string $content
protected $content;
* @ORM\Column(type="datetime", name="updated_at", nullable="true")
* @var DateTime $updatedAt
protected $updatedAt;
* @ORM\ManyToOne(targetEntity="Category")
* @ORM\JoinColumn(name="category_id", referencedColumnName="id")
* @var Category $category
protected $category;
* @ORM\ManyToOne(targetEntity="User", inversedBy="posts")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
* @var User $user
protected $user;
* @ORM\ManyToMany(targetEntity="Tag")
* @ORM\JoinTable(name="post_tag",
* joinColumns={@ORM\JoinColumn(name="post_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id")}
* )
* @var ArrayCollection $tags
protected $tags;
* Constructs a new instance of Post.
*/
$this->tags = new ArrayCollection();
* Invoked before the entity is updated.
* @ORM\PreUpdate
public function preUpdate()
$this->updatedAt = new \DateTime();
As you can see most of the annotations for the Post class are similar to that of the User class. If you take a look at the annotations for the user field you will see that we have used a ManyToOne annotation. This tells doctrine that Posts has a many-to-one relationship with User. The targetEntity attribute points to the entity to which the association is with, in our case User. The inversedBy attribute tells doctrine that the User object has a property named posts which represents the relationship in the inverse direction. This makes the association bi-directional. If you look at the posts field annotation in the User entity class it should now make sense. It simply says that we have a one-to-many relationship with the Post entity. This is spelled out using the targetEntity and the mappedBy attributes. The mappedBy attribute simply designates the field in the entity that is the owner of the relationship. If you look at the category field of the Post entity, you will see a very similar association mapping as the user field except that it is a unidirectional mapping. As an exercise you can change it into a bidirectional mapping if you wish.
正如您所看到的,Post類中的大部分注釋與User類中的相似。如果您注意到user字段的注釋,您将發現我們使用了ManyToOne注釋。它告訴Doctrine,Posts類與User類有着多對一的關系。targetEntity屬性指出與哪個實體關聯,在這裡是User。inverseBy屬性告訴doctrine,User對象有一個名為posts的屬性,表示的是反向關系。這形成了雙向關聯。如果你在User實體類中看到posts字段,那麼現在您将明白是什麼意思了。簡單來說該類與Post實體有着一對多的關系。它是由targetEntity和 mappedBy屬性組成。mappedBy屬性指定擁有這個關系的實體中的字段。如果你注意到Post實體中的category字段,你會發現一個與user字段中非常相似的關聯映射,除了它是一個單向映射。如果您希望,您可以做将它轉變為雙向映射的練習。
Next, take a look at the annotations for the tags field in the Post object. These annotations define a unidirectional many-to-many relationship. This annotation is fairly straightforward. One of the cool things about doctrine2 annotations is that we don’t need to create join tables for our many-to-many relationships by hand. We can just specify them with a JoinTable annotation and doctrine will take care of the rest for us.
接下來,看一下Post對象中tags字段的注釋。這些注釋定義了一個單向的多到多的關系。該注釋相當簡單,Doctrine2注釋中很酷的地方在于我們不需要手工建立多對多的表連接配接。我們隻需使用JoinTable注釋指定它們,然後Doctrine就會幫我們完成剩餘的事情。
php app/console doctrine:schema:create
That is it for this part. We have configured our doctrine connection, created and annotated the entity objects, and let doctrine automatically create our database tables based on those annotations. Next time we will start to work with routing, controllers and templates.
這就是本部分所講内容。我們配置了我們的Doctrine連接配接,建立和注釋了實體對象,并讓Doctrine根據那些注釋自動建立我們的資料表。接下來的時間,我們将開始路由、控制器和模闆方面的工作。
本文轉自 firehare 51CTO部落格,原文連結:http://blog.51cto.com/firehare/602982,如需轉載請自行聯系原作者