CodeIgniter Doctrine2基本使用(二)(轉)
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基本使用(二)(轉)