2017-04-11 57 views
1

我的項目Pommbundle關係,我用pommbundle我Symfony的項目,我有一個問題:與另一個表

例如:

 
    TABLE Catalogue: 
    id = 1 
    name = test 
    webinfo = 2 

 
    TABLE Info : 
    id=1 
    webid = 2 
    textinfo = OK 
    textmore = it's test 

關係

 Catalogue.webinfo = Info.webid

如果我的實體與架構中定義的另一個實體有關係,並且我想要一個包含所有信息的對象,因爲轉儲「目錄」只返回「webinfo」的整數,所以如何訪問信息。吃掉我自己的方法?該包包含一個方法?

是否可以顯示一個基本的例子,用於symfony2?

感謝您

回答

1

POMM不是一個ORM,因此不提供,自動將獲取關係的方法。

這種選擇是因爲大多數程序員習慣的簡單狀態的取得:

$blog_posts = $orm->getBlogPosts(); // SELECT * FROM blog.post; 

foreach ($blog_posts as $blog_post) { 
    printf(
     "The post titled '%s' has been written by '%s'.\n", 
     $post->getTitle(), 
     $post->getAuthor()->getName() // SELECT * FROM blog.author WHERE author_id = $* 
    ); 
} 

,因爲有博客文章上面的代碼發出的作者表作爲許多查詢,這就是所謂的嵌套循環查詢,這是一個巨大的性能問題,因爲大多數程序員實際上並沒有看到它執行了那麼多的查詢。

你可以只用一個查詢做相同的SQL:

SELECT 
    title, 
    published_at, 
    … -- other fields 
    a AS author 
FROM 
    blog.post p 
    LEFT JOIN blog.author a USING (author_id) 

這將輸出線,如:

 title  |  published_at  | … |     author 
Gone with the wind | 2010-04-04 13:43:02… | … | ("Jules Vernes","[email protected]", …) 

的Postgres可以直接在集合的結果返回作者一行博客帖子,這比以前的解決方案效率高得多,但如果作者記錄很大,這仍然會導致性能問題。自動限制在博客帖子實體中獲取的作者字段的數量可能很有趣,也許只是名字就夠了。讓我們在博客文章模型進行這樣的查詢:

class PostModel extends Model 
{ 
    // … 

    public function getWithAuthor() 
    { 
     // HINT: this is bad practice, read below. 
     $sql = <<<SQL 
select P.post_id, P.title, …, A.name AS author_name 
from blog.post P 
    left join blog.author A using (author_id) 
SQL; 

     return $this->query($sql); 
    } 

在控制器中,則容易與附加的作者信息,以獲取博客文章:

$blog_posts = $this->get('pomm')['my_session'] 
    ->getModel(PostModel::class) 
    ->getWithAuthor(); 

foreach ($blog_posts as $post) { 
    printf(
     "Post '%s' has been written by '%s'.\n", 
     $post['title'], 
     $post['author_name'] 
    ); 
} 

但這種方法是不能,因爲非常便攜每個關係(表格)的名稱都是硬編碼的,投影也是如此(SELECT部分​​中的字段)。更改數據庫結構會毀了這個查詢。這裏有一個方法來規避:

class PostModel extends Model 
{ 
    // … 

    public function getWithAuthor(Where $condition = null) 
    { 
     $condition = (new Where)->andWhere($condition); // empty condition and empty condition => true. 
     $sql = <<<SQL 
select {projection} 
from {post} P 
    left join {author} A using (author_id) 
where {condition} 
SQL; 

     $projection = $this->createProjection()   // use Post fields 
      ->setField('author_name', 'A.name', 'text'); // add a new field with its type 
     $author_relation = $this->getSession() 
      ->getModel(AuthorModel::class)    // get author relation name 
      ->getStructure() 
      ->getRelation(); 

     $sql = strtr(         // transform the SQL 
      $sql, 
      [ 
       '{projection}'  => $projection->formatFieldsWithFieldAlias("P"), 
       '{post}'   => $this->structure->getRelation(), 
       '{author}'   => $author_relation, 
       '{condition}'  => $condition, 
      ]); 

     return $this->query($sql, $condition->getValues(), $projection); 
    } 

如果我們需要,因爲昨天他們的作者姓名獲取所有博客帖子?

$blog_posts = $this->get('pomm')['my_session'] 
    ->getModel(PostModel::class) 
    ->getWithAuthor(new Where("published_at > $*::timestamptz", [new \DateTime('yesterday')])); 

也可以抓取背面整體嵌套者實例,只是改變投影在該方法中:

$projection = $this->createProjection() 
    ->setField('author', 'A', 'blog.author'); 

注:上面的字段的類型是表格,其中行起源。在Postgres中創建表意味着創建一個類型。

在控制器:

foreach ($blog_posts as $post) { 
    printf(
     "Post '%s' has been written by '%s'.\n", 
     $post['title'], 
     $post['author']['name'] 
    ); 
} 

Postgres的是ORM。

0

感謝你們的一切, 我只是一個第二個錯誤在我的代碼 修正:

public function findWithJointureAll(Where $condition = null) 
{ 
    $famille_model = $this 
     ->getSession() 
     ->getModel('\AppBundle\Entity\MyDb1\PublicSchema\FamilleModel') 
     ; 

    $condition = (new Where)->andWhere($condition); 

    $sql =" 
    select 
     {projection} 
    from 
     {ssfamille} ssf 
     inner join {famille} fam ON ssf.\"Famille\" = fam.\"ID\" where {condition}"; 

    $projection = $this->createProjection() 
     ->setField('test', 'fam','"Famille"') 
     ; 

    $sql = strtr(
     $sql, 
     [ 
      '{ssfamille}' => $this->structure->getRelation(), 
      '{famille}'  => $famille_model->getStructure()->getRelation(), 
      '{projection}' => $projection->formatFieldsWithFieldAlias('ssf'), 
      '{condition}' => $condition, 
     ] 
    ); 

    return $this->query($sql,$condition->getValues(),$projection); 
} 

我只想補充$ projection-> formatFieldsWithFieldAlias( 'SSF')等報價,因爲名字與大寫的基地...

謝謝你的包,它只是完美!