mysql 设计 GORM

type Goods struct {
    BaseModel
    CategoryID int32 `gorm:"type:int;not null"`
    Category   Category
    BrandsID   int32 `gorm:"type:int;not null"`
    Brands     Brands
}

 Goods 是从表,从表中add foreign key关系, reference 主表

alter table 从表名 add [constraint] [外键名称] foreign key(从表中的外键字段名) references 主表(主表的主键);

[外键名称]:用于删除外键约束,一般建议以“_fk”结尾。

删除从表(goods),再删除主表(brands)

先建立主表,再删除从表

因为goods的存在依赖于category

2. has many:多方是从表,credit card 依赖于user

 

// User 有多张 CreditCard,UserID 是外键
type User struct {
  gorm.Model
  CreditCards []CreditCard
}

type CreditCard struct {
  gorm.Model
  Number string
  UserID uint
}

 

3. belong to: User 里面有Company,代表User依赖于Company

reference:改变指向

type User struct {
  gorm.Model
  Name      string
  CompanyID string
  Company   Company `gorm:"references:Code"` // 使用 Code 作为引用
}

type Company struct {
  ID   int
  Code string
  Name string
}

1. 目录怎么做?

 如何选择一级目录并已经加载好二级目录? preload("subcategory")

  - 如何加载好三级目录? preload("subcategory.subcategory")

give JSON DATA to front end

  var categorys []model.Category
    global.DB.Where(&model.Category{Level: 1}).Preload("SubCategory.SubCategory").Find(&categorys)
    b, _ := json.Marshal(&categorys)
    return &proto.CategoryListResponse{JsonData: string(b)}, nil

不用显示的json用-

type Category struct {
    BaseModel
    Name             string      `gorm:"type:varchar(20);not null" json:"name"`
    ParentCategoryID int32       `json:"parent"`
    ParentCategory   *Category   `json:"-"`
    SubCategory      []*Category `gorm:"foreignKey:ParentCategoryID;references:ID" json:"subCategory"`
    Level            int32       `gorm:"type:int;not null;default:1" json:"level"`
    IsTab            bool        `gorm:"default:false;not null" json:"is_tab"`
}

2. 外键需要先preload

global.DB.Preload("Brands").Preload("Category").Scopes(Paginate(int(req.Pages), int(req.PagePerNums))).Find(&categoryBrands)

3. conditions concat

1)使用map构造条件(如果只有 =)

2)使用localdb拼接语句

  localDB := global.DB.Model(model.Goods{})
    if req.KeyWords != "" {
        //搜索
        localDB = localDB.Where("name LIKE ?", req.KeyWords+"%")
    }
    if req.IsHot {
        localDB = localDB.Where(model.Goods{IsHot: true})
    }
    if req.IsNew {
        localDB = localDB.Where(model.Goods{IsNew: true})
    }

3)使用子查询

    var subQuery string
    if req.TopCategory > 0 {
        var category model.Category
        if result := global.DB.First(&category, req.TopCategory); result.RowsAffected == 0 {
            return nil, status.Errorf(codes.NotFound, "商品分类不存在")
        }

        if category.Level == 1 {
            subQuery = fmt.Sprintf("select id from category where parent_category_id in (select id from category WHERE parent_category_id=%d)", req.TopCategory)
        } else if category.Level == 2 {
            subQuery = fmt.Sprintf("select id from category WHERE parent_category_id=%d", req.TopCategory)
        } else if category.Level == 3 {
            subQuery = fmt.Sprintf("select id from category WHERE id=%d", req.TopCategory)
        }

        localDB = localDB.Where(fmt.Sprintf("category_id in (%s)", subQuery))
    }

4)分页前count

    var count int64
    localDB.Count(&count)
    goodsListResponse.Total = int32(count)

5)  preload fk

result := localDB.Preload("Category").Preload("Brands").Scopes(Paginate(int(req.Pages), int(req.PagePerNums))).Find(&goods)

6)where语句:

where(主键切片) => id in (1,2,3)

where("name IN (?)",切片) 

1.
order
有[]goods list,但是选择使用单独的表
ordergoods
因为要满足通过一个goods查询多个订单的需求

如果没有这个需求,可以使用list
goods
imgList GormList // store json

type GormList []string

func (g *GormList) Scan(value interface{}) error {
return json.Unmarshal(value.([]byte), &g)
}
func (g GormList) Value() (driver.Value, error) {
return json.Marshal(g)
}

 

2. ordergoods中有order,goods,还有商品信息(不满足3NF)
in microservices, high concurrency, => 否则order还需要调用goods服务查询字段
还需要goodsPrice(因为price是浮动的)

 

posted @ 2023-11-12 16:34  PEAR2020  阅读(37)  评论(0)    收藏  举报