zoukankan      html  css  js  c++  java
  • GORM-V1-关联

    说明

    请先阅读官方文档,由于官方文档对每个例子和概念解释比较简单,官方文档中个人认为比较难理解的概念在正文章节进行解释

    本文须与官方文档伴食,否则将不知所云。

    可对应 学习项目 实践验证。

    参考

    正文

    关系

    foreignkey & association foreignkey

    //情况A:不指定外键和关联外键
    type User struct {
        gorm.Model
        CreditCard   CreditCard
    }
    
    type CreditCard struct {
        gorm.Model
        UserID   uint
        Number   string
    }
    
    //情况B:外键和关联外键
    type User struct {
        gorm.Model
      	Refer   string
        CreditCard   CreditCard `gorm:"ForeignKey:ReferRela;AssociationForeignKey:Refer"`
    }
    
    type CreditCard struct {
        gorm.Model
        ReferRela   uint
        Number   string
    }
    

    理解:

    • 在情况A下,默认credit_cards.user_idForeignKey,对应users.idAssociationForeignKey,即某条users表的记录id=1234,那么credit_cards表中的user_id=1234的记录属于与其对应;
    • 在情况B下,由于显式指定了外键和关联外键,则credit_cards.refer_rela对应users.refer

    后文多种关系中都涉及此两键,但是在 Many to Many 关联关系中使用方式稍有不同。

    • foreignkey:B 表关联 A 表的字段
    • association foreignkey:A 表被 B 表关联的字段

    即:A 表的association foreignkey对应 B表的foreignkey,两表两值相等的记录具有关联关系。

    后文多种关系中都涉及此两个键,用法是一样的。默认不指定的时候 A 表的association foreignkey为其primary key,B 表的foreignkey为 A 表表名+A 表 primary key

    Belongs To & Has One

    //Profile Belongs To User
    type User struct {
      gorm.Model
      Name string
    }
    
    // `Profile` 属于 `User`, 外键是`UserID` 
    type Profile struct {
      gorm.Model
      UserID int
      User   User
      Name   string
    }
    
    //User Has One Profile
    type User struct {
      gorm.Model
      Name string
      Profile Profile
    }
    
    // `Profile` 属于 `User`, 外键是`UserID` 
    type Profile struct {
      gorm.Model
      UserID int
      Name   string
    }
    

    理解:

    两者区别在于主体(主语)不同,在逻辑上孪生:

    • Belongs To :以 Profile 为主体,Profile属于 User。——Profile 内持有 User;
    • Has One:以 User 为主体,User 拥有 Profile。——User 内持有 Profile。

    两者的ForeignKeyAssociationForeignKey关系是一样的,都是在 Profile 里定义ForeignKey——Profile.UserID,其对应的是User的PrimerKey(即AssociationForeignKey)——User.ID

    根据以上两种定义方式在数据库创建表结构没有差别,但在应用程序内对数据操作有区别(设计目的|效果)。就查询而言,前者可以查询出携带对应 User 信息的 Profile;后者可以查询出携带对应 Profile 信息的 User。

    多态关联

    Many To Many中不能使用多态关联

    type Cat struct {
        Id    int
        Name  string
        Toy   Toy `gorm:"polymorphic:Owner;"`
      }
    
      type Dog struct {
        Id   int
        Name string
        Toy  Toy `gorm:"polymorphic:Owner;"`
      }
    
      type Toy struct {
        Id        int
        Name      string
        OwnerId   int
        OwnerType string
      }
    

    理解:toys.owner_id对应cats.iddogs.idtoys.owner_type对应catdog

    Has Many & Many To Many

    • 通过切片指定对多关系

    • `gorm:"many2many:关系表命;"`指定多对多关系

    • Many To Manyforeignkey & association foreignkey不做方向区分,都是指定关系表对应的实体表字段

    • association_jointable_foreignkey&jointable_foreignkey指定关系表中字段名

    关系的使用

    通过 gorm.DB.Set(xxx) 或者 Struct Tag 定义关系行为:

    • gorm:association_autoupdate——自动更新关联开关
    • gorm:association_autocreate——自动创建关联开关
    • gorm: save_associations——前两者的和
    • gorm:association_save_reference——关联引用保存开关
    // Set set setting by name, which could be used in callbacks, will clone a new db, and update its setting
    func (s *DB) Set(name string, value interface{}) *DB {
       return s.clone().InstantSet(name, value)
    }
    

    根据 Set 方法的注释说明,返回的是 DB 的副本,则此设置只在一次 DB 构造执行中有效。

    方法

     db.Model(&user).Association("Languages")
     指定表、记录 ID
     指定字段
     后面跟操作方法如下
    
    • Find(&languages)——查询匹配的关联记录
    • Append(Language{Name: "DE"})——添加关联
    • Replace([]Language{languageZH, languageEN})——替换关联
    • Delete([]Language{languageZH, languageEN})——删除关联
    • Clear()——清空关联
    • Count()——返回关联记录数量

    Preloading (预加载)

    Preload("Orders")Find(&users)实际作用与语义刚好相反。

    • 从方法语义来说,只管感觉是加载 Orders 表记录,根据 Orders 记录查询所有关联的 Users 记录
    • 实际过程是,加载 Users 记录,更具 Users 记录查询关联的 Orders 记录

    并且可以在 Preload 内指定 Orders 的筛选条件,可以配合 Where 方法指定 Users 的筛选条件。

    生老病死过于平淡,唯有求知聊以慰藉。
  • 相关阅读:
    Sql server
    分布式爬虫
    爬取某电影网站最新电影
    随笔写一个简单的爬虫
    python的os模块
    基于python的文件处理
    mysql习惯及主从复制参数设置
    git常用命令
    git实习笔记
    微信公众平台开发接口PHP SDK完整版
  • 原文地址:https://www.cnblogs.com/wangbs95/p/13859640.html
Copyright © 2011-2022 走看看