SpeedPHP/数据表一对一关联:修订间差异
(新页面: {{SpeedPHP top}} ==一对多关联== 首先我们的例子是一个留言本程序,一个用户可以发布多条留言信息,而每条留言信息只能由一个用户来发布。 ...) |
无编辑摘要 |
||
第1行: | 第1行: | ||
{{SpeedPHP top}} | {{SpeedPHP top}} | ||
在一对一关联中,spLinker提供了几乎全部的spModel拥有的功能,在理解了spModel的基础知识后,很轻易就可以使用spLinker带来的关联功能了。 | |||
关联 spLinker类型 可以应用范围 特殊要求 | |||
==一对一关联== | |||
首先看例子,我们先准备了两个数据表,分别是用户表及用户详细资料表,为了方便讲述,这里的数据表都是简化的。 | |||
===user用户表=== | |||
<pre>< ?php | *user_id int 用户ID 自增/主键 | ||
*user_name varchar(50) 用户名 唯一 | |||
*user_detail 用户详细资料表 | |||
*user_id int 用户ID 主键 | |||
*intro varchar(255) 用户个人介绍 | |||
一个用户记录对应着一个详细资料,因而这两个表是一对一的。正如前文所述,由于详细资料在逻辑上并非经常和用户表同时出现,所以我们将本来是相关的记录拆分成两个表来对待。(下面我们称user为本表,user_detail为对应表) | |||
第二步,我们分别建立了这两个表的spModel继承类,[[代码]]如下,user.php: | |||
<pre><?php | |||
class user extends spModel | class user extends spModel | ||
{ | { | ||
第22行: | 第23行: | ||
var $linker = array( | var $linker = array( | ||
array( | array( | ||
'type' => 'hasone', // | 'type' => 'hasone', // 关联类型,这里是一对一关联 | ||
'map' => 'detail', // 关联的标识 | 'map' => 'detail', // 关联的标识 | ||
'mapkey' => 'user_id', | 'mapkey' => 'user_id', // 本表与对应表关联的字段名 | ||
'fclass' => 'user_detail', | 'fclass' => 'user_detail', // 对应表的类名 | ||
'fkey' => 'user_id', | 'fkey' => 'user_id', // 对应表中关联的字段名 | ||
'enabled' => | 'enabled' => true // 启用关联 | ||
) | |||
) | |||
); | ); | ||
} | } | ||
</pre> | </pre> | ||
user_detail.php: | |||
<pre>< ?php | <pre><?php | ||
class | class user_detail extends spModel | ||
{ | { | ||
public $pk = | public $pk = 'user_id'; | ||
public $table = | public $table = 'user_detail'; | ||
} | } | ||
</pre> | </pre> | ||
我们看到,作为主表的user类,它使用了$linker来设置关联信息(本章的最后将详细介绍$linker的每个设置的作用)。$linker是非常必要的,因为无论是作为模型类的变量出现,或者是在程序过程中动态地载入到spLinker中,都需要按照正确的格式去设置。 | |||
下面我们来介绍一对一关联的create,update,delete,find,findAll操作: | |||
===CREATE=== | ===CREATE=== | ||
首先,一般而言如果我们调用了user类的create方法,将在user表中新增一条记录。不过现在我们希望通过使用了一对一的关联,同时地将记录新增到主表和对应表上: | |||
<pre>$newrow = array( | <pre>$newrow = array( | ||
'user_name' => | 'user_name' => "灰太狼", | ||
' | 'detail' => array( // 请注意这里对应的就是$linker的'map' => 'detail',也就是关联的标识 | ||
'intro' => "草原上的王者" // 这里是增加到对应表上的数据 | |||
), | ), | ||
); | ); | ||
$userObj = spClass("user"); | $userObj = spClass("user"); | ||
$userObj->spLinker()->create($newrow); | $userObj->spLinker()->create($newrow); // 和普通的create不同! | ||
</pre> | </pre> | ||
好了,看看两个[[数据]]表,数据已经如我们想象一样出现了: | |||
user表 | user表 | ||
1 灰太狼 | 1 灰太狼 | ||
user_detail表 | |||
1 草原上的王者 | |||
在使用spLinker过程中,需要注意的地方如上面注释的,一个是关联的标识的作用,另一个是spLinker()->形式的函数调用。 | |||
$userObj->spLinker()->create($newrow)这种形式的调用在sp框架内尤其是spModel的附属类内经常可以见到,这是一种提高代码写作效率和减少理解误差的好方法。它在spModel的意义就是附加的功能,比如$userObj->spPager()->findAll()就是在findAll上面附加了spPager分页的功能,本例中$userObj->spLinker()->create($newrow); 就是在create的时候加入了spLinker关联功能等等。建议大家能好好的熟悉这种写法,这将为我们的系统开发效率带来非常明显的改善。 | |||
==UPDATE== | |||
在一对一的关联中,更新可以是对主表的记录更新,也可以是对对应表的记录进行更新。当然,前提是更新条件要在主表中都能有记录匹配。 | |||
<pre>$conditions = array('user_name' => "灰太狼"); // 和普通的update一样,首先是要有更新的条件,条件主要是针对主表的 | |||
$updaterow = array( // 这里是需要更新的数据 | |||
'detail' => array( // 注意detail指代的是什么 | |||
'intro' => "不像草原上的王者" | |||
), | |||
); | |||
$userObj = spClass("user"); | |||
$userObj->spLinker()->update($conditions, $updaterow); // 完成更新 | |||
</pre> | |||
执行了上面代码后,我们再来看看两表: | |||
user表 | |||
1 灰太狼 | |||
user_detail表 | |||
1 不像草原上的王者 | |||
显然这里只更新了对应表。当然,如果加入其他的更新数据,那么主表也是能够更新的。 | |||
===DELETE=== | |||
<pre>$ | 一对一的关联中,删除操作是会将两表的对应记录同时删除。 | ||
<pre>$conditions = array('user_name' => "灰太狼"); // 还是要设置对主表的条件 | |||
$userObj = spClass("user"); | |||
$userObj->spLinker()->delete($conditions); // 完成删除 | |||
); | |||
</pre> | </pre> | ||
===FIND/FINDALL=== | |||
我们并没有把find和findAll放到前面去讲述,这是因为我们希望能够先了解数据从何而来,再去熟悉数据的使用。 | |||
在spLinker的作用下,拥有表间关联的find和findAll,查找获取的结果都将带上关联表中的内容。 | |||
首先我们准备下面的表数据: | |||
user表 | |||
1 灰太狼 | |||
2 小羊羊 | |||
user_detail表: | |||
1 不像草原上的王者 | |||
2 是一只羊 | |||
然后我们用find查找: | |||
<pre>$conditions = array("user_name"=>"小羊羊"); | |||
$userObj = spClass("user"); | |||
$result = $userObj->spLinker()->find($conditions); | |||
dump($result); | |||
</pre> | |||
结果是: | |||
<pre>Array | |||
( | |||
[user_id] => 2 | |||
[user_name] => 小羊羊 | |||
[detail] => Array | |||
( | |||
[user_id] => 2 | |||
[intro] => 是一只羊 | |||
) | |||
) | |||
</pre> | |||
我们看到detail的标识已经带上了对应表user_detail的记录了。 | |||
使用findAll查找 | |||
<pre>$userObj = spClass("user"); | <pre>$userObj = spClass("user"); | ||
$result = $userObj->spLinker()->findAll(); | $result = $userObj->spLinker()->findAll(); | ||
dump($result); | dump($result); | ||
</pre> | </pre> | ||
结果是: | |||
<pre>Array | <pre>Array | ||
( | ( | ||
第111行: | 第151行: | ||
[user_id] => 12 | [user_id] => 12 | ||
[user_name] => 灰太狼 | [user_name] => 灰太狼 | ||
[ | [detail] => Array | ||
( | |||
[user_id] => 12 | |||
[intro] => 不像草原上的王者 | |||
) | |||
) | ) | ||
[1] => Array | [1] => Array | ||
第117行: | 第161行: | ||
[user_id] => 14 | [user_id] => 14 | ||
[user_name] => 小羊羊 | [user_name] => 小羊羊 | ||
[ | [detail] => Array | ||
( | ( | ||
[user_id] => 14 | |||
[intro] => 是一只羊 | |||
[ | |||
) | ) | ||
) | ) | ||
) | ) | ||
</pre> | |||
主表和对应表的记录都能查找出来了。 | |||
==$linker属性== | |||
在这里,我们还需要介绍一下$linker的全部属性,部分是上面已经介绍过的。 | |||
===对本表内容而言=== | |||
*type,关联类型,只能取值"hasone","hasmany"和"manytomany"三者之一。 | |||
*enabled,取值TRUE/FALSE,指示是否开启本关联 | |||
*map,关联标识,在返回的结果里面标识关联内容的键值。 | |||
*mapkey,本表中与对应表关联的字段名 | |||
===对对应表内容而言=== | |||
*fclass,对应表的spModel继承类名称 | |||
*fkey,对应表中与本表关联的字段名 | |||
*midclass,中间表的spModel继承类名称 | |||
===对关联结果的限制=== | |||
*condition,对关联的附加条件,格式和findAll一样 | |||
*countonly,取值TRUE/FALSE,在关联查找时是否只返回关联结果的记录数量,而并不返回全部结果。 | |||
*sort,返回关联结果的排序,格式和findAll一样 | |||
*field,返回关联结果的限定字段,格式和findAll一样 | |||
*limit,返回关联结果的数量,格式和findAll一样 | |||
完整的 $linker 应该是: | |||
<pre> var $linker = array( | |||
array( | |||
'type' => 'hasmany', | |||
'map' => 'ulink', | |||
'mapkey' => 'user_id', | |||
'fclass' => 'gb', | |||
'fkey' => 'user_id', | |||
'midclass' => 'user2gb', | |||
'sort' => '', 'condition' => '', 'field' => '', 'limit' => '', | |||
'enabled' => true, 'countonly' => false | |||
), | |||
array( | |||
... | |||
) | |||
); | |||
</pre> | </pre> | ||
2011年5月28日 (六) 15:45的最新版本
SpeedPHP | 快速入门 | 访问交互 | 数据操作 | 框架概述 | 模板引擎 | 优化加速 | 开发指南 | 数据模型 | API参考 |
在一对一关联中,spLinker提供了几乎全部的spModel拥有的功能,在理解了spModel的基础知识后,很轻易就可以使用spLinker带来的关联功能了。 关联 spLinker类型 可以应用范围 特殊要求
一对一关联[ ]
首先看例子,我们先准备了两个数据表,分别是用户表及用户详细资料表,为了方便讲述,这里的数据表都是简化的。
user用户表[ ]
- user_id int 用户ID 自增/主键
- user_name varchar(50) 用户名 唯一
- user_detail 用户详细资料表
- user_id int 用户ID 主键
- intro varchar(255) 用户个人介绍
一个用户记录对应着一个详细资料,因而这两个表是一对一的。正如前文所述,由于详细资料在逻辑上并非经常和用户表同时出现,所以我们将本来是相关的记录拆分成两个表来对待。(下面我们称user为本表,user_detail为对应表)
第二步,我们分别建立了这两个表的spModel继承类,代码如下,user.php:
<?php class user extends spModel { public $pk = 'user_id'; public $table = 'user'; // 由spModel的变量$linker来设置表间关联 var $linker = array( array( 'type' => 'hasone', // 关联类型,这里是一对一关联 'map' => 'detail', // 关联的标识 'mapkey' => 'user_id', // 本表与对应表关联的字段名 'fclass' => 'user_detail', // 对应表的类名 'fkey' => 'user_id', // 对应表中关联的字段名 'enabled' => true // 启用关联 ) ); }
user_detail.php:
<?php class user_detail extends spModel { public $pk = 'user_id'; public $table = 'user_detail'; }
我们看到,作为主表的user类,它使用了$linker来设置关联信息(本章的最后将详细介绍$linker的每个设置的作用)。$linker是非常必要的,因为无论是作为模型类的变量出现,或者是在程序过程中动态地载入到spLinker中,都需要按照正确的格式去设置。
下面我们来介绍一对一关联的create,update,delete,find,findAll操作:
CREATE[ ]
首先,一般而言如果我们调用了user类的create方法,将在user表中新增一条记录。不过现在我们希望通过使用了一对一的关联,同时地将记录新增到主表和对应表上:
$newrow = array( 'user_name' => "灰太狼", 'detail' => array( // 请注意这里对应的就是$linker的'map' => 'detail',也就是关联的标识 'intro' => "草原上的王者" // 这里是增加到对应表上的数据 ), ); $userObj = spClass("user"); $userObj->spLinker()->create($newrow); // 和普通的create不同!
好了,看看两个数据表,数据已经如我们想象一样出现了:
user表
1 灰太狼
user_detail表
1 草原上的王者
在使用spLinker过程中,需要注意的地方如上面注释的,一个是关联的标识的作用,另一个是spLinker()->形式的函数调用。
$userObj->spLinker()->create($newrow)这种形式的调用在sp框架内尤其是spModel的附属类内经常可以见到,这是一种提高代码写作效率和减少理解误差的好方法。它在spModel的意义就是附加的功能,比如$userObj->spPager()->findAll()就是在findAll上面附加了spPager分页的功能,本例中$userObj->spLinker()->create($newrow); 就是在create的时候加入了spLinker关联功能等等。建议大家能好好的熟悉这种写法,这将为我们的系统开发效率带来非常明显的改善。
UPDATE[ ]
在一对一的关联中,更新可以是对主表的记录更新,也可以是对对应表的记录进行更新。当然,前提是更新条件要在主表中都能有记录匹配。
$conditions = array('user_name' => "灰太狼"); // 和普通的update一样,首先是要有更新的条件,条件主要是针对主表的 $updaterow = array( // 这里是需要更新的数据 'detail' => array( // 注意detail指代的是什么 'intro' => "不像草原上的王者" ), ); $userObj = spClass("user"); $userObj->spLinker()->update($conditions, $updaterow); // 完成更新
执行了上面代码后,我们再来看看两表:
user表
1 灰太狼
user_detail表
1 不像草原上的王者
显然这里只更新了对应表。当然,如果加入其他的更新数据,那么主表也是能够更新的。
DELETE[ ]
一对一的关联中,删除操作是会将两表的对应记录同时删除。
$conditions = array('user_name' => "灰太狼"); // 还是要设置对主表的条件 $userObj = spClass("user"); $userObj->spLinker()->delete($conditions); // 完成删除
FIND/FINDALL[ ]
我们并没有把find和findAll放到前面去讲述,这是因为我们希望能够先了解数据从何而来,再去熟悉数据的使用。
在spLinker的作用下,拥有表间关联的find和findAll,查找获取的结果都将带上关联表中的内容。
首先我们准备下面的表数据:
user表
1 灰太狼
2 小羊羊
user_detail表:
1 不像草原上的王者
2 是一只羊
然后我们用find查找:
$conditions = array("user_name"=>"小羊羊"); $userObj = spClass("user"); $result = $userObj->spLinker()->find($conditions); dump($result);
结果是:
Array ( [user_id] => 2 [user_name] => 小羊羊 [detail] => Array ( [user_id] => 2 [intro] => 是一只羊 ) )
我们看到detail的标识已经带上了对应表user_detail的记录了。
使用findAll查找
$userObj = spClass("user"); $result = $userObj->spLinker()->findAll(); dump($result);
结果是:
Array ( [0] => Array ( [user_id] => 12 [user_name] => 灰太狼 [detail] => Array ( [user_id] => 12 [intro] => 不像草原上的王者 ) ) [1] => Array ( [user_id] => 14 [user_name] => 小羊羊 [detail] => Array ( [user_id] => 14 [intro] => 是一只羊 ) ) )
主表和对应表的记录都能查找出来了。
$linker属性[ ]
在这里,我们还需要介绍一下$linker的全部属性,部分是上面已经介绍过的。
对本表内容而言[ ]
- type,关联类型,只能取值"hasone","hasmany"和"manytomany"三者之一。
- enabled,取值TRUE/FALSE,指示是否开启本关联
- map,关联标识,在返回的结果里面标识关联内容的键值。
- mapkey,本表中与对应表关联的字段名
对对应表内容而言[ ]
- fclass,对应表的spModel继承类名称
- fkey,对应表中与本表关联的字段名
- midclass,中间表的spModel继承类名称
对关联结果的限制[ ]
- condition,对关联的附加条件,格式和findAll一样
- countonly,取值TRUE/FALSE,在关联查找时是否只返回关联结果的记录数量,而并不返回全部结果。
- sort,返回关联结果的排序,格式和findAll一样
- field,返回关联结果的限定字段,格式和findAll一样
- limit,返回关联结果的数量,格式和findAll一样
完整的 $linker 应该是:
var $linker = array( array( 'type' => 'hasmany', 'map' => 'ulink', 'mapkey' => 'user_id', 'fclass' => 'gb', 'fkey' => 'user_id', 'midclass' => 'user2gb', 'sort' => '', 'condition' => '', 'field' => '', 'limit' => '', 'enabled' => true, 'countonly' => false ), array( ... ) );
参考来源[ ]
http://speedphp.com/manual.html
SpeedPHP使用手册导航 | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|