CodeIgniter Doctrine2基本使用(二)

继上次写的一篇文章《CodeIgniter Doctrine2基本使用(一)》写到操作实体的之通过Channel这个实体向数据库表插入一条数据,那么今天要写的就是通过实体获取数据,当然查询这一块比较多,可能也会分好几篇讲。

Doctrine2 简单的用法

操作实体

上一篇文章讲到插入一条数据,插入很简单只要设置实体的成员属性的值就能完成,当然如果有多个实体的话可以多次使用 $this->em->persist();这个方法。然后只要再执行一次 $this->em->flush(); 这个方法就行了,它会进行一次数据库连接,然后执行上面实体生成的SQL语句。

简单查询操作

通过Entity查询的方式 有很多,我们先从最简单的开始,还是以Entity\Channel这个实体为例,以下面一段代码为例:


  1. public function index()
  2. {
  3. $id = 1;
  4. $limit = 20;
  5. $offset = 1;
  6. /**
  7. * @var $channelInfo Entity\Channel
  8. * @var $channelOneBy Entity\Channel
  9. */
  10. $channelRepository = $this->em->getRepository('Entity\Channel');
  11. $channelAll = $channelRepository->findAll();
  12. $channelInfo = $channelRepository->find( $id );
  13. $channelOneBy = $channelRepository->findOneBy([
  14. 'channelName' => '百度'
  15. ], [
  16. 'channelId' => 'DESC'
  17. ]);
  18. $channelBy = $channelRepository->findBy([
  19. 'channelName' => '阿里'
  20. ], [
  21. 'channelId' => 'DESC'
  22. ], $limit, $offset);
  23. /** @var $value Entity\Channel */
  24. foreach( $channelBy as $value )
  25. {
  26. echo $value->getChannelName();
  27. }
  28. echo $channelInfo->getChannelName();
  29. var_dumt( $channelInfo );
  30. }

看上面一段代码,分别写了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里就是为了同样的东西可以重复调用,提高代码的复用性。

那天下面我就举几个例子吧,说这么还不如直接看代码。

  1. /**
  2. * 根据渠道tag查询渠道信息
  3. * @param $tag
  4. * @return array
  5. */
  6. public function findChannelByTag( $tag )
  7. {
  8. return $this->_em->createQueryBuilder()
  9. ->select("c")
  10. ->from('Entity\Channel', 'c')
  11. ->where('c.channelTag = :tag')
  12. ->setParameter( 'tag', $tag )
  13. ->getQuery()->getSingleResult();
  14. }
  15. /**
  16. * 分页查找所有渠道
  17. * @param $page
  18. * @return mixed
  19. */
  20. public function findChannelPage( $page )
  21. {
  22. return $this->_em->createQueryBuilder()
  23. ->select("c")
  24. ->from('Entity\Channel', 'c')
  25. ->orderBy('c.channelId', 'desc')
  26. ->setMaxResults( 10 )
  27. ->setFirstResult( (($page -1 ) * 10 ) )
  28. ->getQuery()->getResult();
  29. }
  30. /**
  31. * 统计渠道数量
  32. * @return mixed
  33. */
  34. public function countChannelAll()
  35. {
  36. return $this->_em->createQueryBuilder()
  37. ->select("COUNT(c.channelId)")
  38. ->from('Entity\Channel', 'c')
  39. ->getQuery()->getSingleScalarResult();
  40. }

如以上写的这些方法,相信大多数人都能看得懂吧,基本每个方法都是这样,更多的方法请查看Doctrine\ORM\QueryBuilder这个类。

  • createQueryBuilder() 创建一个查询生成器
  • select() 需要查询的字段,要注意的是这里写的字段是Entity\Channel里面成员属性所对应的字段,可以自定义查询的字段。比如select('c.channelId,c.channelTag')它只会返回两个字段数据(理论上是这样)。如果有关联查询如innerJoin,leftJoin等关联查询那么可以这样写select('c', 'u')当然我这样写的比较少,基本都是使用 ManyToOne 、 OneToOne等形式来进行关联查询,这个我后面再讲,当然也可以通过addSelect()这个方法来设置多个查询实体
  1. $this->_em->createQueryBuilder()
  2. ->select('u')
  3. ->addSelect('c')
  4. ->from('Entity\User', 'u')
  5. ->leftJoin('Entity\Channel', 'c');
  • from() 这个无需多讲就是查询哪个实体,写它的全名空间就好了,这里传两个参数,第二个是别名
  • where() 这个也不用多解释了,传的查询条件。可以写多个比如where('c.channelTag = :tag AND c.channelId = :id')当然,如果不想这样写的话还可以通过andWhere()方法来设置条件。
  • orWhere() 与上面一样,用过*CodeIgniter*框架的应该都知道吧,用法都差不多,得配合where()方法使用
  1. $this_em->createQueryBuilder()
  2. ->select('c')
  3. ->from('Entity\Channel', 'c')
  4. ->where('c.channelId = :id')
  5. ->orWhere('c.channelTag = :tag')
  • delete() 这个也很好理解,当然就是删除啦如下列子
  1. $this->_em->createQueryBuilder()
  2. ->delete('Entity\Channel', 'c')
  3. ->where('c.channelId = :id')
  4. ->setParameter('id', 1);
  • update() 这个就是更新数据的方法,需要配合下面的set()方法进行使用
  1. $this->_em->createQueryBuilder()
  2. ->update('Entity\Channel', 'c')
  3. ->set('c.channelName', "{$channelName}")
  4. ->where('c.channelId = 1');
  • set() 这个也不用多讲解了,配合上面的update()方法使用上面有例子
  • join()、innerJoin()、leftJoin() 关联查询这几个方法的使用方式类型我下面就写一个例子好了,对了这里需要把Join这个类给加载进来,use Doctrine\ORM\Query\Expr\Join因为到现在为止我项目用得比较少,非常少基本都是用ManyToOne()做的联查关于这个联查我将在下一篇文章进行讲解
  1. $this_em->createQueryBuilder()
  2. ->select('u')
  3. ->from('Entity\User', 'u')
  4. ->innerJoin('Entity\Channel', 'c', Join::WITH, 'c.channelId = u.channelId');
  • setParameter() 这个也很好理解,就是设置前面的where条件的参数,上面的where方法我不是定义了:id:tag这两个flag,这个方法就是对它们进行传参的,这个上面也有例子,我就不再这里凑字数了
  • setParameters() 这个方法跟上同那个传参数的方法似,也比较常用,传多个参数
  1. setParameters(new ArrayCollection(array(
  2. new Parameter('id', 1),
  3. new Parameter('tag', 2)
  4. )));
  • groupBy()、addGroupBy() 这两个也不用多说吧,就是goup by 怎么整的好像在讲mysql的用法似得
  1. $this->_em->createQueryBuilder()
  2. ->select('u')
  3. ->from('Entity\User', 'u')
  4. ->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基本使用(二)(转)的更多相关文章

  1. CodeIgniter Doctrine2基本使用(一)(转)

    CodeIgniter Doctrine2基本使用(一) 之前写了一篇文章叫作<CodeIgniter 3.0整合Doctrine2>里面介绍了一些简单的Doctrine2的用法,当然我也 ...

  2. Debian中CodeIgniter+nginx+MariaDB+phpMyAdmin配置

    本文不讲述软件安装过程,记述本人在Debia中配置CodeIgniter时遇到的问题及解决方法,希望能够为有需要的人提供帮助. 一.Debian版本及所需的软件 Debian 9.8 stretch ...

  3. 使用 CodeIgniter 框架快速开发 PHP 应用(二)

    原文:使用 CodeIgniter 框架快速开发 PHP 应用(二) 二分钟: 建立一个 CodeIgniter 网站用CI建一个网站很容易. 这一章很短,解释了用CI制作网站时发生了些什么,哪些文件 ...

  4. 微信支付Native扫码支付模式二之CodeIgniter集成篇

    CI:3.0.5 微信支付API类库来自:https://github.com/zhangv/wechat-pay 请先看一眼官方场景及支付时序图:https://pay.weixin.qq.com/ ...

  5. CodeIgniter框架中关于URL重写(index.php)的二三事

    最近,在做自己的个人网站时,采用了轻量级的php框架CodeIgniter.乍一看上去,代码清晰简洁,MVC模型非常容易维护.开发时我采用的工具是Netbeans IDE 8.0,当然,本文的内容和开 ...

  6. CodeIgniter学习笔记二:CI中的query_builder(AR)、连贯操作

    一.开启query_builder 在application\config\database.php中添加如下代码(默认已开启): $query_builder = TRUE; 二.查询数据 //ge ...

  7. 学习CodeIgniter框架之旅(二)继承自定义类

    在很多情况下,框架类并不能满足项目的需求,这时候需要程序要自定义一些类,比如说基类等等,对比了TP框架,CI框架目前好像还没加入命名空间,这点TP做得比较好,不用特殊的处理就可以随便继承自定义的类,只 ...

  8. ***CodeIgniter集成微信支付(转)

    微信支付Native扫码支付模式二之CodeIgniter集成篇  http://www.cnblogs.com/24la/p/wxpay-native-qrcode-codeigniter.html ...

  9. Codeigniter的Redis使用

    1. ./config/redis.php: <?php $config['redis_host'] = '127.0.0.1'; $config['redis_port'] = '6379'; ...

随机推荐

  1. Flutter完整开发实战详解

    Flutter完整开发实战详解(一.Dart语言和Flutter基础) Flutter完整开发实战详解(二. 快速开发实战篇) Flutter完整开发实战详解(三. 打包与填坑篇)

  2. Android onActivityResult和setResult

    如果你想在Activity中得到新打开Activity关闭后返回的数据,你需要使用系统提供的startActivityForResult(Intent intent,int requestCode)方 ...

  3. ShowDoc

    ShowDoc 摘自ShowDoc 每当接手一个他人开发好的模块或者项目,看着那些没有写注释的代码,我们都无比抓狂.文档呢?!文档呢?!Show me the doc !! 程序员都很希望别人能写技术 ...

  4. [swift] Async

    Async https://github.com/duemunk/Async Syntactic sugar in Swift for asynchronous dispatches in Grand ...

  5. [UI] 精美UI界面欣赏[7]

    精美UI界面欣赏[7] 视频地址: http://v.youku.com/v_show/id_XOTM0MDUzNTg0.html UI介绍地址: http://www.zhihu.com/quest ...

  6. 申请Let’s Encrypt永久免费SSL证书过程教程及常见问题

    配置证书https://easy.zhetao.com/   虽然目前Let’s Encrypt免费SSL证书默认是90天有效期,但是我们也可以到期自动续约,不影响我们的尝试和使用,为了考虑到文章的真 ...

  7. 《C++ Primer Plus》读书笔记之六—函数探幽

    第八章 函数探幽 1.常规函数与内联函数的主要区别不在于编写方式,而在于C++编译器如何将它们组合到程序中. 2.常规函数调用使程序跳到另外一个地址(函数地址),并在函数结束时返回,更详细的的实现过程 ...

  8. vmware查看HBA卡、网卡驱动、firmware版本信息

    在 ESXi 5.x 中,swfw.sh 命令随 vm-support 支持包收集工具一起提供.swfw.sh 命令可用来识别连接到主机的硬件的固件和驱动程序版本.要运行此命令,请使用该路径: # / ...

  9. Sublime Text3 使用总结

    一.简介: Sublime Text 3是一款强大而精巧的文本编辑器 [点击下载].它的界面友好.功能非凡.性能极佳可令代码高亮.语法提示.自动完成更重要的是,它支持众多插件扩展——锦上添花.强之又强 ...

  10. SpringBoot整合Redis初实践

    Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理. 有时,为了提升整个网站的性能,在开发时会将经常访问的数据进行缓存,这样在调用这个数据接口时,可以提 ...