namespace app\common\traits\model;
use think\db\Query;
use think\Model;
trait RelationHelpers
{
/*** 使用关联查询(别名,Model对象调用)* @param mixed $relation 子模型对象* @param null $alias 子模型别名(单个关联时有效)* @param null $condition 关联条件* @param string $joinType JOIN类型* @return Query*/
public function useRelationQuery(
$relation,
$alias = null,
$condition = null,
$joinType = 'INNER'
) {
return $this->handldRelationQuery($this, $relation, $alias, $condition, $joinType);
}
/*** 使用关联查询(别名,Query对象调用)* @param Query $parent 父Query对象* @param null $relation 子模型对象* @param null $alias 子模型别名(单个关联时有效)* @param null $condition 关联条件* @param string $joinType JOIN类型* @return Query*/
public function scopeUseRelationQuery(
Query $parent,
$relation,
$alias = null,
$condition = null,
$joinType = 'INNER'
) {
return $this->handldRelationQuery($parent->getModel(), $relation, $alias, $condition, $joinType);
}
/*** 使用关联查询(支持跨库查询)* @param Model $parent 父模型对象* @param mixed $relation 子模型对象* @param null $relationAlias 子模型别名(单个关联时有效)* @param null $condition 关联条件* @param string $joinType JOIN类型* @return Query** 参数说明* parent* 父模型对象* relation* 关联的子模型对象。多个模型关联时,可传入一个数组* 数组格式:[Model relation, string|null relationAlias, mixed condition, string joinType]* relationAlias* 子模型别名。单个关联时有效,如果参数值为 null 时,默认以模型类名作为别名* condition* 关联条件。可以为字符串或数组, 为数组时每一个元素都是一个关联条件* joinType* 关联类型。可以为:INNER、LEFT、RIGHT、FULL,不区分大小写,默认为INNER** Example* 单个关联:(new TestA())->useRelationQuery(new TestB(), null, 'TestA.id=Test.id');* 多个关联:(new TestA())->useRelationQuery([[new TestB(), null, 'TestA.id=Test.id']]);*/
public function handldRelationQuery(
Model $parent,
$relation,
$relationAlias = null,
$condition = null,
$joinType = 'INNER'
) {
list($parentTable, $parentTableAlias) = $this->getJoinTable($parent);
$aliass = $parent->getOptions('alias');
$parentTableAlias = empty($alias = $aliass[$parent->getTable()]) ? $parentTableAlias : $alias;
$this->setTable($parentTable)->alias($parentTableAlias);
if (empty($condition)) {
// 如果为组数,则循环调用join foreach ($relation as $_join) {
list($model, $alias, $condition, $joinType) = array_pad($_join, 4, null);
list($childTable, $tableAlias) = $this->getJoinTable($model);
$childTableAlias = $alias ?: $tableAlias;
$this->join(
[$childTable => $childTableAlias],
$condition,
$joinType ?: 'INNER'
);
}
} else {
list($childTable, $tableAlias) = $this->getJoinTable($relation);
$childTableAlias = $relationAlias ?: $tableAlias;
$this->join(
[$childTable => $childTableAlias],
$condition,
$joinType
);
}
return $this;
}
/*** 获取JOIN表名及别名* @param Model $query* @return array*/
protected function getJoinTable(Model $query)
{
$table = $query->getConfig('database') . '.' . $query->getTable();
$tableAlias = basename(str_replace('\\', '/', get_class($query)));
return [$table, $tableAlias];
}
}