区块链Two——数据库(2)—Gorm

还是继续学习GORM文档,不知道这个学习顺序对不对。这篇文章主要说的第二大部分模型。我这个就是做个笔记平日翻看方便,建议大家可以去看原版的文档,这一篇有的精简有的增加。我看着方便,大家就根据自己的需求吧


1.模型定义

先随便来一个user的结构体(我感觉这个java pojo类从差不多)

type User struct { 

       gorm.Model

       Birthday  time.Time

        Age  int

       Name string  `gorm:"size:255"` //string默认长度为255, 使用这种tag重设。

       Num  int`gorm:"AUTO_INCREMENT"` //自增

       CreditCard   CreditCard //One-To-One (拥有一个 - CreditCard表的UserID作外键)

        Emails   []Email //One-To-Many (拥有多个 - Email表的UserID作外键)

        BillingAddress   Address //One-To-One (属于 - 本表的BillingAddressID作外键)

        BillingAddressID   sql.NullInt64

        ShippingAddress  Address //One-To-One (属于 - 本表的ShippingAddressID作外键)

        ShippingAddressID  int

        IgnoreMe  int`gorm:"-"` //忽略这个字段

        Languages  []Language `gorm:"many2many:user_languages;"` //Many-To-Many , 'user_languages'是连接表

}

type Email struct{ 

         ID  int

         UserID  int  `gorm:"index"` //外键 (属于), tag `index`是为该列创建索引                       Email  string  `gorm:"type:varchar(100);unique_index"` //`type`设置sql类型, `unique_index` 为该列设置唯一索引

         Subscribed  bool

}

type Address struct{ 

         ID  int

         Address1  string  `gorm:"not null;unique"` //设置字段为非空并唯一  

         Address2  string  `gorm:"type:varchar(100);unique"`

         Post  sql.NullString  `gorm:"not null"`

}

type Language struct{ 

          ID  int

         Name  string  `gorm:"index:idx_name_code"` //创建索引并命名,如果找到其他相同名称的索引则创建组合索引

        Code  string  `gorm:"index:idx_name_code"` //`unique_index` also works

}

2.约定

(1)gorm.Model 结构体

type Model struct{ 

       ID  uint  `gorm:"primary_key"` //主键id

      CreatedAt  time.Time  //记录创建时间

      UpdatedAt  time.Time  //记录的修改时间

      DeletedAt  *time.Time //记录删除时间(如果字段存在)

}

基本模型包含了四个字段:ID,CreatedAt,UpdatedAt,DeletedAt。这是可以直接嵌入使用的,当然也可以增加你需要的字段。例如:

type User struct{ 

      gorm.Model //基本模型

      Name  string //自己新增加的

}

(2)表名是结构体名称的复数形式

type User struct{} //一个结构体出来它默认表名是`users`(+s)


func (User //实体名) TableName() string { //部份表使用源表名,在实体类中声明

    return"profiles"  //设置User的表名为`profiles`

}

func (u User) TableName() string{

    if  u.Role =="admin"{ //获取当前用户的名称

           return"admin_users"

    }else{

           return"users"

    } 

}

//全局禁用表名复数,如果不禁止会出现y结尾变ies问题

db.SingularTable(true) //如果设置为true,`User`的默认表名为`user`,使用`TableName`设置的表名不受影响

(3)更改默认表名

gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName  string)  string  {

      return"prefix_"+ defaultTableName;

}

(4)列名是字段名的蛇形小写(使用小写+"_")

列名均为小写,例如:

ID  uint 的列名为 id 。

当然我们也可以重新设置列名,例如:

AnimalId  int64  `gorm:"column:beast_id"` //设置列名为`beast_id`

(5)设置主键

通常情况下,字段id默认为主键。当然也可以设置主键例如:

AnimalId  int64  `gorm:"primary_key"` //设置AnimalId为主键

3.关联

(1)属于

有两个结构体A和B结构体A内字段是结构体B,则A属于B。例如:

type A struct {                                                                     

     gorm. Modle                                                                             

     Bb  B       `gorm:"ForeignKey:Bid"`  //使用Bid作为外键

     //Bb  B        `gorm:"AssociationForeignKey:Bid"`   使用Bid作为关联外键

     Bid  int                                                   

}

type B struct {

     gorm.Model 

     Name  string

}

db.Model(&A).Related(&B) //可以使用Related查找这个关系(一对一)

(2)包含一个

type A truct{ //A中包含一个B

      gorm.Model 

     Refer  string

      B    B //字段名与变量名相同

     //B    B  `gorm:"ForeignKey:AID"`  :指定外键

     //B    B  `gorm:"ForeignKey:AID;AssociationForeignKey:Refer"` :指定外键和关联外键

}

type B struct{ 

       gorm.Model 

       AID  uint //外键

       Number  string

}

var b B //先来一个B

db.Model(&A).Related(&b,"B") //B是A中的字段名并且字段名与变量名相同,也可以这样写:db.Model(&A.Related(&b)

(3)包含多个

type A struct { 

        gorm.Model 

        Refer  string

        B  []B //A包含多个B

      //B  []B  `gorm:"ForeignKey:Aid"`  指定外键

      //B  []B  `gorm:"ForeignKey:AID;AssociationForeignKey:Refer"`  指定外键和关联外键

}

type B struct {

         gorm.Model

         B  string

         AID  uint

}

db.Model(&A).Related(&B) //查询

(4)多对多

// User 包含并属于多个 languages, 使用 `user_languages` 表连接

type A struct { 

         gorm.Model

         ID string

         Bs  []B  `gorm:"many2many:A_Bs;"` //A中包含并属于多个Bs,使用A_Bs

// Bs  []B  `gorm:"many2many:AB;ForeignKey:ID;AssociationForeignKey:Bid"`  指定外键和关联键

}

type B struct { 

         gorm.Model 

        Bid  string

         Name  string  `gorm:"primary_key:true"` //指定外键

}

db.Model(&A).Related(&Bs,"Bs")

(5)多种包含

支持多种的包含一个和包含多个的关联;不支持多态属性和多对多显式,并且会抛出错误。

type Cat struct { 

 Id  int

Name  string

Toy  Toy  `gorm:"polymorphic:Owner;"`

}

type Dogs truct { 

  Id  int

Name  string

Toy   Toy  `gorm:"polymorphic:Owner;"`

}

type Toy struct { 

 Id  int

Name  string 

OwnerId  int

OwnerType  string

}

(6)关联模式(包含一些帮助方法来处理关系事情)

type User struct {  

      gorm.Model 

      Languages []Language

}

type Language struct {

      gorm.Model 

      Name  string

}

var  user User //先来一个,开始关联模式

db.Model(&user).Association("Languages") //user是源,它需要一个有效的记录(包含主键);Languages是关系中源的字段名,如果条件不匹配,则返回一个错误来检查它:db.Model(&user).Association("Languages").Error

db.Model(&user).Association("Languages").Find(&languages) //Query - 查找所有相关关联

db.Model(&user).Association("Languages").Append([]Language{languageZH, languageEN}) //Append - 添加新的many2many, has_many关联, 会替换掉当前 has_one, belongs_to关联

db.Model(&user).Association("Languages").Delete([]Language{languageZH, languageEN}) //Delete - 删除源和传递的参数之间的关系,不会删除这些参数

db.Model(&user).Association("Languages").Replace([]Language{languageZH, languageEN}) //Replace - 使用新的关联替换当前关联

db.Model(&user).Association("Languages").Count() //Count - 返回当前关联的计数

db.Model(&user).Association("Languages").Clear() //Clear - 删除源和当前关联之间的关系,不会删除这些关联

你可能感兴趣的:(区块链Two——数据库(2)—Gorm)