1. 程式人生 > >CodeIgniter Doctrine2基本使用(二)(轉)

CodeIgniter Doctrine2基本使用(二)(轉)

IT name 多維數組 輸入 很好 ech 理解 不用 獲取

CodeIgniter Doctrine2基本使用(二)

繼上次寫的一篇文章《CodeIgniter Doctrine2基本使用(一)》寫到操作實體的之通過Channel這個實體向數據庫表插入一條數據,那麽今天要寫的就是通過實體獲取數據,當然查詢這一塊比較多,可能也會分好幾篇講。

Doctrine2 簡單的用法

操作實體

  • 《CodeIgniter 3.0整合Doctrine2》
  • 《CodeIgniter Doctrine2基本使用(一)》

上一篇文章講到插入一條數據,插入很簡單只要設置實體的成員屬性的值就能完成,當然如果有多個實體的話可以多次使用 $this->em->persist();

這個方法。然後只要再執行一次 $this->em->flush(); 這個方法就行了,它會進行一次數據庫連接,然後執行上面實體生成的SQL語句。

簡單查詢操作

通過Entity查詢的方式 有很多,我們先從最簡單的開始,還是以Entity\Channel這個實體為例,以下面一段代碼為例:


public function index()
{
	$id = 1;
	
	$limit  = 20;
	$offset = 1;
	
	/**
	 * @var  $channelInfo Entity\Channel
	 * @var  $channelOneBy Entity\Channel
	 */
	 
	$channelRepository = $this->em->getRepository(‘Entity\Channel‘);
	
	$channelAll  	= $channelRepository->findAll();
	
	$channelInfo 	= $channelRepository->find( $id );
	
	$channelOneBy 	= $channelRepository->findOneBy([
		‘channelName‘ => ‘百度‘
	], [
		‘channelId‘ => ‘DESC‘
	]);
	
	$channelBy		= $channelRepository->findBy([
		‘channelName‘ => ‘阿裏‘
	], [
		‘channelId‘ => ‘DESC‘
	], $limit, $offset);
	
	/** @var $value Entity\Channel */
	foreach( $channelBy as $value )
	{
		echo $value->getChannelName();
	}
	
	echo $channelInfo->getChannelName();
	
	var_dumt( $channelInfo );
}

看上面一段代碼,分別寫了4個咱們比較常用的並且簡單的查詢方式,下面對這些方法進行一個簡單的解釋:

  • findAll 這個方法表示查詢這個實體的所有數據,也就是查詢相應表的所有數據,它返回的是一個多維數組 對象,可以通過 foreach 進行遍歷。
  • find 這個是按照ID查詢數據,返回一條結果,也就是一個 Channel 實體對象。
  • findOneBy 這個是根據條件查詢一條數據,可傳入兩個數組參數,第一個參數是簡單的查詢數組,可以寫多個它們是 AND 的關系。第二個參數是排序,上面我是channelId這個字段排序。
  • findBy 這個與上面那個findOneBy方法類似,前兩個參數都一樣,第三個參數表示查詢的數量,第四表參數表示從第幾行開始,返回的是多維數組對象,可以用foreach
    遍歷。

為什麽我要寫 /** @var $value Entity\Channel */ 這樣的一些註釋? 關於這點,我上篇文章已經講過了一些,可遠遠不只是那樣。這樣寫表示 $value 這個變量它指向了實體對象 Entity\Channel,因為查詢到結果後把結果設置到Entity\Channel這個實體上並且返回這個實體。然後咱們就可以使用這個實體裏的一些方法了,比如當你輸入 $value-> 的時候IDE應該提示這個實體上有哪些方法,然後你找到自己需要的照著敲就是了,這種寫法對編輯器是比較友好的。如果對返回的東西不熟悉的話使用var_dump() 這個函數把它打印出來看一下就知道了。

當然這裏只是最簡單的幾種用法如果想了解更多的用法可以去看 Doctrine\ORM\EntityRepository 這個類或繼續看我下面的講解。

往往有時間就上面這些查詢是無法滿我們的需求的,我們還需要更多的更加復雜的查詢功能,當然 Doctrine\ORM\EntityRepository 也提供了給開發人員自己定更復雜的語句的方法,比如:

  • createQueryBuilder
  • createNamedQuery
  • createResultSetMappingBuilder
  • createNativeNamedQuery

想知道更多可以去doctrine的官網查詢更多的相關資料(前提是你英文足夠好),當然它提供的這些方法我不建議在控制器上使用,這個時候我們最好把它單獨出來,減少代碼冗余提高復用性。這個時候我們就要使用到 Repository了,還記得上篇文章我對Repository的一些簡單的介紹嗎?什麽?不知道?回去把我寫的文章抄寫三遍...

擴展庫 Repository

咱們上一篇文章提到過Repository這個東西,如果有不清楚的可以點這裏《CodeIgniter Doctrine2基本使用(一)》 其實寫在Repository裏就是為了同樣的東西可以重復調用,提高代碼的復用性。

那天下面我就舉幾個例子吧,說這麽還不如直接看代碼。

	/**
     * 根據渠道tag查詢渠道信息
     * @param $tag
     * @return array
     */
    public function findChannelByTag( $tag )
    {
        return $this->_em->createQueryBuilder()
            ->select("c")
            ->from(‘Entity\Channel‘, ‘c‘)
            ->where(‘c.channelTag = :tag‘)            
            ->setParameter( ‘tag‘, $tag )
            ->getQuery()->getSingleResult();
    }

    /**
     * 分頁查找所有渠道
     * @param $page
     * @return mixed
     */
    public function findChannelPage( $page )
    {
        return $this->_em->createQueryBuilder()
            ->select("c")
            ->from(‘Entity\Channel‘, ‘c‘)
            ->orderBy(‘c.channelId‘, ‘desc‘)
            ->setMaxResults( 10 )
            ->setFirstResult( (($page -1 ) * 10 ) )
            ->getQuery()->getResult();
    }

    /**
     * 統計渠道數量
     * @return mixed
     */
    public function countChannelAll()
    {
        return $this->_em->createQueryBuilder()
            ->select("COUNT(c.channelId)")
            ->from(‘Entity\Channel‘, ‘c‘)
            ->getQuery()->getSingleScalarResult();
    }

如以上寫的這些方法,相信大多數人都能看得懂吧,基本每個方法都是這樣,更多的方法請查看Doctrine\ORM\QueryBuilder這個類。

  • createQueryBuilder() 創建一個查詢生成器
  • select() 需要查詢的字段,要註意的是這裏寫的字段是Entity\Channel裏面成員屬性所對應的字段,可以自定義查詢的字段。比如select(‘c.channelId,c.channelTag‘)它只會返回兩個字段數據(理論上是這樣)。如果有關聯查詢如innerJoin,leftJoin等關聯查詢那麽可以這樣寫select(‘c‘, ‘u‘)當然我這樣寫的比較少,基本都是使用 ManyToOne 、 OneToOne等形式來進行關聯查詢,這個我後面再講,當然也可以通過addSelect()這個方法來設置多個查詢實體
	$this->_em->createQueryBuilder()
    	->select(‘u‘)
     	->addSelect(‘c‘)
     	->from(‘Entity\User‘, ‘u‘)
     	->leftJoin(‘Entity\Channel‘, ‘c‘);
  • from() 這個無需多講就是查詢哪個實體,寫它的全名空間就好了,這裏傳兩個參數,第二個是別名
  • where() 這個也不用多解釋了,傳的查詢條件。可以寫多個比如where(‘c.channelTag = :tag AND c.channelId = :id‘)當然,如果不想這樣寫的話還可以通過andWhere()方法來設置條件。
  • orWhere() 與上面一樣,用過*CodeIgniter*框架的應該都知道吧,用法都差不多,得配合where()方法使用
$this_em->createQueryBuilder()
	->select(‘c‘)
	->from(‘Entity\Channel‘, ‘c‘)
	->where(‘c.channelId = :id‘)
	->orWhere(‘c.channelTag = :tag‘)

  • delete() 這個也很好理解,當然就是刪除啦如下列子
$this->_em->createQueryBuilder()
	->delete(‘Entity\Channel‘, ‘c‘)
    ->where(‘c.channelId = :id‘)
    ->setParameter(‘id‘, 1);
  • update() 這個就是更新數據的方法,需要配合下面的set()方法進行使用
$this->_em->createQueryBuilder()
	->update(‘Entity\Channel‘, ‘c‘)
	->set(‘c.channelName‘, "{$channelName}")
	->where(‘c.channelId = 1‘);
  • set() 這個也不用多講解了,配合上面的update()方法使用上面有例子
  • join()、innerJoin()、leftJoin() 關聯查詢這幾個方法的使用方式類型我下面就寫一個例子好了,對了這裏需要把Join這個類給加載進來,use Doctrine\ORM\Query\Expr\Join因為到現在為止我項目用得比較少,非常少基本都是用ManyToOne()做的聯查關於這個聯查我將在下一篇文章進行講解
$this_em->createQueryBuilder()
	->select(‘u‘)
	->from(‘Entity\User‘, ‘u‘)
	->innerJoin(‘Entity\Channel‘, ‘c‘, Join::WITH, ‘c.channelId = u.channelId‘);
  • setParameter() 這個也很好理解,就是設置前面的where條件的參數,上面的where方法我不是定義了:id:tag這兩個flag,這個方法就是對它們進行傳參的,這個上面也有例子,我就不再這裏湊字數了
  • setParameters() 這個方法跟上同那個傳參數的方法似,也比較常用,傳多個參數
	setParameters(new ArrayCollection(array(  
  		new Parameter(‘id‘, 1),  
     	new Parameter(‘tag‘, 2)  
 	)));
 	
  • groupBy()、addGroupBy() 這兩個也不用多說吧,就是goup by 怎麽整的好像在講mysql的用法似得
$this->_em->createQueryBuilder()
	->select(‘u‘)
	->from(‘Entity\User‘, ‘u‘)
	->groupBy(‘u.channelId‘);
  • having()、andHaving()、orHaving() having的用法跟一樣吧,這個用得比較少,因為性能比較低,不太喜歡在mysql上進行過多的運算
  • orderBy()、addOrderBy() 這兩個也不用多說了,就是排序嘛,不需要寫例子吧...上面有
  • getQuery() 這個時候還沒有生成結果集,只是做了一個查詢?
  • getResult() 返回多個結果集,最終返回的是一個多維數組對象,可以通過foreach進行遍歷,遍歷出來的value就是它的實體
  • getSingleScalarResult() 這個就是返回一個值吧,我只有統計的時候用過它
  • getSingleResult() 返回單個結果集,也就是一個實體對象
  • getDql() 返回生成的DQL語句?

上面寫了辣麽多,我怎麽感覺自己好像是在講怎麽操作數據庫呢?總結就是需要復用的稍微復雜一點的查詢就放在Repository裏吧,方便你我他。

好了Repository就暫時先講到這裏吧,下一節我們講 ManyToOne、OneToMany、OneToOne、ManyToMany的查詢。

原文目錄:https://lattecake.com/post/20045

CodeIgniter Doctrine2基本使用(二)(轉)