devweyes/db-orm

databse orm for swoft

v1.1 2020-01-08 09:33 UTC

This package is not auto-updated.

Last update: 2021-09-15 18:33:02 UTC


README

1.简介

2.定义关联

2.1.一对一

2.2.一对多

2.3.一对多(反向)

2.4.多对多

3.查询关联

3.1.存在关联

3.2.筛选关联

4.预加载

4.1.普通预加载

4.2.延迟预加载

5.插入 & 更新关联模型

5.1.save 方法

5.3.create 方法

5.3.更新 Belongs To 关联

5.4.多对多关联

1.简介

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

1.1 composer

composer require devweyes/db-orm

1.2 实体需继承 Model

class Model extends \Jcsp\Orm\Eloquent\Model

2 定义关联

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

2.1 一对一hasOne

字段 是否必填 描述
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;
    }
 }

2.2 一对多hasMany

字段 是否必填 描述
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;
    }
 }

2.3 一对多(反向)belongsTo

字段 是否必填 描述
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;
    }
 }

2.4 多对多belongsToMany

字段 是否必填 描述
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;
    }
}

3.查询关联

3.1 存在关联

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

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

3.2 筛选关联

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

// 获取所有至少有一条评论的文章且评论内容以 foo 开头
$posts = App\Post::whereHas('comments', function ($query) {
    $query->where('content', 'like', 'foo%');
})->get();

4.预加载

4.1 普通预加载

//获取书作者
$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();

4.2 延迟预加载

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

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

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