在Yii2.0框架中,利用migration文件创建数据库表时,经常需要对表中的字段进行外键约束处理:比如:teacher表中的数据必须是user表中的数据,那么在创建teacher表的时候就需要添加外键约束:
CONSTRAINT `user_tenant` FOREIGN KEY (`tenant_dbu`) REFERENCES `tbl_tenant` (`dbu`)
这种做法虽然正确,但会给后期删除数据带来一定的麻烦,例如要删除user表的中数据时,如果teacher表中存在与之有外键约束的记录,那么删除就会失败,错误就是因为存在外键约束。在这种情况下的处理方法有以下几种:
方法1:删除外键法
这种方法是创建migration文件,删除teacher表对应的外键约束即可,但这种方法并不好,因为这会使得teacher表中存在非user表记录的问题。
方法2:级联删除法
这种方法是在使用migration文件创建表,外键约束语句改为如下代码:
CONSTRAINT `teacher_user` FOREIGN KEY (`user_id`) REFERENCES `tbl_user` (`id`) ON DELETE cascade)
注意,这里设置的是ON DELETE CASCADE,表示在删除user表数据时,同时删除teacher表中有外键约束的记录。此外,如果设置为ON DELETE ON ACTION,表示如果试图删除某一行,而该行的键被其他表的现有行中的外键所引用,则产生错误并回滚 DELETE 语句。
方法3:使用beforeDelete()方法
先看一下Yii2.0文档中的解释。
This method is invoked before deleting a record.The default implementation raises the EVENT_BEFORE_DELETE event. When overriding this method, make sure you call the parent implementation like the following:
顾名思义,在删除操作之前触发该函数。那么在删除user表中记录之前,就可以在beforeDelete方法中查询teacher表中外键引用的记录,然后删除,再执行user表中的删除就没有问题了。
使用方法:
public function beforeDelete()
{
// ...custom code here...
return parent::beforeDelete();
}
说到beforeDelete()方法,类似的还有beforeSave(), beforeValidate()方法等,使用方法基本一样,注意不要忘记最后调用父类的beforeDelete()方法即可。