- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
最近在写ThinkPHP关联模型的时候一些用法总忘,我就想通过写博客的方式复习和整理下一些用法.
具体版本:
。
1、一对一关联 。
1.1、我先设计了两张表,分别为用户表(user),用户扩展表(user_extend) 。
。
1.2、分别给两个表建立模型 。
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2023/12/19 * Time: 14:50 */ namespace app\common\model; /** * 用户模型 */ class UserModel extends ComBaseModel { protected $name='user'; /** * 关联的用户扩展表 * hasOne的第一个参数是要关联的模型类名,第二个参数是关联的外键名,第三个参数是当前模型(userModel)的主键名 * @return \think\model\relation\HasOne * @Author: fengzi * @Date: 2024/6/27 17:38 */ public function userExtend() { return $this->hasOne(UserExtendModel::class,'user_id','id'); } }
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2023/12/19 * Time: 14:50 */ namespace app\common\model; /** * 用户扩展表 */ class UserExtendModel extends ComBaseModel { protected $name='user_extend'; /** * 用户模型的相对关联 * belongsTo的第一个参数是关联模型类名,第二个参数是当前模型(UserExtendModel)的外键,第三个参数是关联表的主键 * @return \think\model\relation\BelongsTo * @Author: fengzi * @Date: 2024/6/27 17:41 */ public function user() { return $this->belongsTo(UserModel::class,'user_id','id'); } }
。
1.3、with() 关联查询 。
一对一关联查询,user表对user_extend表使用的hasOne,使用hasWhere查询user_extend表时,相当于把user_extend表中符合查询条件的user_id集合作为user表的查询条件.
因为使用的一对一关联,所以当user_extend没找到对应查询数据时,user表也不会有数据.
注意:
<?php /** * Created by PhpStorm * Author: fengzi * Date: 2024/6/26 * Time: 17:13 */ namespace app\admin\controller\orm; use app\common\model\UserModel; class OrmController { /** * @var UserModel|object|\think\App */ private UserModel $userModel; public function __construct() { $this->userModel = app(UserModel::class); } public function index() { /** * with 关联查询一对一 * hasWhere第四个参数joinType的值:LEFT、RIGHT 或 INNER * user表对user_extend表使用的hasOne * 使用hasWhere查询user_extend表时,相当于把user_extend表中符合查询条件的user_id集合作为user表的查询条件。 * 因为使用的一对一关联,所以当user_extend没找到对应查询数据时,user表也不会有数据 */ $lists = $this->userModel ->with(['user_extend']) ->hasWhere('userExtend', function ($query){ $query->where('organize_id', 1); }, '*', 'LEFT') ->select()->toArray(); // 输出打印 dd($lists); } }
。
1.3.1、查询结果展示 。
。
1.4、withJoin() 的查询( 我在user模型中定义的user_extend表的关联方法名称为userExtend ):
public function index() { // 实例化模型 $userModel = app(UserModel::class); /** * 联表数据和主表数据在同一级 */ $info = $userModel->withJoin(['user_extend'])->find(1); dump($info->toArray()); /** * 联表数据是主表数据的一个子级,主/联表数据呈现父子级关系 */ $info = $userModel->withJoin(['userExtend'])->find(1); dd($info->toArray()); }
。
1.4.1、withJoin的条件查询注意事项:
public function index() { // 实例化模型 $userModel = app(UserModel::class); /** * where(['organize_id'=>3]) * 可以根据条件查询出结果 * * * hasWhere('userExtend', function ($query){ * $query->where('organize_id', 3); * }, '*', 'LEFT') * 不能查询出结果,报错“Illegal offset type” */ $info = $userModel->withJoin(['user_extend']) ->where(['organize_id'=>3]) /*->hasWhere('user_extend', function ($query){ $query->where('organize_id', 3); })*/ ->select(); /*********** 以下是主/联表有相同字段(role_id字段相同)时的查询方式 ***********/
// 要筛选主表(user表)中的相同字段时 $info = $userModel ->withJoin('userExtend') ->where(['mkl_user.role_id'=>2]) ->select(); // 输出打印 dump($info->toArray()); // 要筛选关联表(user_extend表)中的相同字段时 $extendInfo = $userModel ->withJoin('userExtend') ->where(['userExtend.role_id'=>3]) ->select(); // 输出打印 dd($extendInfo->toArray()); }
。
1.5、with 关联修改 。
关联修改的常见形式有两种:
注意:
public function index() { // 关联查询 $info = $this->userModel->with(['user_extend'])->find(1); // 输出打印 dump($info->toArray()); // 关联修改:方式一 /*$userExtend = [ 'email' => '88888888@qq.com', 'gender' => 1, ]; $info->user_extend->save($userExtend);*/ // 关联修改:方式二 $info->userExtend->email = '88888888@qq.com'; $info->userExtend->gender = 0; $info->userExtend->save(); // 再次关联查询 $newInfo = $this->userModel->with(['user_extend'])->find(1); // 输出打印 dd($newInfo->toArray()); }
。
1.5.1、with关联修改后的结果 。
。
1.6、关联删除 。
关联删除这里有一些小细节需要注意,下面我们用user_id=1的用户来试验。下图user_id=1的用户数据目前是没有删除的.
。
1.6.1、with 的关联删除 。
(1)这种写法能正确的删除主表和关联表的数据,需要注意的是【 with(['userExtend']) 】和【 together(['userExtend']) 】中的参数名称要一样,不能一个驼峰【userExtend】写法,另一个下划线【user_extend】写法。要么都写【userExtend】,要么都写【user_extend】.
public function index() { // 实例化模型 $userModel = app(UserModel::class); // 查询用户ID=1的数据 $info = $userModel->with(['userExtend'])->find(1); // 删除主表和关联表 $del = $info->together(['userExtend'])->delete(); }
。
(2)这种写法在查询的时候没有带 with() 方法,那么在删除数据的时候,只能删除主表数据,关联表数据不会删除.
public function index() { // 实例化模型 $userModel = app(UserModel::class); // 查询用户ID=1的数据 $info = $userModel->find(1); // 删除主表和关联表 $del = $info->together(['userExtend'])->delete(); // 输出打印 dd($del); }
。
注意:当主表的数据已经被删除后,还调用 together() 进行主/联表的数据删除就会报错.
。
(3)当前代码中的方式一和方式二其实跟上面介绍的没什么区别,只是上面几个写法的链式操作.
public function index() { // 实例化模型 $userModel = app(UserModel::class);// 删除主表和关联表 // 方式一 $del = $userModel->find(1)->together(['userExtend'])->delete(); // 方式二 $del = $userModel->with(['userExtend'])->find(1)->together(['userExtend'])->delete(); }
。
1.6.2、withJoin 的关联删除 。
注意:
public function index() { // 实例化模型 $userModel = app(UserModel::class); /** * withJoin(['user_extend']) together(['userExtend']) 主表数据删除,联表数据不会删除 * withJoin(['user_extend']) together(['user_extend']) 主表数据删除,联表数据不会删除 * withJoin(['userExtend']) together(['userExtend']) 主表数据删除,联表数据删除 * withJoin(['userExtend']) together(['user_extend']) 主表数据删除,联表数据不会删除 */ // 查询用户ID=1的数据 $info = $userModel->withJoin(['userExtend'])->find(1); // 删除主表和关联表 $del = $info->together(['userExtend'])->delete();
/** * together(['user_extend']) 主表数据删除,联表数据不会删除 * together(['userExtend']) 主表数据删除,联表数据不会删除 */ // 查询用户ID=1的数据 $info = $userModel->find(1); // 删除主表和关联表 $del = $info->together(['userExtend'])->delete(); }
。
最后此篇关于ThinkPHP一对一关联模型的运用(ORM)的文章就讲到这里了,如果你想了解更多关于ThinkPHP一对一关联模型的运用(ORM)的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我在使用一对一映射时遇到问题。我搜索了互联网并找到了许多解决方案,但没有一个令人满意。大多数示例都带有将父实例存储在子类中的开销。 我只想在具有外键约束关系的子类中使用父 ID,但不想在子类中保留任何
我有以下设置: Micronaut 3.x Java 15 我要更新的实体: @Setter @Getter @Entity @ToString @Table(name = "single_choic
我正在使用AVAudioPlayer制作MP3播放器。我有多种MP3声音,想一一播放。以下是我的应用程序的逻辑: ///// For playing 1st sound mp3Player = [[A
所以这就是问题所在。我有 2 个模型: 裁判级别和裁判 两个都有: class RefereeLevel(models.Model): level = models.PositiveSmall
我想将数组添加到列表或多维数组(不是一次全部...)。但是我真的不明白为什么这应该那么难。 可以说我有这个: string[] a = { "h", "b"}; string[] b
我有一个长度为 1000 的数字序列,我将其分成 100 个长度的序列。所以我最终得到了 901 个长度为 100 的序列。让前 900 个序列为 trainX。 trainY 是这些序列中的第 2
关键字:association 一对一映射(一个班级只有一个班主任) ?
所以,这是我第一次学习计算机语言。我选择了python和django。现在,我了解了 python 和 django 的许多基本概念。我可以使用 View 和所有其他内容创建新页面。但我仍然对这些关系
在一对一映射中,我编写了以下代码行。 @GenericGenerator(name = "generator", strategy = "foreign", parameters = @Paramet
我有两个如下所示的实体 @Data @EqualsAndHashCode(callSuper = true) @Entity @Table(name = "foo") @Audited @AuditO
我的问题很简单.. 假设有 2 个类..书籍和作者 假设一本书只能由一位作者撰写。 一个作家可以写很多本书。 假设作者有唯一的名字。 [两个作者不能同名] 现在..假设所有 hibernate\JPA
我正在尝试创建一个实体,如下所示 @Data public class Person { @Id private String id; @OneToMany(mapp
我有一个包含字段的Project表 ID PROJECT_BASELINE_ATTRIBUTES_ID (FK for table PROJECT_BASELINE_ATTR) 这个表有如下映射
我正在学习基本的 hibernate 教程。我正在尝试在 2 个表之间建立一对一的关系。当我尝试插入 Client 表时它起作用了,但是当我尝试做相反的事情时(插入 Facture 表)我得到了这个异
我已经在 hibernate 3 中使用注释完成了一对一映射,我有两张表“组”和“类别”。类别是预定义的。当用户选择类别和组时,CategoryId和goupid应该只插入组表中。 那么应该如何映射。
我使用Linux服务Fedora 4.14.33-51.37.amzn1.x86_64。我想使用 NAT 1 对 1。例如是否相同problem我的方案是:我的服务器有两个网络接口(interface
我正在尝试与实体 Revision 创建一对一、自引用、双向关系(哇),看起来像这个: /** * @Entity() * @Table(name="rev") */ class Revisio
我需要两个实体之间的链接,所以我使用一对一 @Entity @Table(name = "T_USER") public class User implements Serializable {
一对一: 一对一的关系极为一个数据仅对应一个数据,用下图的结构图可以帮助理解: 下面用代码实现一下,首先要创建工程项目如下: 接着,我们定义模型: 来到models.py文件,创建两
假设我有5列。 pd.DataFrame({ 'Column1': [1, 2, 3, 4, 5, 6, 7, 8, 9], 'Column2': [4, 3, 6, 8, 3, 4, 1, 4, 3
我是一名优秀的程序员,十分优秀!