<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>4's symfony blog &#187; propel</title>
	<atom:link href="http://www.foolbirds.com/t/propel/feed" rel="self" type="application/rss+xml" />
	<link>http://www.foolbirds.com</link>
	<description>all about symfony</description>
	<lastBuildDate>Tue, 17 Aug 2010 01:22:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Add table prefix  in symfony－在symfony中使用表前缀</title>
		<link>http://www.foolbirds.com/add-table-prefix-in-symfony.html</link>
		<comments>http://www.foolbirds.com/add-table-prefix-in-symfony.html#comments</comments>
		<pubDate>Tue, 24 Mar 2009 08:51:30 +0000</pubDate>
		<dc:creator>maker</dc:creator>
				<category><![CDATA[symfony]]></category>
		<category><![CDATA[prefix]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[表前缀]]></category>

		<guid isPermaLink="false">http://www.foolbirds.com/?p=675</guid>
		<description><![CDATA[The propel 1.3 is support table prefixes.
In your config/propel.ini add the following:
propel.tablePrefix=prefix_
then run the propel:build-all-load task.
Done!
网上找不到任何关于symfony或者propel支持表前缀的资料，只在propel1.3的修改历史中发现了1.3是支持表前缀的，但文档却没有更新相关内容，无奈之下只能查看源码，最后终于让我找到了。
补遗：还有一种方法我觉得是更加可靠的，那就是手动修改schema.yml中的全部数据库名，手动加前缀，同时强制设定表的phpName保证其不会随着表名一同变化,然后重新./symfony propel:build-all
symfony数据表关联详解(for propel)关于数据查询的使用使用SYMFONY Filter 过滤URL仿symfony机制实现不用require或者include来实例化类symfony1.4 DateTime对于PHP低版本的兼容问题如何在fixtures.yml写循环添加数据symfony 1.4 数据库 utf8设置symfony cheat sheetCheat Sheets!如何使用swift发送邮件]]></description>
			<content:encoded><![CDATA[<p>The propel 1.3 is support table prefixes.</p>
<p>In your config/propel.ini add the following:</p>
<p><code>propel.tablePrefix=prefix_</code></p>
<p>then run the propel:build-all-load task.</p>
<p>Done!</p>
<p>网上找不到任何关于symfony或者propel支持表前缀的资料，只在propel1.3的修改历史中发现了1.3是支持表前缀的，但文档却没有更新相关内容，无奈之下只能查看源码，最后终于让我找到了。</p>
<p>补遗：还有一种方法我觉得是更加可靠的，那就是手动修改schema.yml中的全部数据库名，手动加前缀，同时强制设定表的phpName保证其不会随着表名一同变化,然后重新./symfony propel:build-all</p>
<ul class="related_post"><li><a href="http://www.foolbirds.com/symfony-references-with-propel.html" title="symfony数据表关联详解(for propel)">symfony数据表关联详解(for propel)</a></li><li><a href="http://www.foolbirds.com/use-orm-propel.html" title="关于数据查询的使用">关于数据查询的使用</a></li><li><a href="http://www.foolbirds.com/use_symfony_filter_to_filteredurl.html" title="使用SYMFONY Filter 过滤URL">使用SYMFONY Filter 过滤URL</a></li><li><a href="http://www.foolbirds.com/%e4%bb%bfsymfony%e6%9c%ba%e5%88%b6%e5%ae%9e%e7%8e%b0%e4%b8%8d%e7%94%a8require%e6%88%96%e8%80%85include%e6%9d%a5%e5%ae%9e%e4%be%8b%e5%8c%96%e7%b1%bb.html" title="仿symfony机制实现不用require或者include来实例化类">仿symfony机制实现不用require或者include来实例化类</a></li><li><a href="http://www.foolbirds.com/use-datetime-in-php5-1-x-with-symfony.html" title="symfony1.4 DateTime对于PHP低版本的兼容问题">symfony1.4 DateTime对于PHP低版本的兼容问题</a></li><li><a href="http://www.foolbirds.com/%e5%a6%82%e4%bd%95%e5%9c%a8fixtures-yml%e5%86%99%e5%be%aa%e7%8e%af%e6%b7%bb%e5%8a%a0%e6%95%b0%e6%8d%ae.html" title="如何在fixtures.yml写循环添加数据">如何在fixtures.yml写循环添加数据</a></li><li><a href="http://www.foolbirds.com/symfony-1-4-database-utf8.html" title="symfony 1.4 数据库 utf8设置">symfony 1.4 数据库 utf8设置</a></li><li><a href="http://www.foolbirds.com/symfony-cheat-sheet.html" title="symfony cheat sheet">symfony cheat sheet</a></li><li><a href="http://www.foolbirds.com/cheat-sheets.html" title="Cheat Sheets!">Cheat Sheets!</a></li><li><a href="http://www.foolbirds.com/how-to-use-swift-to-send-mail-in-symfon.html" title="如何使用swift发送邮件">如何使用swift发送邮件</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.foolbirds.com/add-table-prefix-in-symfony.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>symfony数据表关联详解(for propel)</title>
		<link>http://www.foolbirds.com/symfony-references-with-propel.html</link>
		<comments>http://www.foolbirds.com/symfony-references-with-propel.html#comments</comments>
		<pubDate>Fri, 27 Feb 2009 08:52:29 +0000</pubDate>
		<dc:creator>maker</dc:creator>
				<category><![CDATA[symfony]]></category>
		<category><![CDATA[propel]]></category>
		<category><![CDATA[一对多]]></category>
		<category><![CDATA[关联]]></category>
		<category><![CDATA[多对多]]></category>

		<guid isPermaLink="false">http://www.foolbirds.com/?p=554</guid>
		<description><![CDATA[上周又接到一个研究性质的任务，最近比较忙碌，所以这两天才开始分析代码，由于数据表相关的内容会比较多，所以本文将分成以下几部分。

商店的数据关系
一对多(hasMany)关系的处理
从属(belongsTo)关系的处理
多对多(manyToMany)关系的处理
一对一(oneToOne)关系的处理
总结

本文使用的测试环境如下:

php 5.2.6
apache 2.2.8
mysql 5.0.67
symfony 1.2.4-DEV

一. 商店的数据关系
我们用一个例子来对symfony中的表关联进行分析，我们假设商店有如下的数据关系。
图1.1

这里涉及到4类对象实体，分别是City（城市），Shop（商店），Shopinfo（商店信息）， Tag（标签）。其中又涉及到了三种数据关系，一个城市可以有多家商店（一对多），一个商店拥有一个商店信息（一对一），一个商店可以拥有很多特点（多对多），这里我们用Tag来表示特点（特性）。
首先我们设计数据库结构config/schema.yml
图1.2

然后我们自动生成相关的库文件
$ ./symfony propel:build-all
首先我们来分析City和Shop之间的一对多/从属关系.
二.一对多(hasMany)关系的处理
我们先来看propel自动生成的BaseCity对象
图1.3

其他和关联没有关系的表这里不做过多描述, 我们重点介绍下面几个方法.
clearShops();
清空当前已经获得的关联商店， 实际上这个清空操作并没有真正意义上的进行清空或者删除，只是清空了当前取得的关联对象集合.
示例2.1(通过测试):
$mc = new Shop;
$mc-&#62;setName('MC in Beijing');
$city-&#62;addShop($mc);
$city-&#62;initShops();
$wc = new Shop;
$wc-&#62;setName('WC in Beijing');
$city-&#62;addShop($wc);
$city-&#62;save();
initShops();
清空当前已经获得的关联商店， 实际上这个清空操作并没有真正意义上的进行清空或者删除，只是清空了当前取得的关联对象集合. 该方法与clearShops()类似, 但该方法将Shop集合初始化为一个空的数组而clearShops()将Shop集合设置为null.
示例2.2(通过测试):
$mc = new Shop;
$mc-&#62;setName('MC in Beijing');
$city-&#62;addShop($mc);
$city-&#62;initShops();
$wc = new Shop;
$wc-&#62;setName('WC in Beijing');
$city-&#62;addShop($wc);
$city-&#62;save();
getShops($criteria, $con);
根据条件$criteria返回city下相关联的shop对象集合.
示例2.3(通过测试):
//我们用下面代码获得某城市下全部的KFC(肯德基)店铺
$c = new Criteria;
$c-&#62;add(ShopPeer::NAME, '%KFC%', Criteris::LIKE);
foreach($city-&#62;getShops($c) as $shop){
echo $shop-&#62;getId();
}
countShops($criteria, $con);
countShops()方法用来返回满组织定条件的关联Shop个数
示例2.4(通过测试):
//我们用下面代码获得某城市下全部的KFC(肯德基)的个数
$c = new Criteria;
$c-&#62;add(ShopPeer::NAME, '%KFC%', Criteris::LIKE);
echo $city-&#62;getName() . ' has ' . [...]]]></description>
			<content:encoded><![CDATA[<p>上周又接到一个研究性质的任务，最近比较忙碌，所以这两天才开始分析代码，由于数据表相关的内容会比较多，所以本文将分成以下几部分。</p>
<ol>
<li><a href="#part-shop-references">商店的数据关系</a></li>
<li><a href="#part-has-many">一对多(hasMany)关系的处理</a></li>
<li><a href="#part-belongs-to">从属(belongsTo)关系的处理</a></li>
<li><a href="#part-many-to-many">多对多(manyToMany)关系的处理</a></li>
<li><a href="#part-one-to-one">一对一(oneToOne)关系的处理</a></li>
<li><a href="#part-end">总结</a></li>
</ol>
<p>本文使用的测试环境如下:</p>
<ul>
<li>php 5.2.6</li>
<li>apache 2.2.8</li>
<li>mysql 5.0.67</li>
<li>symfony 1.2.4-DEV</li>
</ul>
<p><span style="color: #008080;"><strong><a name="part-shop-references">一. 商店的数据关系</a></strong></span></p>
<p>我们用一个例子来对symfony中的表关联进行分析，我们假设商店有如下的数据关系。</p>
<p><a name="pic-1-1">图1.1</a></p>
<p><img class="aligncenter size-full wp-image-611" title="2009-02-26-104551_294x299_scrot" src="http://www.foolbirds.com/wp-content/uploads/2009/02/2009-02-26-104551_294x299_scrot.png" alt="2009-02-26-104551_294x299_scrot" width="294" height="299" /></p>
<p>这里涉及到4类对象实体，分别是City（城市），Shop（商店），Shopinfo（商店信息）， Tag（标签）。其中又涉及到了三种数据关系，一个城市可以有多家商店（一对多），一个商店拥有一个商店信息（一对一），一个商店可以拥有很多特点（多对多），这里我们用Tag来表示特点（特性）。</p>
<p>首先我们设计数据库结构config/schema.yml</p>
<p><a name="pic-1-2">图1.2</a></p>
<p><img class="aligncenter size-full wp-image-610" title="2009-02-26-100743_401x689_scrot" src="http://www.foolbirds.com/wp-content/uploads/2009/02/2009-02-26-100743_401x689_scrot.png" alt="2009-02-26-100743_401x689_scrot" width="401" height="689" /></p>
<p>然后我们自动生成相关的库文件</p>
<p><code>$ ./symfony propel:build-all</code></p>
<p>首先我们来分析City和Shop之间的一对多/从属关系.</p>
<p><span style="color: #008080;"><strong><a name="part-has-many">二.一对多(hasMany)关系的处理</a></strong></span></p>
<p>我们先来看propel自动生成的BaseCity对象</p>
<p><a name="pic-1-3">图1.3</a></p>
<p><img class="aligncenter size-full wp-image-580" title="2009-02-25-103053_396x688_scrot" src="http://www.foolbirds.com/wp-content/uploads/2009/02/2009-02-25-103053_396x688_scrot.png" alt="2009-02-25-103053_396x688_scrot" width="396" height="688" /></p>
<p>其他和关联没有关系的表这里不做过多描述, 我们重点介绍下面几个方法.</p>
<p style="padding-left: 30px;"><strong>clearShops();</strong></p>
<p style="padding-left: 60px;">清空当前已经获得的关联商店， 实际上这个清空操作并没有真正意义上的进行清空或者删除，只是清空了当前取得的关联对象集合.</p>
<p style="padding-left: 60px;"><a name="ex-2-1">示例2.1</a>(<span style="color: #00ff00;">通过测试</span>):</p>
<p style="padding-left: 60px;"><code>$mc = new Shop;<br />
$mc-&gt;setName('MC in Beijing');<br />
$city-&gt;addShop($mc);<br />
$city-&gt;initShops();<br />
$wc = new Shop;<br />
$wc-&gt;setName('WC in Beijing');<br />
$city-&gt;addShop($wc);<br />
$city-&gt;save();</code></p>
<p style="padding-left: 30px;"><strong>initShops();</strong></p>
<p style="padding-left: 60px;">清空当前已经获得的关联商店， 实际上这个清空操作并没有真正意义上的进行清空或者删除，只是清空了当前取得的关联对象集合. 该方法与clearShops()类似, 但该方法将Shop集合初始化为一个空的数组而clearShops()将Shop集合设置为null.</p>
<p style="padding-left: 60px;"><a name="ex-2-2">示例2.2</a>(<span style="color: #00ff00;">通过测试</span>):</p>
<p style="padding-left: 60px;"><code>$mc = new Shop;<br />
$mc-&gt;setName('MC in Beijing');<br />
$city-&gt;addShop($mc);<br />
$city-&gt;initShops();<br />
$wc = new Shop;<br />
$wc-&gt;setName('WC in Beijing');<br />
$city-&gt;addShop($wc);<br />
$city-&gt;save();</code></p>
<p style="padding-left: 30px;"><strong>getShops($criteria, $con);</strong></p>
<p style="padding-left: 60px;">根据条件$criteria返回city下相关联的shop对象集合.</p>
<p style="padding-left: 60px;"><a name="ex-2-3">示例2.3</a>(<span style="color: #00ff00;">通过测试</span>):</p>
<p style="padding-left: 60px;"><code>//我们用下面代码获得某城市下全部的KFC(肯德基)店铺<br />
$c = new Criteria;<br />
$c-&gt;add(ShopPeer::NAME, '%KFC%', Criteris::LIKE);<br />
foreach($city-&gt;getShops($c) as $shop){<br />
echo $shop-&gt;getId();<br />
}</code></p>
<p style="padding-left: 30px;"><strong>countShops($criteria, $con);</strong></p>
<p style="padding-left: 60px;">countShops()方法用来返回满组织定条件的关联Shop个数</p>
<p style="padding-left: 60px;"><a name="ex-2-4">示例2.4</a>(<span style="color: #00ff00;">通过测试</span>):</p>
<p style="padding-left: 60px;"><code>//我们用下面代码获得某城市下全部的KFC(肯德基)的个数<br />
$c = new Criteria;<br />
$c-&gt;add(ShopPeer::NAME, '%KFC%', Criteris::LIKE);<br />
echo $city-&gt;getName() . ' has ' . $city-&gt;countShops($c) . ' KFC shops.';</code></p>
<p style="padding-left: 30px;"><strong>addShop($shop);</strong></p>
<p style="padding-left: 60px;">给city添加一个关联的shop, 参数$shop是一个shop对象</p>
<p style="padding-left: 60px;"><a name="ex-2-5">示例2.5</a>(<span style="color: #00ff00;">通过测试</span>):</p>
<p style="padding-left: 60px;"><code>//我们用下面代码在某城市新加一个KFC店铺<br />
$shop = new Shop;<br />
$shop-&gt;setName('KFC 人民大街店');<br />
$city-&gt;addShop($shop);<br />
$city-&gt;save()</code></p>
<p style="padding-left: 30px;"><strong>clearAllReferences($deep);</strong></p>
<p style="padding-left: 60px;">清空当前已经获得的关联对象， 实际上这个清空操作并没有真正意义上的进行清空或者删除，只是清空了当前已经取得的关联对象集合. 由于city只和shop进行了关联， 所以对于city对象来说其实该方法的效果和clearShops()是相同的.</p>
<p style="padding-left: 60px;"><a name="ex-2-6">示例2.6:</a></p>
<p style="padding-left: 60px;"><code>$mc = new Shop;<br />
$mc-&gt;setName('MC in Beijing');<br />
$city-&gt;addShop($mc);<br />
$city-&gt;clearAllReferences();<br />
$wc = new Shop;<br />
$wc-&gt;setName('WC in Beijing');<br />
$city-&gt;addShop($wc);<br />
$city-&gt;save();</code></p>
<p><span style="color: #008080;"><strong><a name="part-belongs-to">三.从属(belongsTo)关系的处理</a></strong></span></p>
<p>下图为BaseShop对象的结构</p>
<p><a name="pic-3-1">图3.1</a> BaseShop</p>
<p><strong><img class="aligncenter size-full wp-image-613" title="2009-02-26-123737_401x843_scrot" src="http://www.foolbirds.com/wp-content/uploads/2009/02/2009-02-26-123737_401x843_scrot.png" alt="2009-02-26-123737_401x843_scrot" width="401" height="843" /><br />
</strong></p>
<p>前面很多方法和BaseCity都是一样的, 而与BaseCity不同并与city相关的只有以下方法.</p>
<p style="padding-left: 30px;"><strong>setCity(City $city)</strong></p>
<p style="padding-left: 60px;">指定所属city, 参数$city是city对象</p>
<p style="padding-left: 60px;"><a name="ex-3-1">示例3.1</a>(<span style="color: #00ff00;">通过测试</span>):</p>
<p style="padding-left: 60px;"><code>//添加Changchun和KFC并同时创建关联<br />
$city = new City;<br />
$city-&gt;setName('Changchun');<br />
$shop-&gt;new Shop;<br />
$shop-&gt;setName('KFC in Changchun');<br />
$shop-&gt;setCity($city);<br />
$shop-&gt;save();</code></p>
<p style="padding-left: 30px;"><strong>getCity($con)</strong></p>
<p style="padding-left: 60px;">返回所属城市,返回值为city对象.</p>
<p style="padding-left: 60px;"><a name="ex-3-2">示例3.2</a>(<span style="color: #00ff00;">通过测试</span>):</p>
<p style="padding-left: 60px;"><code>// 输出店铺所在城市名<br />
echo $shop-&gt;getCity()-&gt;getName();</code></p>
<p><span style="color: #008080;"><strong><a name="part-many-to-many">四. 多对多(manyToMany)关系的处理</a></strong></span></p>
<p>我们继续看例子, Shop对象和Tag对象通过Shop_Tag对象进行多对多的关联, 下面我们来看一下这三个对象都生成了哪些方法.</p>
<p><a name="pic-4-1">图4.1</a></p>
<p><strong><img class="aligncenter size-full wp-image-603" title="2009-02-25-172720_395x647_scrot" src="http://www.foolbirds.com/wp-content/uploads/2009/02/2009-02-25-172720_395x647_scrot.png" alt="2009-02-25-172720_395x647_scrot" width="395" height="647" /></strong></p>
<p><a name="pic-4-2">图4.2</a></p>
<p><strong><img class="aligncenter size-full wp-image-604" title="2009-02-25-172752_403x704_scrot" src="http://www.foolbirds.com/wp-content/uploads/2009/02/2009-02-25-172752_403x704_scrot.png" alt="2009-02-25-172752_403x704_scrot" width="403" height="704" /></strong></p>
<p>在symfony中多对多关系相对要复杂一些, 整个过程涉及到3种对象, 其中涉及到的方法也要多一些.</p>
<p>其中Shop对象的相关方法有</p>
<p style="padding-left: 30px;"><strong>clearShopTags();</strong></p>
<p style="padding-left: 60px;">参考<a href="#ex-2-1">示例2.1</a></p>
<p style="padding-left: 30px;"><strong>initShopTags();</strong></p>
<p style="padding-left: 60px;">参考<a href="#ex-2-2">示例2.2</a></p>
<p style="padding-left: 30px;"><strong>getShopTags($criteria)</strong></p>
<p style="padding-left: 60px;">返回所有满足条件的相关联的ShopTag对象</p>
<p style="padding-left: 60px;"><a name="ex-4-1">示例4.1</a>(<span style="color: #00ff00;">通过测试</span>):</p>
<p style="padding-left: 60px;"><code>foreach($shop-&gt;getShopTags() as $shopTag){<br />
echo $shopTag-&gt;getTag()-&gt;getName();<br />
}</code></p>
<p style="padding-left: 30px;"><strong>countShopTags($criteria);</strong></p>
<p style="padding-left: 60px;">参考<a href="#ex-2-4">示例2.4</a></p>
<p style="padding-left: 30px;"><strong>addShopTag($shoptag);</strong></p>
<p style="padding-left: 60px;">添加一个ShopTag关联, 参数$shoptag是ShopTag对象</p>
<p style="padding-left: 60px;">我并没有想明白这个方法是用来作什么的, 按照正常的逻辑创建一个多对多关联应该是示例化一个新的ShopTag而不应该在Shop中addShopTag().</p>
<p style="padding-left: 60px;"><a name="ex-4-2">示例4.2</a>(<span style="color: #00ff00;">通过测试</span>):</p>
<p style="padding-left: 60px;"><code>$shopTag = new ShopTag;<br />
$shopTag-&gt;setTagId(2);<br />
$shop-&gt;addShopTag($shopTag);<br />
$shop-&gt;save();</code></p>
<p style="padding-left: 30px;"><strong>getShopTagsJoinTag($criteria);</strong></p>
<p style="padding-left: 60px;">返回所有符合查询条件的ShopTag关联对象并同时取出关联的Tag对象.</p>
<p style="padding-left: 60px;">在使用getShopTagsJoinTags()的时候你会发现用法其实和getShopTags()是一样的, 但使用getShopTagJoinTags()的之后再使用shopTag的getTag()方法实际上就不进行数据库查询了. 下面的例子要比getShopTags()的例子少很多次查询.</p>
<p style="padding-left: 60px;"><a name="ex-4-3">示例4.3</a>(<span style="color: #00ff00;">通过测试</span>):</p>
<p style="padding-left: 60px;"><code>foreach($shop-&gt;getShopTagsJoinTag() as $shopTag){<br />
echo $shopTag-&gt;getTag()-&gt;getName();<br />
}</code></p>
<p style="padding-left: 30px;"><strong>clearAllReferences($deep);</strong></p>
<p style="padding-left: 60px;">参考<a href="#ex-2-6">示例2.6</a></p>
<p>Tag对象的相关方法有</p>
<p style="padding-left: 30px;"><strong>clearShopTags();</strong></p>
<p style="padding-left: 60px;">参考<a href="#ex-2-1">示例2.1</a></p>
<p style="padding-left: 30px;"><strong>initShopTags();</strong></p>
<p style="padding-left: 60px;">参考<a href="#ex-2-2">示例2.2</a></p>
<p style="padding-left: 30px;"><strong>getShopTags($criteria)</strong></p>
<p style="padding-left: 60px;">参考<a href="#ex-4-1">示例4.1</a></p>
<p style="padding-left: 30px;"><strong>countShopTags($criteria);</strong></p>
<p style="padding-left: 60px;">参考<a href="#ex-2-4">示例2.4</a></p>
<p style="padding-left: 30px;"><strong>addShopTag($shoptag);</strong></p>
<p style="padding-left: 60px;">参考<a href="#ex-4-2">示例4.2</a></p>
<p style="padding-left: 30px;"><strong>getShopTagsJoinShop($criteria);</strong></p>
<p style="padding-left: 60px;">参考<a href="#ex-4-3">示例4.3</a></p>
<p style="padding-left: 30px;"><strong>clearAllReferences($deep);</strong></p>
<p style="padding-left: 60px;">参考<a href="#ex-2-6">示例2.6</a></p>
<p>ShopTag对象的相关方法有</p>
<p style="padding-left: 30px;"><strong>getShop();</strong></p>
<p style="padding-left: 60px;">返回关联的Shop对象</p>
<p style="padding-left: 60px;"><a name="ex-4-4">示例4.4</a>(<span style="color: #00ff00;">通过测试</span>):</p>
<p style="padding-left: 60px;"><code>// 输出与tag关联的全部shop的name<br />
foreach($tag-&gt;getShopTags() as $shopTag){<br />
echo $shopTag-&gt;getShop()-&gt;getName();<br />
}</code></p>
<p style="padding-left: 30px;"><strong>setShop($shop);</strong></p>
<p style="padding-left: 60px;">设置关联Shop, $shop参数是Shop对象</p>
<p style="padding-left: 30px;"><strong>getTag();</strong></p>
<p style="padding-left: 60px;">返回关联的Tag对象</p>
<p style="padding-left: 60px;"><a href="#ex-4-5">示例4.5</a>(<span style="color: #00ff00;">通过测试</span>):</p>
<p style="padding-left: 60px;"><code>// 输出与shop关联的全部tag的name<br />
foreach($shop-&gt;getShopTags() as $shopTag){<br />
echo $shopTag-&gt;getTag()-&gt;getName();<br />
}</code></p>
<p style="padding-left: 30px;"><strong>setTag($tag);</strong></p>
<p style="padding-left: 60px;">设置关联Tag, $tag参数是Tag对象</p>
<p style="padding-left: 30px;"><strong>clearAllReferences($deep);</strong></p>
<p style="padding-left: 60px;">参考<a href="#ex-2-6">示例2.6</a></p>
<p><span style="color: #008080;"><strong><a name="part-one-to-one">五.一对一(oneToOne)关系的处理</a></strong></span></p>
<p>首先, 我们来看一下propel自动生成的Shopinfo对象, Shop对象在<a href="#pic-3-1">图3.1</a>中已经有介绍.</p>
<p><a name="pic-5-1">图5.1</a> BaseShopinfo</p>
<p><img class="aligncenter size-full wp-image-612" title="2009-02-26-123139_398x617_scrot" src="http://www.foolbirds.com/wp-content/uploads/2009/02/2009-02-26-123139_398x617_scrot.png" alt="2009-02-26-123139_398x617_scrot" width="398" height="617" /></p>
<p>经过几天的探索才成功的找到了进行一对一关联的方法.我们必须要将shopinfo中的外键设定为shopinfo的主键才可以被propel处理.</p>
<p>下面这几种都是<span style="color: #ff0000;">错误</span>的关联设计.</p>
<blockquote><p>shop:<br />
..id:<br />
..shopinfo_id:<br />
..name:<br />
shopinfo:<br />
..id:<br />
..add:<br />
..tel:</p></blockquote>
<blockquote><p>shop:<br />
..id:<br />
..name:<br />
shopinfo:<br />
..id:<br />
..shop_id:<br />
..add:<br />
..tel:</p></blockquote>
<blockquote><p>shop:<br />
..id:<br />
..shopinfo_id:<br />
..name:<br />
shopinfo:<br />
..id:<br />
..shop_id:<br />
..add:<br />
..tel:</p></blockquote>
<p><span style="color: #00ff00;">正确</span>的一对一关联设计应该是</p>
<blockquote><p>shop:<br />
..id:<br />
..name:<br />
shopinfo:<br />
..shop_id:<br />
..add:<br />
..tel:</p></blockquote>
<p>根据<a href="#pic-3-1">图3.1</a>和<a href="#pic-5-1">图5.1</a>, Shop对象拥有方法setShopinfo()和getShopinfo()方法来操作唯一的关联店铺信息, 而Shopinfo对象也拥有setShop()和getShop()方法来操作唯一的关联店铺.</p>
<p style="padding-left: 30px;"><a name="ex-5-1">示例5.1</a>:</p>
<p style="padding-left: 30px;"><code>//给商店添加店铺信息<br />
$shop-&gt;setShopinfo(new Shopinfo);<br />
$shop-&gt;getShopinfo()-&gt;setAddress('a Place');<br />
$shop-&gt;getShopinfo()-&gt;setTel('010-12345678');<br />
$shop-&gt;save();</code></p>
<p style="padding-left: 30px;"><a name="ex-5-2">示例5.2</a>:</p>
<p style="padding-left: 30px;"><code>// 修改店铺的店铺信息<br />
$shop-&gt;getShopinfo()-&gt;setTel('010-87654321');<br />
$shop-&gt;save();</code></p>
<p><span style="color: #008080;"><strong><a name="part-end">六.总结</a></strong></span></p>
<p>到这里为止我们就把symfony中propel对数据关联的操作介绍的差不多了, 可能还有一些方面没有详细的介绍也只能考各位自己钻研了. 介于本人能力有限, 本文难免会有错误和遗漏, 希望大家可以指出, 感慨一下, 这篇文章从策划到结束一共用了4天.</p>
<p>附件是本文进行测试的项目文件, 内无symfony库, 请将symfony/lib目录cp到lib目录下并重命名为symfony.</p>
<p>附件: <a href="http://www.foolbirds.com/wp-content/uploads/2009/02/references.tgz">references.tgz</a></p>
<p>(本文完)</p>
<ul class="related_post"><li><a href="http://www.foolbirds.com/add-table-prefix-in-symfony.html" title="Add table prefix  in symfony－在symfony中使用表前缀">Add table prefix  in symfony－在symfony中使用表前缀</a></li><li><a href="http://www.foolbirds.com/use-orm-propel.html" title="关于数据查询的使用">关于数据查询的使用</a></li><li><a href="http://www.foolbirds.com/use_symfony_filter_to_filteredurl.html" title="使用SYMFONY Filter 过滤URL">使用SYMFONY Filter 过滤URL</a></li><li><a href="http://www.foolbirds.com/%e4%bb%bfsymfony%e6%9c%ba%e5%88%b6%e5%ae%9e%e7%8e%b0%e4%b8%8d%e7%94%a8require%e6%88%96%e8%80%85include%e6%9d%a5%e5%ae%9e%e4%be%8b%e5%8c%96%e7%b1%bb.html" title="仿symfony机制实现不用require或者include来实例化类">仿symfony机制实现不用require或者include来实例化类</a></li><li><a href="http://www.foolbirds.com/use-datetime-in-php5-1-x-with-symfony.html" title="symfony1.4 DateTime对于PHP低版本的兼容问题">symfony1.4 DateTime对于PHP低版本的兼容问题</a></li><li><a href="http://www.foolbirds.com/%e5%a6%82%e4%bd%95%e5%9c%a8fixtures-yml%e5%86%99%e5%be%aa%e7%8e%af%e6%b7%bb%e5%8a%a0%e6%95%b0%e6%8d%ae.html" title="如何在fixtures.yml写循环添加数据">如何在fixtures.yml写循环添加数据</a></li><li><a href="http://www.foolbirds.com/symfony-1-4-database-utf8.html" title="symfony 1.4 数据库 utf8设置">symfony 1.4 数据库 utf8设置</a></li><li><a href="http://www.foolbirds.com/symfony-cheat-sheet.html" title="symfony cheat sheet">symfony cheat sheet</a></li><li><a href="http://www.foolbirds.com/cheat-sheets.html" title="Cheat Sheets!">Cheat Sheets!</a></li><li><a href="http://www.foolbirds.com/how-to-embed-forms-in-symfony-12-admin-generator.html" title="内嵌表单详解（How to Embed Forms in Symfony 1.2 Admin Generator 中文版）">内嵌表单详解（How to Embed Forms in Symfony 1.2 Admin Generator 中文版）</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.foolbirds.com/symfony-references-with-propel.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>关于数据查询的使用</title>
		<link>http://www.foolbirds.com/use-orm-propel.html</link>
		<comments>http://www.foolbirds.com/use-orm-propel.html#comments</comments>
		<pubDate>Tue, 16 Dec 2008 02:44:16 +0000</pubDate>
		<dc:creator>kthiz2006</dc:creator>
				<category><![CDATA[symfony]]></category>
		<category><![CDATA[criteria]]></category>
		<category><![CDATA[propel]]></category>

		<guid isPermaLink="false">http://symfony.bobhero.net/?p=24</guid>
		<description><![CDATA[目前常用的数据库查询采用的是Criteria。

常用的sql如下：
WHERE column = value 	-&#62;add(column, value);
WHERE column &#60;&#62; value 	-&#62;add(column, value, Criteria::NOT_EQUAL);
Other Comparison Operators
&#62; , &#60; 	Criteria::GREATER_THAN, Criteria::LESS_THAN
&#62;=, &#60;= 	Criteria::GREATER_EQUAL, Criteria::LESS_EQUAL
IS NULL, IS NOT NULL 	Criteria::ISNULL, Criteria::ISNOTNULL
LIKE, ILIKE 	Criteria::LIKE, Criteria::ILIKE
IN, NOT IN 	Criteria::IN, Criteria::NOT_IN
Other SQL Keywords
ORDER BY column ASC 	-&#62;addAscendingOrderByColumn(column);
ORDER BY column DESC 	-&#62;addDescendingOrderByColumn(column);
LIMIT limit 	-&#62;setLimit(limit)
OFFSET offset 	-&#62;setOffset(offset)
FROM table1, table2 WHERE table1.col1 = table2.col2 	-&#62;addJoin(col1, [...]]]></description>
			<content:encoded><![CDATA[<pre name="code" class="php">目前常用的数据库查询采用的是Criteria。

常用的sql如下：
WHERE column = value 	-&gt;add(column, value);
WHERE column &lt;&gt; value 	-&gt;add(column, value, Criteria::NOT_EQUAL);
Other Comparison Operators
&gt; , &lt; 	Criteria::GREATER_THAN, Criteria::LESS_THAN
&gt;=, &lt;= 	Criteria::GREATER_EQUAL, Criteria::LESS_EQUAL
IS NULL, IS NOT NULL 	Criteria::ISNULL, Criteria::ISNOTNULL
LIKE, ILIKE 	Criteria::LIKE, Criteria::ILIKE
IN, NOT IN 	Criteria::IN, Criteria::NOT_IN
Other SQL Keywords
ORDER BY column ASC 	-&gt;addAscendingOrderByColumn(column);
ORDER BY column DESC 	-&gt;addDescendingOrderByColumn(column);
LIMIT limit 	-&gt;setLimit(limit)
OFFSET offset 	-&gt;setOffset(offset)
FROM table1, table2 WHERE table1.col1 = table2.col2 	-&gt;addJoin(col1, col2)
FROM table1 LEFT JOIN table2 ON table1.col1 = table2.col2 	-&gt;addJoin(col1, col2, Criteria::LEFT_JOIN)
FROM table1 RIGHT JOIN table2 ON table1.col1 = table2.col2 	-&gt;addJoin(col1, col2, Criteria::RIGHT_JOIN)

使用或语句查询的例子：
&lt;?php
  $c = new Criteria();
  $c1 = $c-&gt;getNewCriterion(TableAPeer::COLUMN_A, 1);
  $c2 = $c-&gt;getNewCriterion(TableAPeer::COLUMN_A, 2);
  $c1-&gt;addOr($c2);
  $c-&gt;add(TableAPeer::COLUMN_B, ‘xxx’);
  $c-&gt;add($c1);
?&gt;
等价于
SELECT * FROM table_a WHERE (column_a = 1 OR column_a = 3) AND column_c = ‘xxx

使用group语句查询的例子：
&lt;?php
 $c=new Criteria();
 $c-&gt;addSelectColumn('SUM(score) as A');
 $c-&gt;addSelectColumn(BuryPeer::SCORE);
 $c-&gt;addGroupByColumn('article_id');
 $crit=$c-&gt;getNewCriterion(BuryPeer::ARTICLE_ID,$article-&gt;getId());
 $c-&gt;addHaving($crit);
 $buries=BuryPeer::doSelectRS($c);
?&gt;
等价于select SUM(score) from bury group by article_id having article_id=@ARTICLE_ID

Criteria可以用doSelect,doUpdate,doInsert,doDelete方法.
例：
doDelete($obj)操作
&lt;?php
  ShopTagPeer::doDelete($tag);
?&gt;
doInsert操作
&lt;?php
  $b = new Criteria();
  $b-&gt;add(ShopTagPeer::SHOP_ID, $shop_id);
  $b-&gt;add(ShopTagPeer::TAG_ID, $tag);
  ShopTagPeer::doInsert($b);
?&gt;
还有一个查询不重复的方法
&lt;?php
$c = new Criteria();
$c-&gt;setDistinct();
?&gt;

&lt;?php
//新建
$user = new User();
$user-&gt;setName('symfony');
$user-&gt;setAge(3);
$user-&gt;save();

//查询
$user = UserPeer::retrieveByPk(1);
echo $user-&gt;getName() . '   ' . $user-&gt;getAge() . '&lt;br /&gt;    ';
$users = UserPeer::retrieveByPks(array(1, 2, 3, 4));
foreach ($users as $user) {
echo $user-&gt;getName() . '   ' . $user-&gt;getAge() . '&lt;br /&gt;    ';
}

// 更新
$user = UserPeer::retrieveByPk(1);
$user-&gt;setName('new Name');
$user-&gt;save();

// 删除
UserPeer::doDelete(1);
$user = UserPeer::retrieveByPk(1);
$user-&gt;delete();
?&gt;
&lt;?php
// 查询 name = 'symfony' 的记录
$c = new Criteria();
$c-&gt;add(UserPeer::NAME, 'symfony');
$users = UserPeer::doSelect($c);

//只查询一条记录
$user = UserPeer::doSelectOne($c);

//...也支持 group by、limit、table join 等等特性
?&gt;

使用 Criteria::CUSTOM 可使 Criteria 实现自定义条件查询

SELECT *
FROM users
WHERE CONCAT(first_name, ' ', last_name) = '$username';

&lt;?php
$c = new Criteria();
$c-&gt;add(UserPeer::FIRST_NAME,
"CONCAT(" . UserPeer::FIRST_NAME . ", ' ', " . UserPeer::LAST_NAME . ") = '" . $username . "'",
Criteria::CUSTOM);
$users = UserPeer::doSelect($c);
?&gt;

当遇到复杂语句查询的时候，可以采取以下方法:
&lt;?php
 $connection = Propel::getConnection();
 $query = 'SELECT MAX(%s) AS max FROM %s'; //写你要查询的sql
 $query = sprintf($query, ArticlePeer::CREATED_AT, ArticlePeer::TABLE_NAME);
 $statement = $connection-&gt;prepare($query);
 $statement-&gt;execute();
 $resultset = $statement-&gt;fetch(PDO::FETCH_OBJ);
 $max = $resultset-&gt;max;
?&gt;</pre>
<ul class="related_post"><li><a href="http://www.foolbirds.com/add-table-prefix-in-symfony.html" title="Add table prefix  in symfony－在symfony中使用表前缀">Add table prefix  in symfony－在symfony中使用表前缀</a></li><li><a href="http://www.foolbirds.com/symfony-references-with-propel.html" title="symfony数据表关联详解(for propel)">symfony数据表关联详解(for propel)</a></li><li><a href="http://www.foolbirds.com/use_symfony_filter_to_filteredurl.html" title="使用SYMFONY Filter 过滤URL">使用SYMFONY Filter 过滤URL</a></li><li><a href="http://www.foolbirds.com/%e4%bb%bfsymfony%e6%9c%ba%e5%88%b6%e5%ae%9e%e7%8e%b0%e4%b8%8d%e7%94%a8require%e6%88%96%e8%80%85include%e6%9d%a5%e5%ae%9e%e4%be%8b%e5%8c%96%e7%b1%bb.html" title="仿symfony机制实现不用require或者include来实例化类">仿symfony机制实现不用require或者include来实例化类</a></li><li><a href="http://www.foolbirds.com/use-datetime-in-php5-1-x-with-symfony.html" title="symfony1.4 DateTime对于PHP低版本的兼容问题">symfony1.4 DateTime对于PHP低版本的兼容问题</a></li><li><a href="http://www.foolbirds.com/%e5%a6%82%e4%bd%95%e5%9c%a8fixtures-yml%e5%86%99%e5%be%aa%e7%8e%af%e6%b7%bb%e5%8a%a0%e6%95%b0%e6%8d%ae.html" title="如何在fixtures.yml写循环添加数据">如何在fixtures.yml写循环添加数据</a></li><li><a href="http://www.foolbirds.com/symfony-1-4-database-utf8.html" title="symfony 1.4 数据库 utf8设置">symfony 1.4 数据库 utf8设置</a></li><li><a href="http://www.foolbirds.com/symfony-cheat-sheet.html" title="symfony cheat sheet">symfony cheat sheet</a></li><li><a href="http://www.foolbirds.com/cheat-sheets.html" title="Cheat Sheets!">Cheat Sheets!</a></li><li><a href="http://www.foolbirds.com/how-to-use-swift-to-send-mail-in-symfon.html" title="如何使用swift发送邮件">如何使用swift发送邮件</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.foolbirds.com/use-orm-propel.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
