Skip to content

Latest commit

 

History

23 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

ORM 模型关联

数据库表通常相互关联。例如,一篇博客文章可能有很多评论,或者一个订单对应一个下单用户。 ORM 让这些关联的管理和使用变得简单,并支持多种类型的关联

1.1 composer

composer require devweyes/db-orm

1.2 实体需继承 Model

class Model extends \Jcsp\Orm\Eloquent\Model

一般只需定义两个注解,及Getter Setter。 @RelationPassive() 为切面注解,如需预加载,必不可缺。

字段 是否必填 描述
entity 目标实体
foreign 目标关联字段(xxx_id获取 xxx表示本实体转蛇形)
owner 本字段(keyName主键获取)
<?php declare(strict_types=1);

namespace App\Model\Entity;

use Swoft\Orm\Annotation\Mapping\HasOne;
use Swoft\Orm\Annotation\Mapping\RelationPassive;
use Swoft\Db\Eloquent\Model;
/**
 *
 * Class Api
 *
 * @since 2.0
 *
 * @Entity(table="users")
 */
class User extends Model
{
    /**
     * @HasOne(
     *     entity=Role::class,
     *     foreign="id",
     *     owner="user_id"
     * )
     * @var mixed
     */
    private $roles;

    /**
     * @param $roles
     */
    public function setRoles($roles)
    {
        $this->roles = $roles;
    }

    /**
     * 获取一个角色
     * @RelationPassive()
     * @return mixed
     */
    public function getRoles()
    {
        return $this->roles;
    }
 }
字段 是否必填 描述
entity 目标实体
foreign 目标关联字段(xxx_id获取 xxx表示本实体转蛇形)
owner 本字段(keyName主键获取)
<?php declare(strict_types=1);

namespace App\Model\Entity;

use Swoft\Orm\Annotation\Mapping\HasMany;
use Swoft\Orm\Annotation\Mapping\RelationPassive;
use Swoft\Db\Eloquent\Model;
/**
 *
 * Class Api
 *
 * @since 2.0
 *
 * @Entity(table="users")
 */
class User extends Model
{
    /**
     * @HasMany(
     *     entity=Role::class,
     *     foreign="id",
     *     owner="user_id"
     * )
     * @var mixed
     */
    private $roles;

    /**
     * @param $roles
     */
    public function setRoles($roles)
    {
        $this->roles = $roles;
    }

    /**
     * 获取专属的多个角色
     * @RelationPassive()
     * @return mixed
     */
    public function getRoles()
    {
        return $this->roles;
    }
 }
字段 是否必填 描述
entity 目标实体
owner 本表字段(xxx_id获取 xxx表示关系名,id表示目标主键)
foreign 目标表字段(keyName主键获取)
<?php declare(strict_types=1);

namespace App\Model\Entity;

use Swoft\Orm\Annotation\Mapping\BelongsTo;
use Swoft\Orm\Annotation\Mapping\RelationPassive;
use Swoft\Db\Eloquent\Model;
/**
 *
 * Class Api
 *
 * @since 2.0
 *
 * @Entity(table="roles")
 */
class Role extends Model
{
    /**
     * @BelongsTo(
     *     entity=User::class,
     *     foreign="user_id",
     *     owner="id"
     * )
     * @var mixed
     */
    private $users;

    /**
     * @param $roles
     */
    public function setUsers($users)
    {
        $this->users = $users;
    }

    /**
     * 获取角色的账号
     * @RelationPassive()
     * @return mixed
     */
    public function getUsers()
    {
        return $this->users;
    }
 }
字段 是否必填 描述
entity 目标实体
pointEntity 中间实体
foreignPivot 中间实体关联本字段的字段(xxx_id获取)
ownerPivot 中间实体关联目标字段的字段(xxx_id获取)
foreign 目标关联字段(id获取)
owner 本字段(id获取)
<?php declare(strict_types=1);

namespace App\Model\Entity;

use Swoft\Orm\Annotation\Mapping\BelongsToMany;
use Swoft\Orm\Annotation\Mapping\RelationPassive;
/**
 *
 * Class Api
 *
 * @since 2.0
 *
 * @Entity(table="users")
 */
class User extends Model
{
    /**
     * @BelongsToMany(
     *     entity=Role::class,
     *     pointEntity=UserRole::class,
     *     foreignPivot="api_id",
     *     ownerPivot="cat_id",
     *     foreign="id",
     *     owner="id"
     * )
     * @var mixed
     */
    private $roles;

    /**
     * @param $cats
     */
    public function setRoles($roles)
    {
        $this->roles = $roles;
    }

    /**
     * 获取多个角色
     * @RelationPassive()
     * @return mixed
     */
    public function getRoles()
    {
        return $this->roles;
    }
}

当通过模型获取数据时,你可能希望限制在一个已存在的关系上。比如说,你想要获取至少包含一条评论的博客文章。你就应该这样做,使用针对关联关系的 has and orHas 方法:

// 获取至少有一条评论的文章
$posts = App\Post::has('comments')->get();
// 获取至少有3
$posts = App\Post::has('comments', '>=', 3)->get();
// 获取至少有一条评论的文章,并加载评论的投票信息
$posts = App\Post::has('comments.votes')->get();

如果你想要做更多特性,你还可以使用 whereHas 和 orWhereHas 方法,在方法中,你可以指定 「where」 条件在你的 has 语句之中。这些方法允许你在关联查询之中添加自定义的条件约束,比如检查评论的内容:

// 获取所有至少有一条评论的文章且评论内容以 foo 开头
$posts = App\Post::whereHas('comments', function ($query) {
    $query->where('content', 'like', 'foo%');
})->get();
//获取书作者
$books = App\Book::with('author')->get();
foreach ($books as $book) {
        echo $book->getAuthor()->getName;
}
//或书的作者及作者联系人
$books = App\Book::with('author.contacts')->get();
foreach ($books as $book) {
        echo $book->getAuthor()->getContacts()->getName;
}
//获取书及作者 并且作者为tom,只需要作者的id name信息,且按照作者id排序
$users = App\Book::with(['author' => function ($query) {
        $query->where('name', '=', '%tom%')
            ->select('id','name')
            ->orderBy('id');
}])->get();

有可能你还希望在模型加载完成后在进行预加载。举例来说,如果你想要动态的加载关联数据,那么 load 方法对你来说会非常有用:

$books = App\Book::all();

if ($someCondition) {
        $books->load('author', 'publisher');
}
$books->load(['author' => function ($query) {
        $query->orderBy('published_date', 'asc');
}]);

About

databse orm for swoft

Topics

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages