# 关联模型 在实际开发中,表与表之间产生联系,是特别常见的。这个时候查询起来,就比较麻烦了,要么自己手动join写查询语句,要么使用join()连贯操作。 这里我们更建议使用模型中的“关联”查询功能,将复杂的查询交给TP去做,我们自己只把控好我们自己的业务逻辑(系统中,就几乎没有自己手动join或使用join()连贯操作,全部使用关联交给TP自己去查)。 TP本身的关联操作,这里不做详细介绍 → [关联操作传送门](https://www.kancloud.cn/manual/thinkphp6_0/1037599)。 很多人不用关联的原因是对关联中几种关系hasOne、belongsTo、hasMany理解不够,这里我以前写过一篇帖子,有兴趣的可以在“问答”中看下。 ### 总览格式 比如“文章”模型中,关联有“栏目”、“用户” ~~~ public $relationLink = array( 'Menu' => array( 'type' => 'belongsTo', 'foreignKey' => 'menu_id', 'localKey' => 'id', 'counterCache' => true ), 'User' => array( 'type' => 'belongsTo' ) ); ~~~ 可以同时定义多个关联模型,格式:`关联模型名 => 关联属性`。 这样定义以后,就不用像TP那样去定义一个关联function了;然后使用的时候和TP一样: ~~~ $article = model('Article')->find();//查询文章 $article = $article->Menu;//关联到Menu数据 $article = $article->User;//关联到User数据 pr($article->toArray());//从对象中获取到数据 //最后,得到的数据结构: Array ( [id] => 1 [menu_id] => 3 [user_id] => 1 [title] => 测试 ...... [Menu] => Array ( [id] => 3 [title] => 新闻 ...... ) [User] => Array ( [id] => 1 [username] => eduask ...... ) ) ~~~ * * * * * ### hasOne定义 ~~~ public $relationLink = [ '关联模型名'=>[ 'type' => 'hasOne', 'foreign' => '关联模型名', 'foreignKey' => '外键名', 'localKey' => '主键名', 'deleteWith' => true, 'field' => [关联查询时字段], 'where' => [关联查询时额外条件], 'order' => [关联查询时排序方式] ] ]; public $relationLink = [ '关联模型名' => 'hasOne' ]; ~~~ `type`:string 关联类型,**必须**含有该属性且值为`hasOne` `foreign`:string 关联模型名,没有设置自动使用 数组所在键名 `foreignKey`:string 关联外键名,默认为 `当前模型小写形式_id`。 比如:User 对应 user_id ,AdPosition 对应 ad_position_id `localKey`:string 默认为"",交给tp自己处理(tp默认肯定就是`id`) `deleteWith`:boolean 关联删除,系统自己增加功能;默认不会关联删除 比如,`User`模型中: ~~~ public $relationLink = array( 'Profile' => array( 'type' => 'hasOne', 'deleteWith' => true ) ); ~~~ 当删除一条用户记录时,关联的用户信息记录也会被自动删除 `field`:array 关联查询时字段,同`field()`用法,一般不会定义;后面几个属性同理。 * * * * * ### hasMany定义 ~~~ public $relationLink =[ '关联模型名' => [ 'type' => 'hasMany', 'foreign' => '关联模型名', 'foreignKey' => '外键名', 'localKey' => '主键名', 'deleteWith' => true, 'field' => [关联查询时字段], 'where' => [关联查询时额外条件], 'order' => [关联查询时排序方式], 'limit' => 2 ] ]; public $relationLink = [ '关联模型名' => 'hasMany' ]; ~~~ `type`:string 关联类型,**必须**含有该属性且值为`hasMany` `foreign`:string 关联模型名,没有设置自动使用 数组所在键名 `foreignKey`:string 关联外键名,默认为 `当前模型小写形式_id`。 比如:User 对应 user_id ,AdPosition 对应 ad_position_id `localKey`:string 默认为"",交给tp自己处理(tp默认肯定就是`id`) `deleteWith`:boolean 关联删除,系统自己增加功能; 比如,`AdPosition`模型中: ~~~ public $relationLink = array( 'Ad' => array( 'type' => 'hasMany', 'deleteWith' => true ) ); ~~~ 当删除一条广告位记录,关联的所有广告记录都将会被自动删除 `field`:array 关联查询时字段,同`filed()`用法,一般不会定义;后面几个属性同理。 * * * * * ### belongsTo 定义 ~~~ public $relationLink =[ '关联模型名' => [ 'type' => 'belongsTo', 'foreign' => '关联模型名', 'foreignKey' => '外键名', 'localKey' => '主键名', 'counterCache' => '关联统计字段', 'counterWhere' => [关联统计额外条件],// V2.3.1新增 'sumCache' => '关联求和统计字段',// V2.3.1新增 'sumCacheTo' => '求和以后更新到父模型的字段名'// V2.3.1新增 'sumWhere' => [关联求和统计额外条件],// V2.3.1新增 'field' => [关联查询时字段], 'where' => [关联查询时额外条件], 'order' => [关联查询时排序方式], ] ]; public $relationLink = [ '关联模型名' => 'belongsTo' ]; ~~~ `type`:string 关联类型,**必须**含有该属性且值为`belongsTo` `foreign`:string 关联模型名,没有设置自动使用 数组所在键名 `foreignKey`:string 外键名,默认为 `关联模型小写形式_id`。 比如:User 对应 user_id ,AdPosition 对应 ad_position_id `localKey`:string 关联表主键名 默认为"",交给tp自己处理(tp默认肯定就是`id`) `counterCache` :boolean 或 string 关联统计计数,系统自己增加功能,默认不会统计;如果为true,关联统计字段为 `当前模型小写形式_count`,如果为字符串,表示以此为关联统计字段。 比如,`Ad`模型中: ~~~ public $relationLink = array( 'AdPosition' => array( 'type' => 'belongsTo', 'counterCache' => true ) ); ~~~ 这样你的AdPosition模型中需要有一个字段叫`ad_count`,每当广告添加或删除时,对应广告位就会重新统计含有多少条广告记录并更新到该字段。 `field`:array 关联查询时字段,同`filed()`用法,一般不会定义;后面几个属性同理。 `sumCache`:string 关联求和统计,系统自己增加功能,默认不会统计;还必须有 'sumCacheTo' 属性:当前模型数据变动时会统计当前模型中sumCache所设字段之和然后更新到父模型(当前关联模型)的sumCacheTo所设字段中。 `V2.3.4`以后支持多个字段,多个字段之间用逗号`,`分隔;相应的`sumCacheTo`也应该是对应的多个字段。 `sumCacheTo`:string 父模型的统计求和字段,需和sumCache属性配合。 * * * * * ### belongsToMany 定义 ~~~ public $relationLink =[ '关联模型名' => [ 'type' => 'belongsToMany', 'foreign' => '关联模型名', 'middle' => '中间表名', 'foreignKey' => '外键名', 'localKey' => '当前模型关联键名' ] ]; ~~~ `type`:string 关联类型,**必须**含有该属性且值为`belongsToMany` `middle`:string 中间表名,**必须**定义中间表对应的模型名 `foreign`:string 关联模型名,没有设置自动使用 数组所在键名 `foreignKey` :string,中间表的当前模型外键,默认的外键名规则是关联模型名+`_id` `localKey`:string,中间表的当前模型关联键名,默认规则是当前模型名+`_id` `deleteWith`:boolean,默认false;当前模型数据删除以后,自动删除中间表(非关联模型数据)相关联的数据