果然还是我太弱了,看了好多教程都没明白zen’怎么回事,每次轮到自己操作的时候就会sh失败。
记录下来,成功了方便以后自己使用。
问题1:数据库需要做xia相应的关系绑定吗?比如设置外键主键什么的?
外键不用设置,但是主键要设置。
附上官方3.1的relation示例(虽然是示例但是我用的是3.2感觉不会搭建3.1的,最后3.2的搭建成功了。)
-- 数据库: `examples`
-- --------------------------------------------------------
-- 表的结构 `think_card`
CREATE TABLE IF NOT EXISTS `think_card` (
`id` mediumint(6) NOT NULL AUTO_INCREMENT,
`member_id` mediumint(6) NOT NULL,
`card` varchar(25) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ;
-- --------------------------------------------------------
-- 表的结构 `think_dept`
CREATE TABLE IF NOT EXISTS `think_dept` (
`id` smallint(3) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
-- 转存表中的数据 `think_dept`
INSERT INTO `think_dept` (`id`, `name`) VALUES
(1, '开发部'),
(2, '销售部'),
(3, '财务部');
-- --------------------------------------------------------
-- 表的结构 `think_groups`
CREATE TABLE IF NOT EXISTS `think_groups` (
`id` mediumint(6) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
-- 转存表中的数据 `think_groups`
INSERT INTO `think_groups` (`id`, `name`) VALUES
(1, '项目组1'),
(2, '项目组2'),
(3, '项目组3');
-- --------------------------------------------------------
-- 表的结构 `think_member`
CREATE TABLE IF NOT EXISTS `think_member` (
`id` mediumint(6) NOT NULL AUTO_INCREMENT,
`name` varchar(25) NOT NULL,
`dept_id` smallint(3) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=18 ;
-- --------------------------------------------------------
-- 表的结构 `think_member_groups`
CREATE TABLE IF NOT EXISTS `think_member_groups` (
`id` mediumint(6) NOT NULL AUTO_INCREMENT,
`groups_id` mediumint(5) NOT NULL,
`member_id` mediumint(5) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=333 ;
-- --------------------------------------------------------
-- 表的结构 `think_profile`
CREATE TABLE IF NOT EXISTS `think_profile` (
`id` mediumint(6) NOT NULL AUTO_INCREMENT,
`member_id` mediumint(6) NOT NULL,
`email` varchar(255) NOT NULL,
`nickname` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=18 ;
从sql中可以看出并没有做外键约束(就可以使用了),当然约束不约束的,我还是个弱鸡以后慢慢了解哪样好。
官方3.2的文档是写的很清楚了,但是还是不会做,是我太笨了吗?我在想是我做的和官方的示例有什么区别吗?
仔细看区别在哪里。
问题2:示例的模型是怎么绑定的?
这里我起初一直失败,看了对比才发现问题,于是我增加了self::下面代码中所有self::都是我加的
<?php
namespace Home\Model;//3.1示例原文没有这两句
use Think\Model\RelationModel;//当然3.2是这么做的
class MemberModel extends RelationModel {
protected $_link = array( //关联保存的规则://这里我也做了对应的修改,3.1示例内没有self::
'Profile' => self::HAS_ONE, //HAS_ONE 关联数据的更新直接赋值
'Dept' => self::BELONGS_TO, //关联数据的更新直接赋
'Card' => self::HAS_MANY, //HAS_MANY 的关联数据如果传入主键的值 则表示更新 否则就表示新增
'Groups' => self::MANY_TO_MANY, //更新是删除之前的数据后重新写入
);
}
问题3:看不懂示例这里,我查看其他例子有一些也都是这么写的为什么?
class IndexAction extends Action
我就直接写在自己的控制器的方法里。
public function hello(){
$User = D("Member");
$info[] = '关联数据操作开始';
G('1');
// 添加用户数据
$User->name = 'thinkphp';
$User->dept_id = 1;
// 用户档案数据
$User->Profile = array(
'email' => 'liu21st@gmail.com',
'nickname' => '流年',
);
// 用户的银行卡数据
$User->Card = array(
array('id'=>1,'card' => '12345678'),
array('id'=>2,'card' => '88888888'),
);
// 用户的所属项目组数据
$User->Groups = array(
array('id' => 1),
array('id' => 2),
);
$info[] = '<div class="result">'.dump($User->data(),false).'</div>';
// 关联添加用户数据
$id = $User->relation(true)->add();
$info[] = '用户数据关联写入完成!用时:'.G('1','2',6).'s';
// 关联查询
$user = $User->relation(true)->find($id);
$info[] = '查询用户ID为'.$id.'的所有关联数据,用时:'.G('2','3',6).'s';
$info[] = '<div class="result">'.dump($user,false).'</div>';
$user = $User->relation('Profile')->find($id);
$info[] = '查询用户ID为'.$id.'的用户档案关联数据,用时:'.G('3','4',6).'s';
$info[] = '<div class="result">'.dump($user,false).'</div>';
$list = $User->relation('Card')->order('id desc')->limit(2)->select();
$info[] = '查询用户的数据集并包含用户银行卡关联数据,用时:'.G('4','5',6).'s';
foreach ($list as $key=>$val){
$info[] = '<div class="result">'.dump($val,false).'</div>';
}
G('6');
// 关联更新
$user['id'] = $id;
$user['name'] = 'tp';
// HAS_ONE 关联数据的更新直接赋值
$user['Profile']['email'] = 'thinkphp@qq.com';
$user['dept_id'] = 2;
// 注意HAS_MANY 的关联数据要加上主键的值
// 可以更新部分数据
$user['Card'] = array(
array('id' => 1, 'card' => '66666666'), // 更新主键为1的记录
array('card'=> '77777777'), // 增加一条新的记录
);
// MANY_TO_MANY 的数据更新是重新写入
$user['Groups'] = array(
array('id' => 2),
array('id' => 3),
);
$User->where(array('id'=>$id))->relation(true)->save($user);
$info[] = '用户数据关联更新完成!用时:'.G('6','7',6).'s';
// 查询更新后的数据
$user = $User->relation(true)->find($id);
$info[] = '查询更新后的用户ID为'.$id.'的用户关联数据,用时:'.G('7','8',6).'s';
$info[] = '<div class="result">'.dump($user,false).'</div>';
// 关联删除
$User->relation(true)->delete($id);
$info[] = '用户ID为' . $id . '数据关联删除完成!用时:'.G('8','9',6).'s';
$this->assign('info',$info);
$this->display();
}
然后我把示例里的tpl放在view里对应的hello.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> ThinkPHP示例:关联操作 </title>
<style type="text/css">
*{ padding: 0; margin: 0;font-size:16px; font-family: "微软雅黑"}
div{ padding: 25px 20px;}
body{ background: #fff; color: #333;}
h2{font-size:36px}
div.result{border:1px solid #d4d4d4;background:#FFC;color:#393939; padding:8px 20px;float:auto; width:450px;margin:2px}
pre{font-size:12px;}
</style>
</head>
<body>
<div >
<h2>ThinkPHP示例:关联操作</h2>
<foreach name="info" item="i">
{$i}<br/>
</foreach>
</div>
</body>
</html>
于是3.2的关联模型就运行成功了。
说起来很简单,但是做起来还是出问题,当然成功一次后应该就好了哈哈。
好了,现在要开始做修改了。
- 把think_member表内的idzi’d字段改成uid。
其他一切不变。进行关联添加操作。
我发现操作一切正常。
这里出现了一点小问题,是我对D函数的理解不透彻,我平时用的时候都直接写数据库的表名都可以正常访问使用。
实际上看文档的意思是D或者M对应的是实例化模型,模型首字母大写,所以正确的写法应该是D(‘Member’)捂脸,不知道我这些年都是怎么写的。
这个习惯导致了一个问题!
添加数据的时候示例使用的是对象的方式添加的
$User->Profile = array(
'email' => 'liu21st@gmail.com',
'nickname' => '流年',
);
而我是使用数组的方式添加的
$data = array();
$data['name']='张三';
$data['dept_id']=66;
$data['Profile']=array(
'email' => 'zhangsan@qq.com',
'nickname' => '流年',
);
这里刚开始操作的时候失败了,我仔细检查了下原因,原来是Profile写成 了profile导致的,这里对应的竟然是大写的,小写不行。还有绑定关系的时候也要注意都是大写的,顾名思义,是关联“模型”模型首字母大写,我错误的用法导致了不区分大小写的操作。
'Card' => self::HAS_MANY,
好了,到了这里,仅仅修改了一个member表的id改成uid,一切正常。记录下。
接下来,修改了profile表的字段,把member_id改成了uid,出问题了。
foreign_key : 关联的外键名称
外键的默认规则是当前数据对象名称_id,例如: UserModel对应的可能是表think_user (注意:think只是一个表前缀,可以随意配置) 那么think_user表的外键默认为 user_id,如果不是,就必须在定义关联的时候显式定义 foreign_key 。
果然还是我太弱了,看了好多教程都没明白zen’怎么回事,每次轮到自己操作的时候就会sh失败。
记录下来,成功了方便以后自己使用。
问题4:数据库需要做xia相应的关系绑定吗?比如设置外键主键什么的?
外键不用设置,但是主键要设置。
附上官方3.1的relation示例(虽然是示例但是我用的是3.2感觉不会搭建3.1的,最后3.2的搭建成功了。)
-- 数据库: `examples`
-- --------------------------------------------------------
-- 表的结构 `think_card`
CREATE TABLE IF NOT EXISTS `think_card` (
`id` mediumint(6) NOT NULL AUTO_INCREMENT,
`member_id` mediumint(6) NOT NULL,
`card` varchar(25) CHARACTER SET latin1 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ;
-- --------------------------------------------------------
-- 表的结构 `think_dept`
CREATE TABLE IF NOT EXISTS `think_dept` (
`id` smallint(3) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
-- 转存表中的数据 `think_dept`
INSERT INTO `think_dept` (`id`, `name`) VALUES
(1, '开发部'),
(2, '销售部'),
(3, '财务部');
-- --------------------------------------------------------
-- 表的结构 `think_groups`
CREATE TABLE IF NOT EXISTS `think_groups` (
`id` mediumint(6) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
-- 转存表中的数据 `think_groups`
INSERT INTO `think_groups` (`id`, `name`) VALUES
(1, '项目组1'),
(2, '项目组2'),
(3, '项目组3');
-- --------------------------------------------------------
-- 表的结构 `think_member`
CREATE TABLE IF NOT EXISTS `think_member` (
`id` mediumint(6) NOT NULL AUTO_INCREMENT,
`name` varchar(25) NOT NULL,
`dept_id` smallint(3) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=18 ;
-- --------------------------------------------------------
-- 表的结构 `think_member_groups`
CREATE TABLE IF NOT EXISTS `think_member_groups` (
`id` mediumint(6) NOT NULL AUTO_INCREMENT,
`groups_id` mediumint(5) NOT NULL,
`member_id` mediumint(5) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=333 ;
-- --------------------------------------------------------
-- 表的结构 `think_profile`
CREATE TABLE IF NOT EXISTS `think_profile` (
`id` mediumint(6) NOT NULL AUTO_INCREMENT,
`member_id` mediumint(6) NOT NULL,
`email` varchar(255) NOT NULL,
`nickname` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=18 ;
从sql中可以看出并没有做外键约束(就可以使用了),当然约束不约束的,我还是个弱鸡以后慢慢了解哪样好。
官方3.2的文档是写的很清楚了,但是还是不会做,是我太笨了吗?我在想是我做的和官方的示例有什么区别吗?
仔细看区别在哪里。
问题5:示例的模型是怎么绑定的?
这里我起初一直失败,看了对比才发现问题,于是我增加了self::下面代码中所有self::都是我加的
<?php
namespace Home\Model;//3.1示例原文没有这两句
use Think\Model\RelationModel;//当然3.2是这么做的
class MemberModel extends RelationModel {
protected $_link = array( //关联保存的规则://这里我也做了对应的修改,3.1示例内没有self::
'Profile' => self::HAS_ONE, //HAS_ONE 关联数据的更新直接赋值
'Dept' => self::BELONGS_TO, //关联数据的更新直接赋
'Card' => self::HAS_MANY, //HAS_MANY 的关联数据如果传入主键的值 则表示更新 否则就表示新增
'Groups' => self::MANY_TO_MANY, //更新是删除之前的数据后重新写入
);
}
问题6:看不懂示例这里,我查看其他例子有一些也都是这么写的为什么?
class IndexAction extends Action
我就直接写在自己的控制器的方法里。
public function hello(){
$User = D("Member");
$info[] = '关联数据操作开始';
G('1');
// 添加用户数据
$User->name = 'thinkphp';
$User->dept_id = 1;
// 用户档案数据
$User->Profile = array(
'email' => 'liu21st@gmail.com',
'nickname' => '流年',
);
// 用户的银行卡数据
$User->Card = array(
array('id'=>1,'card' => '12345678'),
array('id'=>2,'card' => '88888888'),
);
// 用户的所属项目组数据
$User->Groups = array(
array('id' => 1),
array('id' => 2),
);
$info[] = '<div class="result">'.dump($User->data(),false).'</div>';
// 关联添加用户数据
$id = $User->relation(true)->add();
$info[] = '用户数据关联写入完成!用时:'.G('1','2',6).'s';
// 关联查询
$user = $User->relation(true)->find($id);
$info[] = '查询用户ID为'.$id.'的所有关联数据,用时:'.G('2','3',6).'s';
$info[] = '<div class="result">'.dump($user,false).'</div>';
$user = $User->relation('Profile')->find($id);
$info[] = '查询用户ID为'.$id.'的用户档案关联数据,用时:'.G('3','4',6).'s';
$info[] = '<div class="result">'.dump($user,false).'</div>';
$list = $User->relation('Card')->order('id desc')->limit(2)->select();
$info[] = '查询用户的数据集并包含用户银行卡关联数据,用时:'.G('4','5',6).'s';
foreach ($list as $key=>$val){
$info[] = '<div class="result">'.dump($val,false).'</div>';
}
G('6');
// 关联更新
$user['id'] = $id;
$user['name'] = 'tp';
// HAS_ONE 关联数据的更新直接赋值
$user['Profile']['email'] = 'thinkphp@qq.com';
$user['dept_id'] = 2;
// 注意HAS_MANY 的关联数据要加上主键的值
// 可以更新部分数据
$user['Card'] = array(
array('id' => 1, 'card' => '66666666'), // 更新主键为1的记录
array('card'=> '77777777'), // 增加一条新的记录
);
// MANY_TO_MANY 的数据更新是重新写入
$user['Groups'] = array(
array('id' => 2),
array('id' => 3),
);
$User->where(array('id'=>$id))->relation(true)->save($user);
$info[] = '用户数据关联更新完成!用时:'.G('6','7',6).'s';
// 查询更新后的数据
$user = $User->relation(true)->find($id);
$info[] = '查询更新后的用户ID为'.$id.'的用户关联数据,用时:'.G('7','8',6).'s';
$info[] = '<div class="result">'.dump($user,false).'</div>';
// 关联删除
$User->relation(true)->delete($id);
$info[] = '用户ID为' . $id . '数据关联删除完成!用时:'.G('8','9',6).'s';
$this->assign('info',$info);
$this->display();
}
然后我把示例里的tpl放在view里对应的hello.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> ThinkPHP示例:关联操作 </title>
<style type="text/css">
*{ padding: 0; margin: 0;font-size:16px; font-family: "微软雅黑"}
div{ padding: 25px 20px;}
body{ background: #fff; color: #333;}
h2{font-size:36px}
div.result{border:1px solid #d4d4d4;background:#FFC;color:#393939; padding:8px 20px;float:auto; width:450px;margin:2px}
pre{font-size:12px;}
</style>
</head>
<body>
<div >
<h2>ThinkPHP示例:关联操作</h2>
<foreach name="info" item="i">
{$i}<br/>
</foreach>
</div>
</body>
</html>
于是3.2的关联模型就运行成功了。
说起来很简单,但是做起来还是出问题,当然成功一次后应该就好了哈哈。
好了,现在要开始做修改了。
- 把think_member表内的字段改成uid。
其他一切不变。进行关联添加操作。
我发现操作一切正常。
这里出现了一点小问题,是我对D函数的理解不透彻,我平时用的时候都直接写数据库的表名都可以正常访问使用。
实际上看文档的意思是D或者M对应的是实例化模型,模型首字母大写,所以正确的写法应该是D(‘Member’)捂脸,不知道我这些年都是怎么写的。
这个习惯导致了一个问题!
添加数据的时候示例使用的是对象的方式添加的
$User->Profile = array(
'email' => 'liu21st@gmail.com',
'nickname' => '流年',
);
而我是使用数组的方式添加的
$data = array();
$data['name']='张三';
$data['dept_id']=66;
$data['Profile']=array(
'email' => 'zhangsan@qq.com',
'nickname' => '流年',
);
这里刚开始操作的时候失败了,我仔细检查了下原因,原来是Profile写成 了profile导致的,这里对应的竟然是大写的,小写不行。还有绑定关系的时候也要注意都是大写的,顾名思义,是关联“模型”模型首字母大写,我错误的用法导致了不区分大小写的操作。
'Card' => self::HAS_MANY,
好了,到了这里,仅仅修改了一个member表的id改成uid,一切正常。记录下。
接下来,修改了profile表的字段,把member_id改成了uid,出问题了。
foreign_key : 关联的外键名称
外键的默认规则是当前数据对象名称_id,例如: UserModel对应的可能是表think_user (注意:think只是一个表前缀,可以随意配置) 那么think_user表的外键默认为 user_id,如果不是,就必须在定义关联的时候显式定义 foreign_key 。
这里是官方3.2文档的描述(我打字太快,老是会出英文,这编辑器真cha’差劲,切换到mdshi’试试…额,谁教教我怎么转换?)
再次注意,foreign_key对应的是要绑定的模型(Profile)的对应的表内的字段名,而这个字段名就是外键,名字不要求和Member模型内的主键名字(最初是id,后来改成了uid)一致,但是要求这个uid是member表对应的主键,不然怎么叫外键呢。
绑定的时候Profile的uid和Member的主键(id,后来改成uid)绑定。