CakePHP 3 ORM如何基于非主键app_id关联article_95表
解决CakePHP 3.x中遗留数据库的特殊关联问题
你的问题核心在于CakePHP ORM默认会用主表的主键来建立关联,但你的遗留数据库里article_95表需要和substances表的app_id字段关联,而不是主键id。只需要给关联配置加上bindingKey参数就能搞定,其他基于id的关联不受影响。
修改SubstancesTable的关联配置
在SubstancesTable的hasMany关联里,明确指定用app_id作为主表的关联字段:
// src/Model/Table/SubstancesTable.php public function initialize(array $config) { $this->setTable('substances'); $this->setPrimaryKey('id'); $this->hasMany('Article95s', [ 'foreignKey' => 'app_id', 'bindingKey' => 'app_id' // 新增:指定主表用app_id字段关联 ]); // 其他关联保持不变,比如Cas表的关联 }
修改Article95sTable的关联配置
对应的,在Article95sTable的belongsTo关联里也要加上bindingKey,确保双向关联都使用app_id匹配:
// src/Model/Table/Article95sTable.php public function initialize(array $config) { $this->setTable('article_95'); $this->setPrimaryKey('tbl_id'); $this->belongsTo('Substances', [ 'foreignKey' => 'app_id', 'bindingKey' => 'app_id', // 新增:关联主表的app_id字段 'joinType' => 'INNER' ]); }
关键参数说明
foreignKey:指当前表(子表)中存储关联值的字段,这里Article95s的app_id是对的,不用改。bindingKey:指关联主表中用来匹配的字段,默认是主表的主键id,我们把它改成app_id后,ORM生成的SQL就会用Substances.app_id = Article95s.app_id来关联,完美适配你的遗留数据库结构。
测试验证
你可以用一个简单的查询来验证效果:
$substance = $this->Substances->find() ->contain(['Article95s']) ->where(['Substances.id' => 1]) ->first();
查看生成的SQL,会发现关联article_95表的条件已经变成了INNER JOIN article_95 Article95s ON (Article95s.app_id = Substances.app_id),完全符合你的需求。其他基于substances.id的关联依然会正常使用主键匹配,不会受到影响。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

