#1 jake

spLinker多对多关联是很容易理解的,以下我们举个例子来说明spLinker的多对多关联的用法。

下载多对多关联例子:farm-splinker[1].rar
请注意要先在数据库内导入例子中的SQL文件,这样更有利于理解多对多例子。
最近喜羊羊的村落也非常喜欢种菜(QQ农场)了,所以全部的人(羊?)都种了不少的菜,而且各人种的种类也不尽相同。据我们的调查,他们所种的菜是以下关系:


linkerfarmers[1].jpg

让我们从编程的角度来看,不同的羊种了不同的菜,同时也可以说不同的菜被不同的羊种了,这就是多对多的关系。

下面我们使用程序来描述他们之间的关系,在user的数据类中,定义和fruit表的多对多关系,定义后的farm_user.php如下:

class farm_user extends spModel
{
        public $pk = 'uid';
        public $table = 'user';

        var $linker = array(
                array(
                                'type' => 'manytomany',   // 多对多关联
                                'map' => 'farms',    // 关联的标识
                                'midclass' => 'farm_user2fruit', // 关联的中间表
                                'mapkey' => 'uid',  // 关联的字段
                                'fclass' => 'farm_fruit', // 对应表的数据类
                                'fkey' => 'fruitid', // 对应表的关联字段
                                'enabled' => true
                ),
        );
}
这里要注意和一对多区别的除了type之外,多对多关联还有了midclass,midclass是一个数据库类,对应了一个存储着多对多两表之间的关系。我们可以看看本例中的midclass:

farm_user2fruit.php
class farm_user2fruit extends spModel
{
        public $pk = 'uid';
        public $table = 'user2fruit';
}
数据表内容如下:
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 = spClass("farm_user")->spLinker()->findAll();
dump($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来查询多对多的关联。
如何禁用和启用关联呢?其实很简单,spClass("user")->findAll()就是不启用关联,spClass("user")->spLinker()->findAll()就是启用关联。

另外,如果我们只要查询关联记录的总记录数是多少,而不需要返回记录,要怎么做呢?

只要在$linker内设置一下就行('countonly' => true)。如:

class farm_user extends spModel
{
        public $pk = 'uid';
        public $table = 'user';

        var $linker = array(
                array(
                                'type' => 'manytomany',   // 多对多关联
                                'map' => 'farms',    // 关联的标识
                                'midclass' => 'farm_user2fruit', // 关联的中间表
                                'mapkey' => 'uid',  // 关联的字段
                                'fclass' => 'farm_fruit', // 对应表的数据类
                                'fkey' => 'fruitid', // 对应表的关联字段
                                'enabled' => true
                                'countonly' => true // 只计算关联记录总数
                ),
        );
}

加上了'countonly' => true,返回的将不再是关联表的记录,而是一个数字,代表着关联有多少条件记录。

同时,'countonly' => true,在一对多关联中也有同样的作用。


2012-08-04 22:43:49