2012-11-23 88 views
3

大型數據庫的數據我在Symfony2的初學者。加載從Symfony2的和教條2

我有一個地區 - 國家 - 國家 - 城市數據庫更多2,000,000結果。我有8個實體:

 
Region (recursive with itself) - RegionTranslation 

Country - CountryTranslation 

State (recursive with itself) - StateTranslation 

City - CityTranslation 

的事情是,當我想要加載一個國家列表(在下拉只有250個寄存器,例如)的Symfony +學說負載的所有實體結構(所有國家的所有狀態,和所有州的所有城市,各自的翻譯)。

我認爲它花費了很多記憶。

什麼是正確的方法來做到這一點?我可以只加載國家(和翻譯)這種結構?任何想法?

+0

當然,您可以只從一個實體加載所有數據,假定與其他實體的數據沒有依賴關係。 – undefined

+0

默認情況下,Doctrine具有延遲加載功能。它只應在你需要時加載這些實體。也許你已經意外地禁用了它? – Raziel

+0

我如何檢查是否啓用延遲加載?我如何啓用它? 我認爲這是禁用的,因爲當我做某個實體的var_dump()時,它會嘗試顯示所有遞歸實體並崩潰我的瀏覽器。謝謝! – aaubets

回答

2

我對於無關聯的反對意見有同樣的問題。您最好的選擇是使用select2的ajax加載(http://ivaynberg.github.com/select2/),這會在搜索框中顯示有限數量的項目,並且還會根據框中鍵入的內容縮小搜索範圍。

有幾件事情事情需要編碼:

JavaScript文件:

 $(document).ready(function(){ 
     $('.select2thing').select2({ 
      minimumInputLength:1 
     ,width: "100%" 
     ,ajax: { 
      url: <<path>> + "entity/json" 
     ,dataType: 'jsonp' 
     ,quitMillis: 100 
     ,data: function (term, page) { 
     return { 
      q: term, // search term 
      limit: 20, 
      page: page 
     }; 
     } 
    ,results: function (data, page) { 
     var more = (page * 20) < data.total; 
     return { results: data.objects, more: more }; 
    } 
    } 
    }); 

    } 

一個jsonAction控制器:

/** 
    * Lists all Thing entities return in json format 
    * 
    */ 
    public function jsonAction(Request $request) 
    { 
     $em = $this->getDoctrine()->getManager(); 
     $rep = $em->getRepository('yourBundle:Thing'); 
     $qb = $rep->createQueryBuilder('e'); 

     $limit = $request->query->get('limit'); 
     $current = $request->query->get('current'); 
     $page=$request->query->get('page'); 
     $queries=$request->query->get('q'); 
     $qarray=explode(",", $queries); 

     $entities=$rep->getJSON($qarray, $page, $limit); 
     $total=$rep->getJSONCount($qarray); 
     $callback=$request->query->get('callback'); 

     return $this->render('yourBundle:Thing:json.html.twig' 
     , array(
      'entities' => $entities 
      ,'callback' => $callback 
      ,'total'  => $total 
     ) 
    ); 
    } 

樹枝模板(json.html.twig ,可能定製顯示更多)

{{callback}}(
    { "objects" : 
    [ 
    {% for entity in entities %} 
    { "id": "{{entity.id}}", "text": "{{entity}}""} 
    {% if not loop.last %},{% endif %} 
    {% endfor %} 
    ], 
    "total": {{total}} 
    } 
    ) 

變壓器:

使用選擇2控制必須將 '時間' 傳遞給表單生成器控制器:

$editForm = $this->createForm(new ThingType() 
    ,$entity 
    ,array(
     'attr' => array(
      'securitycontext' => $sc 
      ,'em'    => $this->getDoctrine() 
             ->getEntityManager() 
     ) 
    ) 
); 

而在你的表單類型:

if (isset($options['attr']['em'])){ $em = $options['attr']['em'];} else {$em=null;} 

    $transformer = new ThingTransformer($em); 
    $builder->add(
     $builder->create('thing' 
     ,'hidden' 
     ,array(
      'by_reference' => false 
      ,'required' => false 
      ,'attr' => array(
       'class' => 'select2thing' 
      ) 
     ) 
    ) 
     ->prependNormTransformer($transformer) 
); 
+0

我用ajax加載它。但是隻有加載國家的結構需要花費很多時間(5-10秒),並且在國家選擇相同的時間(5-10秒)時重新加載狀態。 – aaubets

+0

調整您的查詢以僅獲得一些結果以獲得更好的速度。我使用$ limit來獲取一些結果,並且這是通過select2來限制的。這應該會顯着加快速度。 – Lighthart

1

您可以嘗試更改hydration mode,使用數組比創建對象消耗更少的內存。

你可以做到這一點是使用iterations以避免內存問題的其他方式:

最後,我想你不能沒有花費大量的時間和內存加載所有,那麼,爲什麼不把幾個查詢加載整個數據?