kaychem / db-orm
databse orm for swoft
dev-master
2019-12-14 02:11 UTC
Requires
- php: >7.1
- swoft/db: ~2.0.0
- swoft/framework: ~2.0.0
This package is auto-updated.
Last update: 2025-03-14 14:16:49 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 swoft/db-orm
1.2 实体需继承 Model
class Model extends \Swoft\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'); }]);