站长百科 | 数字化技能提升教程 数字化时代生存宝典
首页
数字化百科
电子书
▼
建站程序
开发
服务器
办公软件
开发教程
▼
服务器教程
软件使用教程
运营教程
热门电子书
▼
CSS教程
WordPress教程
导航
程序频道
推广频道
网赚频道
人物频道
网站程序
网页制作
云计算
服务器
CMS
论坛
网店
虚拟主机
cPanel
网址导航
WIKI使用导航
WIKI首页
热点词条
最新资讯
网站程序
站长人物
页面分类
使用帮助
编辑测试
创建条目
网站地图
站长百科导航
站长百科
主机侦探
IDCtalk云说
跨境电商导航
WordPress啦
站长专题
网站推广
网站程序
网站赚钱
虚拟主机
cPanel
网址导航专题
云计算
微博营销
虚拟主机管理系统
开放平台
WIKI程序与应用
美国十大主机
编辑“
Xoops ORM对象关系映射2
”(章节)
人物百科
|
营销百科
|
网赚百科
|
站长工具
|
网站程序
|
域名主机
|
互联网公司
|
分类索引
跳转至:
导航
、
搜索
警告:
您没有登录。如果您做出任意编辑,您的IP地址将会公开可见。如果您
登录
或
创建
一个账户,您的编辑将归属于您的用户名,且将享受其他好处。
反垃圾检查。
不要
加入这个!
===模拟外键=== 在[[MySQL]]的数据库中,当使用REFERENCES tbl_name(col_name)子句定义列时可以使用外部关键字,但是仅有InnoDB类型的表有实际的处理,只作为备忘录或注释来提醒,目前正定义的列指向另一个表中的一个列,适用于表MyISAM和BerkeleyDB。Frameworks库提供了模拟外键的功能,虽然与InnoDB在数据库引擎中实现外键有一定差距,但是功能上要优于MyISAM或BerkeleyDB,本例将演示Frameworks库模拟外键的功能,文件夹结构如下: <pre> /modules/ormjoint /class /chapter.php /section.php /images /logo.png /sql /mysql.sql /templates /ormjoint_chapter.html /ormjoint_index.html /chapter.php /index.php /xoops_version.php </pre> 其中xoops_version.php的内容如下; <pre> /modules/ormjoint/xoops_version.php <?php $modversion['name'] = "ORM对象关系映射 - 模拟外键"; $modversion['version'] = 0.01; $modversion['description'] = "演示模拟数据库外键的查询"; $modversion['author'] = <<<AUTHOR 胡争辉 QQ: 443089607 QQMail: hu_zhenghui@qq.com GTalk: huzhengh GMail: huzhengh@gmail.com Skype: huzhenghui" AUTHOR; $modversion['credits'] = ""; $modversion['license'] = "版权所有"; $modversion['image'] = "images/logo.png"; $modversion['dirname'] = "ormjoint"; $modversion["hasMain"] = 1; $modversion["sqlfile"]["mysql"] = "sql/mysql.sql"; $modversion["tables"][] = "ormjoint_chapter"; $modversion["tables"][] = "ormjoint_section"; $modversion["templates"][0]["file"] = "ormjoint_index.html"; $modversion["templates"][0]["description"] = "Template for index.php"; $modversion["templates"][1]["file"] = "ormjoint_chapter.html"; $modversion["templates"][1]["description"] = "Template for chapter.php"; ?> </pre> 由于外键涉及两个数据表,所以本例的数据结构包括两个数据表。mysql.sql的内容如下: <pre> /modules/ormjoint/sql/mysql.sql CREATE TABLE `ormjoint_chapter` ( `id` int(11) NOT NULL auto_increment, `caption` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; INSERT INTO `ormjoint_chapter` (`id`, `caption`) VALUES (1, 'XOOPS模块开发'); INSERT INTO `ormjoint_chapter` (`id`, `caption`) VALUES (2, 'ORM对象关系映射'); CREATE TABLE `ormjoint_section` ( `id` int(11) NOT NULL auto_increment, `chapter_id` int(11) NOT NULL, `section_order` int(11) NOT NULL, `caption` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=18 ; INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (1, 1, 1, 'xoops_version.php'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (2, 1, 2, '模块普通页面'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (3, 1, 3, '模块管理页面'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (4, 1, 4, '数据表'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (5, 1, 5, '数据对象'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (6, 1, 6, '条件对象'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (7, 1, 7, '表单对象'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (8, 1, 8, '模板'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (9, 1, 9, '区块'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (10, 2, 1, '使用Frameworks库'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (11, 2, 2, '条件组合'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (12, 2, 3, '处理转义'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (13, 2, 4, '数据查询'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (14, 2, 5, '分页'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (15, 2, 6, '数据库安全'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (16, 2, 7, '数据操作'); INSERT INTO `ormjoint_section` (`id`, `chapter_id`, `section_order`, `caption`) VALUES (17, 2, 8, '模拟外键'); </pre> 相应的本例中有两个数据对象和数据访问句柄,对应于ormjoint_chapter数据表的数据对象和数据访问句柄源代码如下: <pre> /modules/ormjoint/class/chapter.php <?php /* 详见源代码 */ class OrmjointChapter extends ArtObject { function OrmjointChapter () { $this->ArtObject("ormjoint_chapter"); $this->initVar("id", XOBJ_DTYPE_INT); $this->initVar("caption", XOBJ_DTYPE_TXTBOX); return; } } class OrmjointChapterHandler extends ArtObjecthandler { function OrmjointChapterHandler($db) { $this->ArtObjectHandler($db, "ormjoint_chapter", "OrmjointChapter", "id", "caption"); return; } } ?> </pre> 结构和前面类似,而对应于ormjoint_section数据表的数据对象和数据访问句柄则略有差异,源代码如下: <pre> /modules/ormjoint/class/section.php <?php /* 详见源代码 */ class OrmjointSection extends ArtObject { function OrmjointSection () { $this->ArtObject("ormjoint_section"); $this->initVar("id", XOBJ_DTYPE_INT); $this->initVar("chapter_id", XOBJ_DTYPE_INT); $this->initVar("section_order", XOBJ_DTYPE_INT); $this->initVar("caption", XOBJ_DTYPE_TXTBOX); return; } } class OrmjointSectionHandler extends ArtObjecthandler { function OrmjointSectionHandler($db) { $this->ArtObjectHandler($db, "ormjoint_section", "OrmjointSection", "id", "caption"); $chapterhandler = xoops_getmodulehandler("chapter", "ormjoint"); /* @var $chapterhandler OrmjointChapterHandler */ $this->field_link = $chapterhandler->keyName; $this->field_object = "chapter_id"; $this->keyName_link = $chapterhandler->keyName; $this->table_link = $chapterhandler->table; return; } } ?> </pre> 由于ormjoint_chapter表的主键是ormjoint_section表的外键,所以在数据访问句柄的构造函数中先创建ormjoint_chapter表的数据访问句柄。 $chapterhandler = xoops_getmodulehandler("chapter", "ormjoint"); 然后设置field_link成员变量为父表的主键字段名。 $this->field_link = $chapterhandler->keyName; 下面设置field_object成员变量为子表的外键字段名。 $this->field_object = "chapter_id"; 接下来设置keyName_link成员变量为父表用于分组的字段名。 $this->keyName_link = $chapterhandler->keyName; 与外键相关的最后一个设置是table_link设置为父表的数据表表名。 $this->table_link = $chapterhandler->table; 通过这四项设置就完成了外键相关的设置,Frameworks库中与外键相关的功能都会调用相应的设置,而不需要为每个功能单独设置,因此本例中外键在数据访问句柄中直接设置。下面首先演示如何借助Frameworks库查询父对象对应的子对象的数目,index.php的源代码如下: <pre> /modules/ormjoint/index.php <?php require_once dirname(__FILE__)."/../../mainfile.php"; $chapterhandler = xoops_getmodulehandler("chapter", "ormjoint"); /* @var $chapterhandler OrmjointChapterHandler */ $sectionhandler = xoops_getmodulehandler("section", "ormjoint"); /* @var $sectionhandler OrmjointSectionHandler */ $xoopsOption["template_main"] = "ormjoint_index.html"; include XOOPS_ROOT_PATH."/header.php"; $xoopsTpl->assign_by_ref("chapters", $chapterhandler->getObjects(null, true)); $xoopsTpl->assign_by_ref("section_counts", $sectionhandler->getCountsByLink()); include XOOPS_ROOT_PATH."/footer.php"; ?> </pre> 在创建两个数据访问句柄后,获取所有的父对象并设置到模板中。 $xoopsTpl->assign_by_ref("chapters", $chapterhandler->getObjects(null, true)); 然后调用子对象数据访问句柄的getCountsByLink函数,按外键来对子对象中的数据分组统计。 $xoopsTpl->assign_by_ref("section_counts", $sectionhandler->getCountsByLink()); getCountsByLink函数是ArtObjectHandler类中动态调用ArtObjectJointHandler类的getCountsByLink函数,定义如下: <pre> /Frameworks/art/object.joint.php function getCountsByLink($criteria = null) {} </pre> 从页面的代码中会发现,两个数据访问句柄并没有直接互操作,这是因为在子表的数据访问句柄中定义了与父表的关系,所以不再需要额外的声明。本例中生成的SQL语句如下: SELECT l.id, COUNT(*) FROM xoops_ormjoint_section AS o LEFT JOIN xoops_ormjoint_chapter AS l ON o.chapter_id = l.id GROUP BY l.id; 该SQL语句就是依赖于与外键相关的几个成员变量实现的,在Frameworks库模拟外键时,子表的表名用o代表,父表的表名用l代表。相应的数据在模板中组合即可,对应模板的源代码如下: <pre> /modules/ormjoint/templates/ormjoint_index.html <{strip}> <{foreach from=$chapters key="key" item="chapter"}> <div> <a href="chapter.php?id=<{$key}>"> <{$key}> <{$chapters.$key->getVar("caption")}> ( <{$section_counts.$key}>) </a> </div> <{/foreach}> <{/strip}> </pre> 在模板中,首先对$chapters数组循环,显示主键的值。 <{$key}> 然后显示每个对象的caption字段的值。 <{$chapters.$key->getVar("caption")}> ( 接下来显示父对象对应于子对象的数量。 <{$section_counts.$key}>) 这里直接从getCountsByLink函数的返回值,按父对象的主键的值就获得了子对象的数量。效果如图2-15分组计算数量所示。 <div> [[Image:xop102.png]] </div> 从图中可以看到每个父对象显示相应的子对象数量。本例为每个父对象都设置了链接到子对象列表页面的链接。 <a href="chapter.php?id=<{$key}>"> 链接到的chapter.php页面源代码如下。 <pre> /modules/ormjoint/hapter.php <?php require_once dirname(__FILE__)."/../../mainfile.php"; $myts = MyTextSanitizer::getInstance(); /* @var $myts MyTextSanitizer */ $chapterhandler = xoops_getmodulehandler("chapter", "ormjoint"); /* @var $chapterhandler OrmjointChapterHandler */ if (true === isset($_GET["id"])) { $chapter = $chapterhandler->get($myts->stripSlashesGPC($_GET["id"])); /* @var $chapter OrmjointChapter */ } if (false === isset($chapter)) { redirect_header("index.php"); } $sectionhandler = xoops_getmodulehandler("section", "ormjoint"); /* @var $sectionhandler OrmjointSectionHandler */ $xoopsOption["template_main"] = "ormjoint_chapter.html"; include XOOPS_ROOT_PATH."/header.php"; $xoopsTpl->assign_by_ref("chapter", $chapter); $criteria = new Criteria("chapter_id", $chapter->getVar("id")); $criteria->setSort("section_order"); $criteria->setOrder("ASC"); $sections = $sectionhandler->getByLink($criteria, array("o.caption", "o.section_order")); $xoopsTpl->assign_by_ref("sections", $sections); include XOOPS_ROOT_PATH."/footer.php"; ?> </pre> 在页面中首先按照传入的id参数获取相应的$chapter对象,如果没有该对象则跳转到列表页面,这段逻辑与前例相同。如果有该对象,则把$chapter传入到模板中。 $xoopsTpl->assign_by_ref("chapter", $chapter); 接下来在ormjoint_section数据表中查询与$chapter对象对应的数据,首先创建查询对象。 $criteria = new Criteria("chapter_id", $chapter->getVar("id")); 然后设置排序的字段。 $criteria->setSort("section_order"); 下面设置排序方式为顺序。 $criteria->setOrder("ASC"); 构造条件对象后就可以调用数据访问句柄的getByLink函数查询。 $sections = $sectionhandler->getByLink($criteria, array("o.caption", "o.section_order")); 其中getByLink函数是ArtObjectHandler类中动态调用ArtObjectJointHandler类的getByLink函数,定义如下: <pre> /Frameworks/art/object.joint.php function &getByLink($criteria = null, $tags = null, $asObject = true, $field_link = null, $field_object = null) {} </pre> 其中$criteria参数是查询条件对象,$tags参数是期望查询的字段数组。本例中使用o.caption和o.section_order代表子表中的caption字段和section_order字段。例如传入参数id的值为1时,生成的SQL语句如下: SELECT o.caption,o.section_order,o.id FROM xoops_ormjoint_section AS o LEFT JOIN xoops_ormjoint_chapter AS l ON o.chapter_id = l.id WHERE chapter_id = '1' ORDER BY section_order ASC; 查询的结果直接设置到模板中。 $xoopsTpl->assign_by_ref("sections", $sections); 对应的模板源代码如下: <pre> /modules/ormjoint/templates/ormjoint_chapter.html <{strip}> <fieldset> <legend> <{$chapter->getVar("id")}> <{$chapter->getVar("caption")}> </legend> <{foreach from=$sections item="section" key="key"}> <div> <{$chapter->getVar("id")}>. <{$section->getVar("section_order")}> <{$section->getVar("caption")}> </div> <{/foreach}> </fieldset> <{/strip}> </pre> 模板中首先显示父对象,然后循环显示查询出的子对象数组,效果如图2-16查询子对象所示。 <div> [[Image:xop103.png]] </div>
摘要:
请注意,您对站长百科的所有贡献都可能被其他贡献者编辑,修改或删除。如果您不希望您的文字被任意修改和再散布,请不要提交。
您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源(参阅
Wordpress-mediawiki:版权
的细节)。
未经许可,请勿提交受版权保护的作品!
取消
编辑帮助
(在新窗口中打开)