thinkphp6模型中联合主键、中间表调用的写法——小白篇,高手勿喷

993 阅读1分钟

前言

Thinkphp框架是不错,但是一些特殊用法几乎找不到文档。 模型就新手来说感觉会很麻烦,但是实际上习惯之后会很方便,比如入库和出库的自动格式化,再比如安全的入库。而且模型会让你养成良好的开发习惯,数据库定义后,程序上也再次做对应。

联合主键

默认主键为id,如果你没有使用id作为主键名,需要在模型中通过$this->pk设置属性。

如果是联合主键,设置的时候,将pk设置为数组即可。 单主键:

protected $pk = 'uid';

联合主键:

protected $pk = ['uid','tid'];

无主键:暂时还没有找到资料

中间表

官方文档:模型 - 模型关联 - 关联预载入 中有讲到 with方法也可以支持嵌套预载入,例如:

$list = User::with(['profile.phone'])->select([1,2,3]);
foreach($list as $user){
    // 获取用户关联的phone模型
    dump($user->profile->phone);
}

支持使用数组方式定义嵌套预载入,例如下面的预载入要同时获取用户的Profile关联模型的PhoneJobImg子关联模型数据:

$list = User::with(['profile'=>['phone','job','img']])->select([1,2,3]);
foreach($list as $user){
    // 获取用户关联
    dump($user->profile->phone);
    dump($user->profile->job);
    dump($user->profile->img);
}

示例

表结构

tags

CREATE TABLE `tags`  (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(100) NOT NULL DEFAULT '' COMMENT '名称',
  PRIMARY KEY (`id`)
);

news

CREATE TABLE `news`  (
  `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
  `title` varchar(100) NOT NULL DEFAULT '' COMMENT '标题',
  `content` varchar(5000) NOT NULL COMMENT '内容',
  PRIMARY KEY (`id`)
);

中间表news_tags

CREATE TABLE `news_tags`  (
  `tag_id` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'tagid',
  `news_id` int(10) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'newsid',
  PRIMARY KEY (`tag_id`, `news_id`)
);

模型

Tags模型

class Tags extends BaseModel {
	// 表
	protected $name = 'tags';
	protected $pk = 'id';


	// 设置字段信息
	protected $schema = [
		'id' => 'int',
		'name' => 'string',
=	];
}

News模型

class News extends BaseModel {
	// 表
	protected $name = 'news';
	protected $pk = 'id';


	// 设置字段信息
	protected $schema = [
		'id' => 'int',
		'title' => 'string',
		'content' => 'string'
	];
	
	// 模型关联NewsTags 一对多关联 调用采用with('tags.tag')=NewsTags.tag关联
	public function tags() {
		return $this->hasMany(NewsTags::class, 'news_id', 'id');
	}
}

中间表NewsTags模型

class NewsTags extends BaseModel {
	// 表
	protected $name = 'news_tags';
	// 联合主键
	protected $pk = ['news_id', 'tag_id'];


	// 设置字段信息
	protected $schema = [
		'news_id' => 'int',
		'tag_id' => 'int',
	];

	// 模型关联 一对一属于关联
	public function tag() {
		return $this->belongsTo(Tags::class, 'tag_id', 'id')->bind(['tag_name' => 'name']);
	}

	// 自动时间
	// protected $createTime = 'time1';
	// protected $updateTime = 'time2';

}

调用:

//News模型中的tags关联,tags关联(NewsTags模型)中的tag关联
$model = News::with('tags.tag')->where('id', $id)->find();
print_r($model);

$model->tags 数据如下(如果有的话):

[	{		"news_id": 3,		"tag_id": 1,		"tag_name": "知识点"	},	{		"news_id": 3,		"tag_id": 2,		"tag_name": "测试"	}]