Copyright(c) DoYouHaoBaby.NET All Rights Reserved.
DyhbFrame多对多关联是很容易理解的,以下我们举个例子来说明DyhbFrame的多对多关联的用法。
本例用的数据库及表:
farm_fruit
DROP TABLE IF EXISTS `farm_fruit`;
CREATE TABLE `farm_fruit` (
`fruitid` int(11) NOT NULL AUTO_INCREMENT,
`fruitname` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
PRIMARY KEY (`fruitid`)
)
ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;
INSERT INTO `farm_fruit` VALUES ('1', '南瓜');
INSERT INTO `farm_fruit` VALUES ('2', '西瓜');
INSERT INTO `farm_fruit` VALUES ('3', '玫瑰');
INSERT INTO `farm_fruit` VALUES ('4', '青草');
INSERT INTO `farm_fruit` VALUES ('5', '大白菜');
INSERT INTO `farm_fruit` VALUES ('6', '圣诞树');
INSERT INTO `farm_fruit` VALUES ('7', '葡萄');
farm_user
DROP TABLE IF EXISTS `farm_user`;
CREATE TABLE `farm_user` (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
PRIMARY KEY (`uid`)
)
ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
INSERT INTO `farm_user` VALUES ('1', '灰太狼');
INSERT INTO `farm_user` VALUES ('2', '喜羊羊');
INSERT INTO `farm_user` VALUES ('3', '羊村长');
INSERT INTO `farm_user` VALUES ('4', '懒羊羊');
INSERT INTO `farm_user` VALUES ('5', '暖羊羊');
farm_user2fruit
DROP TABLE IF EXISTS `farm_user2fruit`;
CREATE TABLE `farm_user2fruit` (
`uid` int(11) NOT NULL,
`fruitid` int(11) DEFAULT NULL
)
ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `farm_user2fruit` VALUES ('2', '3');
INSERT INTO `farm_user2fruit` VALUES ('2', '4');
INSERT INTO `farm_user2fruit` VALUES ('4', '1');
INSERT INTO `farm_user2fruit` VALUES ('4', '2');
INSERT INTO `farm_user2fruit` VALUES ('2', '1');
INSERT INTO `farm_user2fruit` VALUES ('5', '4');
INSERT INTO `farm_user2fruit` VALUES ('5', '6');
INSERT INTO `farm_user2fruit` VALUES ('5', '7');
最近喜羊羊的村落也非常喜欢种菜(QQ农场)了,所以全部的人(羊?)都种了不少的菜,而且各人种的种类也不尽相同。据我们的调查,他们所种的菜是以下关系:
让我们从编程的角度来看,不同的羊种了不同的菜,同时也可以说不同的菜被不同的羊种了,这就是多对多的关系。
下面我们使用程序来描述他们之间的关系,在user的数据类中,定义和fruit表的多对多关系,定义如下:
class UserModel extends Model
{
protected $_linker = array(
array(
'type' => '3', // 多对多关联
'map' => 'farms', // 关联的标识
'midclass' => 'user2fruit', // 关联的中间表
'mapkey' => 'uid', // 关联的字段
'fclass' => 'fruit', // 对应表的数据类
'fkey' => 'fruitid', // 对应表的关联字段
'enabled' => true
),
);
}
这里要注意和一对多区别的除了type之外,多对多关联还有了midclass,midclass是一个数据库类,对应了一个存储着多对多两表之间的关系。我们可以看看本例中的midclass:
数据表内容如下:
CREATE TABLE `farm_user2fruit` (
`uid` int(11) NOT NULL,
`fruitid` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
只有farm_user表的主键uid和farm_fruit表的主键fruitid,而这个表正是表达了farm_user表和farm_fruit表的对应关系。
好了,在配置好了farm_user类之后,我们可以试试查询一下了,在main.php中直接搜索farm_user类:
$results = M("farm_user")->relation()->findall();
print_r($results);
我们看到的输出是:
Array
(
[0] => Array
(
[uid] => 1
[username] => 灰太狼
[farms] =>
)
[1] => Array
(
[uid] => 2
[username] => 喜羊羊
[farms] => Array
(
[0] => Array
(
[fruitid] => 1
[fruitname] => 南瓜
)
[1] => Array
(
[fruitid] => 3
[fruitname] => 玫瑰
)
[2] => Array
(
[fruitid] => 4
[fruitname] => 青草
)
)
)
[2] => Array
(
[uid] => 3
[username] => 羊村长
[farms] =>
)
[3] => Array
(
[uid] => 4
[username] => 懒羊羊
[farms] => Array
(
[0] => Array
(
[fruitid] => 1
[fruitname] => 南瓜
)
[1] => Array
(
[fruitid] => 2
[fruitname] => 西瓜
)
)
)
[4] => Array
(
[uid] => 5
[username] => 暖羊羊
[farms] => Array
(
[0] => Array
(
[fruitid] => 4
[fruitname] => 青草
)
[1] => Array
(
[fruitid] => 6
[fruitname] => 圣诞树
)
[2] => Array
(
[fruitid] => 7
[fruitname] => 葡萄
)
)
)
)
这里可以看出,正如我们期待的那样,每条搜索到的记录都带上了他们关联的内容。
例子内我们还将演示如何用find来查询多对多的关联。
如何禁用和启用关联呢?其实很简单,M("user")->findall()就是不启用关联,M("user")->relation(TRUE)->findall()就是启用关联。
另外,如果我们只要查询关联记录的总记录数是多少,而不需要返回记录,要怎么做呢?
只要在$_linker内设置一下就行('count' => 'the_count')。如:
class UserModel extends Model
{
protected $linker = array(
array(
'type' => 'manytomany', // 多对多关联
'map' => 'farms', // 关联的标识
'midclass' => 'farm_user2fruit', // 关联的中间表
'mapkey' => 'uid', // 关联的字段
'fclass' => 'farm_fruit', // 对应表的数据类
'fkey' => 'fruitid', // 对应表的关联字段
'enabled' => true
'count' => 'the_count' // 只计算关联记录总数
),
);
}
加上了'count' => 'the_count',返回一个‘the_count’的数字,代表着关联有多少条件记录。
