呼叫专家:用理论检索数据
在最近几篇关于Doctrine的博客文章中,我们已经演示了一些将Doctrine与symfony like集成的功能ob娱乐下载定制sfDoctrineGuardPlugin和新的管理生成器.本文略有不同,因为它将演示Doctrine中存在的一些功能,无论您是将其与symfony一起使用还是单独使用。ob娱乐下载
架构文件和数据fixture
首先,我们需要定义一个模式和一些用于测试查询的数据fixture。
模式文件
User: actAs: [Timestampable] columns: username: type: string(255) password: type: string(255) last_login: type: timestamp relations: Friends: class: User refClass: UserFriend local: user_id1 foreign: user_id2 Groups: class: Group refClass: UserGroup foreignAlias: Users Permissions: class: Permission refClass: UserPermission foreignAlias: Users Group: tableName: Groups columns: name: string(255) relations: Permissions: class: Permission refClass: GroupPermission foreignAlias: Groups权限:Groups权限:columns: name: string(255) Phonenumber: columns: user_id: integer Phonenumber: string(55) relations: User: foreignAlias: Phonenumbers onDelete: CASCADE Profile: columns: user_id: integer first_name: string(255) last_name: string(255) email_address: string(255) relations: User: foreignType: one onDelete: CASCADE UserFriend: columns: user_id1: type: integer primary: true user_id2: type: integer primary: true relations: User1: class: User local: user_id1 foreignAlias: UserFriends onDelete:CASCADE User2: class: User local: user_id2 foreignAlias: UserFriends onDelete: CASCADE UserGroup: columns: user_id: type: integer primary: true group_id: type: integer primary: true relations: User: foreignAlias: UserGroups onDelete: CASCADE Group: foreignAlias: UserGroups onDelete: CASCADE UserPermission: columns: user_id: type: integer primary: true permission_id: type: integer primary: true relations: User: foreignAlias: UserPermissions onDelete: CASCADE Permission: columns: user_id: type: integer primary: trueUserPermissions onDelete: CASCADE GroupPermission: columns: group_id: type: integer primary: true permission_id: type: integer primary: true relations: Group: foreignAlias: GroupPermissions onDelete: CASCADE Permission: foreignAlias: GroupPermissions onDelete: CASCADE BlogPost: actAs: Timestampable: Sluggable: fields: [title] columns: user_id: integer title: string(255) body: clob relations: Author: class: User foreignAlias: BlogPosts onDelete: CASCADE Tags: class: Tag refClass:BlogPostTag foreignAlias: BlogPosts Comments: class: Comment refClass: BlogPostComment foreignAlias: BlogPostTags: columns: name: string(255) Comment: columns: title: string(255) body: clob Page: actAs: Timestampable: Sluggable: fields: [title] columns: title: string(255) body: clob BlogPostTag: columns: blog_post_id: type: integer primary: true tag_id: type: integer primary: true relations: BlogPost: foreignAlias: BlogPostTags onDelete: CASCADE Tag: foreignAlias: BlogPostTags onDelete:CASCADE BlogPostComment: columns: blog_post_id: type: integer primary: true comment_id: type: integer primary: true relations: BlogPost: foreignAlias: BlogPostComments onDelete: CASCADE Comment: foreignAlias: BlogPostComments onDelete: CASCADE
数据设备
用户:jwage:用户名:jwage密码:changeme配置文件:first_name: Jonathan last_name: Wage email_address: jonwage@gmail.com组:[管理员]好友:[fabpot, joeblow] Phonenumbers: Phonenumber_1: phonenumber: 6155139185 fabpot:用户名:fabpot密码:changeme配置文件:first_name: Fabien last_name: Potencier email_address: fabien.potencier@symfony-project.com组:[ContentEditor]好友:[jwage] joeblow:用户名:joeblow密ob娱乐下载码:changeme配置文件:first_name: Joe last_name:Blow email_address: jowblow@gmail.com组:[已注册]好友:[jwage, fabpot]组:管理员:名称:管理员权限:[EditPages, EditBlog, EditUsers, EditPages, Frontend]博主:名称:博主权限:[EditBlog, Frontend]主持人:名称:主持人权限:[EditUsers, EditComments, Frontend] ContentEditor:名称:内容编辑权限:[EditPages, EditBlog, Frontend]已注册:名称:已注册权限:[fronttend]权限:EditPages:名称:名称:编辑页面EditBlog:名称:编辑博客EditUsers:名称:编辑用户EditPages:名称:编辑页面EditComments:名称:编辑评论fronttend:名称:前端BlogPost: BlogPost_1:作者:jwage标题:示例博客文章正文:这是一个示例博客文章标签:[symfony, doctrine, php, mvc]评论:Comment_1:标题:这是一个糟糕的博客文章正文:是的,这确实是一个可怕的博客文章Comment_2:标题:我认为这是一个很棒的博客文章正文:这是一个ob娱乐下载很棒的博客文章,你在说什么?!标签:syob娱乐下载mfony: name: symfony php: name: php doctrine: name: doctrine mvc: name: mvc Page: home: title: home正文:这是主页的内容about: title:关于正文:这是关于页面的内容faq: title: F.A.Q.正文:这是常见问题页面的内容
选择查询
DBMS功能
首先,我们将演示如何在查询中使用DBMS函数。例如,您可能希望检索所有博客文章,并计算每个博客文章的评论数量。
美元的问= Doctrine_Query::创建()->选择('p.*, COUNT(c.id) as num_comments')->从(“BlogPost p”)->leftJoin(“p.Comments c”)->groupBy(“p.id”);美元的结果=美元的问->执行();回声美元的结果[0][“num_comments”];
您可以使用任何函数组合,并将它们嵌套到您想要的深度。
多个连接
Doctrine使从多个表中检索数据变得容易。在本例中,我们可以检索用户拥有的所有权限,甚至是通过其分配的组获得的权限。
美元的问= Doctrine_Query::创建()->从(“用户u ')->leftJoin(“u.Permissions p”)->leftJoin(“u.Groups g”)->leftJoin(“g.Permissions p2”)->在哪里(“u.id = ?”,1);$ user=美元的问->fetchOne();
现在我们可以建立一个Doctrine_Collection
用户拥有的所有权限。
美元的权限=新Doctrine_Collection(“许可”);foreach($ user[“组织”]作为美元集团){foreach(美元集团[“权限”]作为美元的许可){美元的权限[]=美元的许可;}}foreach($ user[“权限”]作为美元的许可){美元的权限[]=美元的许可;}
在博客应用程序中,通常需要检索博客
与相关的作者
,评论
而且标签
全部在一个查询中。使用Doctrine,这就像我键入前面的句子一样简单。
美元的问= Doctrine_Query::创建()->从(“BlogPost p”)->leftJoin(“p.Author“)->leftJoin(“p.Comments c”)->leftJoin(“p.Tags t”)->在哪里('p.id = ?',1);
子查询
我们也可以取回相同的东西许可
Doctrine_Collection
直接从Doctrine使用子查询来知道哪个许可
要检索的记录。
userId美元=1;美元的问= Doctrine_Query::创建()->从(“许可p”);q2美元=美元的问->createSubquery()->选择(“p2.permission_id”)->从(“UserPermission p2”)->在哪里(p2。User_id = ?');第三季度美元=美元的问->createSubquery()->选择(“p3.id”)->从(“许可p3”)->leftJoin(p3。GroupPermissions全科医生”)->leftJoin(”医生。g组的)->leftJoin(“g.Users u ')->在哪里(“u.id = ?”);美元的问->在哪里('p.id IN ('.q2美元->getDql().“)”)->orWhere('p.id IN ('.第三季度美元->getDql().“)”);美元的权限=美元的问->执行(数组(userId美元,userId美元));
速记左连接
Doctrine的一个非常方便的特性是能够以速记语法指定连接。这将大大减少一个查询可能占用的代码行数。中一起更改模型即可从()
部件来指定连接,它们默认与using相同leftJoin ()
.
美元的问= Doctrine_Query::创建()->从('用户u, u. profile p, u. groups g');
上面的代码等于做:
美元的问= Doctrine_Query::创建()->从(“用户u ')->leftJoin(“u.Profile p”)->leftJoin(“u.Groups g”);
删除和更新查询
Doctrine_Query
可以用来指定更新
而且删除
查询update ()
或delete ()
功能。这里有一些例子。
删除查询
在本例中,我们将通过用户名删除用户。
Doctrine_Query::创建()->删除()->从(“用户u ')->在哪里(“u.username = ?”,“jwage”)->执行();
更新查询
在这个示例查询中,我们将更新用户密码。
Doctrine_Query::创建()->更新(“用户u ')->集(“u.password”,“?”,“newpassword”)->在哪里(“u.username = ?”,“jwage”)->执行();
的设置()
函数接受三个参数。第一个是您想要设置的字段的名称,第二个是传递给PDO的部分,第三个是参数/值。
另一个例子是用dbms函数设置时间戳字段。我们不用第三个参数,因为我们想现在()
不受影响地传给PDO
Doctrine_Query::创建()->更新(“用户u ')->集(“u.last_login”,“现在()”)->在哪里(“u.username = ?”,“jwage”)->执行();
使用DQL更新和删除的好处是,它只需要一个查询就可以完成您想要的操作。如果使用对象,则必须首先检索对象,然后更新或删除对象,这意味着两个单独的查询。
手动编写DQL
对于SQL爱好者,我们没有忘记您。您可以选择手动编写DQL查询并将其解析为Doctrine_Query
实例或只执行它们。
dql美元=FROM User u, u. phonenumbers p;美元的问= Doctrine_Query::创建()->parseQuery(dql美元);
方法来执行它们查询()
的方法Doctrine_Query
.
dql美元=FROM User u, u. phonenumbers p;美元的问= Doctrine_Query::创建()->查询(dql美元);
执行查询
在上述所有示例中,我们向您展示了如何创建查询,但是如何执行它们呢?Doctrine提供了几种不同的方法来执行查询,以及几种不同的方法来填充数据。它可以将数据水合为对象,php数组这比使用对象要快得多或者它可以简单地跳过水合过程。
数组水化
下面是一些如何执行数组水合作用的示例。
美元的结果=美元的问->执行(美元的参数,原则::HYDRATE_ARRAY);
一个方便的方法被称为fetchArray ()
.
美元的结果=美元的问->fetchArray(美元的参数);
记录水化
美元的结果=美元的问->执行(美元的参数,原则::HYDRATE_RECORD);
Record hydration是默认值,因此如果您愿意,可以省略第二个参数。
没有水
我们可以简单地完全跳过水化过程,并返回PDO给我们的东西。这只在极少数情况下有用,比如当您只有一行和一列数据时。数据作为带有数字键的数组返回,因此在任何其他情况下都不是很有用。
美元的结果=美元的问->执行(美元的参数,原则::HYDRATE_NONE);
获取一条记录
您可以使用fetchOne ()
方便的方法,自动添加一个限制,并返回一个结果,而不是多个。
美元的结果=美元的问->fetchOne(美元的参数,原则::HYDRATE_ARRAY);
这就是今天的全部内容。在下一篇文章中,我们将演示如何使用在关系中定义的对象以及在上述查询中检索的对象。
评论
评论截止。
为了确保评论保持相关性,旧帖子将被关闭。
为什么Fabien在《Propel》中发布了例子,但我们可以在《Doctrine》中看到越来越多的伟大案例。
当Zaninotto在DBFinder工作时,他谈到了性能,他确实说过PROPEL 1.3比任何人都快。
今天,哪个更快?
我们可以比较吗?
另一件事,就是必须学习两种类型的图式(憎恶和教义),可以更简单吗?
请,下次乔纳森,你能告诉我们如何把主要数据放在DB中,不是fixture,而是真实的数据,比如第一个用户或行列表,以填充一个DB以供实际使用。
谢谢
我的下一篇文章将继续讨论这个模式,并向您展示如何使用php代码处理对象和关系。
Doctrine_Query: create ()
- > delete ()
u - >(“用户”)
——> (u。Username = ?', 'jwage')
- > execute ();
不像我们已经写了更新:
Doctrine_Query: create ()
u - > delete(“用户”)
——> (u。Username = ?', 'jwage')
- > execute ();
特别是文章嵌套的形式等,形式书没有完成许多失踪的章节,但大部分的工作,可以进入书似乎出现在这个博客上?
并不是要批评that’所做的努力,这绝对是有用的信息,我只是希望它能被更多的人看到。
大卫
如果能有一个简短的描述,水合作用到底指的是什么,那就太好了。