PageSourceSearch

https://pjchender.dev/assets/js/c6ae4a47.0cf65128.js

js pjchender.dev collected 2026-09-25 14:30:57 UTC 21,464 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkpjchender_notes=self.webpackChunkpjchender_notes||[]).push([[6148],{28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>c});var t=r(96540);const d={},s=t.createContext(d);function o(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:o(e.components),t.createElement(s.Provider,{value:n},e.children)}},78674:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>u,frontMatter:()=>o,metadata:()=>t,toc:()=>i});const t=JSON.parse('{"id":"golang/note-gorm-example","title":"[Note] GORM \u4f7f\u7528\u7bc4\u4f8b","description":"TL;DR","source":"@site/docs/golang/[note] GORM \u4f7f\u7528\u7bc4\u4f8b.md","sourceDirName":"golang","slug":"/golang/note-gorm-example","permalink":"/golang/note-gorm-example","draft":false,"unlisted":false,"editUrl":"https://github.com/pjchender/pjchender.github.io/tree/main/docs/golang/[note] GORM \u4f7f\u7528\u7bc4\u4f8b.md","tags":[],"version":"current","lastUpdatedAt":1775885633000,"frontMatter":{"id":"note-gorm-example","title":"[Note] GORM \u4f7f\u7528\u7bc4\u4f8b","sidebar_label":"[note] GORM \u4f7f\u7528\u7bc4\u4f8b","keywords":["golang","gorm"],"image":"https://i.imgur.com/ZpZ2muh.png"},"sidebar":"docs","previous":{"title":"[note] GORM \u7b46\u8a18","permalink":"/golang/note-gorm"},"next":{"title":"[note] clean architecture","permalink":"/golang/note-go-clean-architecture"}}');var d=r(74848),s=r(28453);const o={id:"note-gorm-example",title:"[Note] GORM \u4f7f\u7528\u7bc4\u4f8b",sidebar_label:"[note] GORM \u4f7f\u7528\u7bc4\u4f8b",keywords:["golang","gorm"],image:"https://i.imgur.com/ZpZ2muh.png"},c=void 0,l={},i=[{value:"TL;DR",id:"tldr",level:2},{value:"\u4e00\u5c0d\u591a\uff08has many, belongs to)",id:"\u4e00\u5c0d\u591ahas-many-belongs-to",level:2},{value:"\u60c5\u5883",id:"\u60c5\u5883",level:3},{value:"Model \u5b9a\u7fa9",id:"model-\u5b9a\u7fa9",level:3},{value:"User has many products",id:"user-has-many-products",level:4},{value:"Product belong to User",id:"product-belong-to-user",level:4},{value:"CRUD \u4f7f\u7528",id:"crud-\u4f7f\u7528",level:3},{value:"Read: \u4f7f\u7528 Preload \u5c07 User \u4e2d\u95dc\u806f\u7684 Product \u53d6\u51fa",id:"read-\u4f7f\u7528-preload-\u5c07-user-\u4e2d\u95dc\u806f\u7684-product-\u53d6\u51fa",level:4},{value:"Create",id:"create",level:4},{value:"Update",id:"update",level:4},{value:"Delete",id:"delete",level:4},{value:"Method Chaining",id:"method-chaining",level:2},{value:"keywords: <code>method chaining</code>, <code>immediate methods</code>, <code>scope</code>",id:"keywords-method-chaining-immediate-methods-scope",level:5},{value:"\u628a\u689d\u4ef6\u586b\u5165 SQL",id:"\u628a\u689d\u4ef6\u586b\u5165-sql",level:3},{value:"\u628a\u689d\u4ef6\u76f4\u63a5\u5e36\u5165 ORM",id:"\u628a\u689d\u4ef6\u76f4\u63a5\u5e36\u5165-orm",level:3},{value:"\u7c21\u6613\u7684\u4f7f\u7528 where \u4e32\u9023\u689d\u4ef6",id:"\u7c21\u6613\u7684\u4f7f\u7528-where-\u4e32\u9023\u689d\u4ef6",level:3}];function a(e){const n={a:"a",blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",h4:"h4",h5:"h5",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.h2,{id:"tldr",children:"TL;DR"}),"\n",(0,d.jsxs)(n.blockquote,{children:["\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.a,{href:"https://gorm.io/docs/query.html",children:"query"})," @ gorm"]}),"\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.a,{href:"https://gorm.io/docs/method_chaining.html",children:"method chaining"})," @ gorm"]}),"\n"]}),"\n"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:'db.\nTable("table_name").         // Model(&model{})\nSelect("select syntax").\nGroup("field_names").\nOrder("field_name").\nFind(&model{})\t\t\t\t\t\t\t\t// Rows()\n'})}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:["methods \u53ef\u4ee5\u5206\u6210 ",(0,d.jsx)(n.strong,{children:"chain methods"}),"\u3001",(0,d.jsx)(n.strong,{children:"finisher methods"}),"\u3001",(0,d.jsx)(n.strong,{children:"new session method"}),"\u3002"]}),"\n"]}),"\n",(0,d.jsx)(n.h2,{id:"\u4e00\u5c0d\u591ahas-many-belongs-to",children:"\u4e00\u5c0d\u591a\uff08has many, belongs to)"}),"\n",(0,d.jsx)(n.h3,{id:"\u60c5\u5883",children:"\u60c5\u5883"}),"\n",(0,d.jsx)(n.p,{children:"\u4e00\u500b User \u6709\u591a\u500b Product\uff0c\u800c\u4e00\u500b Product \u53ea\u5c6c\u65bc\u4e00\u500b User\u3002"}),"\n",(0,d.jsx)(n.h3,{id:"model-\u5b9a\u7fa9",children:"Model \u5b9a\u7fa9"}),"\n",(0,d.jsx)(n.h4,{id:"user-has-many-products",children:"User has many products"}),"\n",(0,d.jsxs)(n.blockquote,{children:["\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.a,{href:"https://gist.github.com/jtbonhomme/ff6db22b8dcac7dd9349e26bad002fb1",children:"hasMany.go"})," @ gist"]}),"\n"]}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:["\u4f7f\u7528 ",(0,d.jsx)(n.code,{children:"Products []Product"})," \u8868\u793a User \u6709\u5f88\u591a Product"]}),"\n",(0,d.jsxs)(n.li,{children:["\u5982\u679c\u6c92\u6709 Products \u4e0d\u5e0c\u671b\u986f\u793a\u7a7a\u9663\u5217\uff0c\u53ef\u4ee5\u5728 json tag \u4e2d\u4f7f\u7528 ",(0,d.jsx)(n.code,{children:"omitempty"})]}),"\n"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:'type User struct {\n\tName      str
1ing         `json:"name"`\n\tProducts  []Product      `json:"products"`\n}\n'})}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:'type Product struct {\n  Name      string          `json:"name"`\n\tUserID    uuid.UUID       `json:"userId"`\n  User      User            `json:"user"`\n}\n'})}),"\n",(0,d.jsx)(n.h4,{id:"product-belong-to-user",children:"Product belong to User"}),"\n",(0,d.jsxs)(n.p,{children:["\u5728 ",(0,d.jsx)(n.code,{children:"Product"})," model \u9700\u8981"]}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:["\u6709 ",(0,d.jsx)(n.code,{children:"UserID"})," \u4f5c\u70ba foreign key\uff08\u9810\u8a2d\uff09"]}),"\n",(0,d.jsxs)(n.li,{children:["\u6709 ",(0,d.jsx)(n.code,{children:"User"})," Model \u8868\u793a belongs to\uff0c\u578b\u5225\u4f7f\u7528 ",(0,d.jsx)(n.code,{children:"*User"})," \u642d\u914d json struct field tag \u7684 ",(0,d.jsx)(n.code,{children:"omitempty"})," \u5247\u53ef\u4ee5\u5728 Product \u6c92\u6709 User \u6488\u51fa\u8cc7\u6599\u6642\u4e0d\u8981\u986f\u793a\u6b64\u6b04\u4f4d"]}),"\n"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:'type Product struct {\n\tName      string          `json:"name"`\n\tUserID    uuid.UUID       `json:"userId"`\n\tUser      *User           `json:"user,omitempty"`\n}\n'})}),"\n",(0,d.jsx)(n.h3,{id:"crud-\u4f7f\u7528",children:"CRUD \u4f7f\u7528"}),"\n",(0,d.jsx)(n.h4,{id:"read-\u4f7f\u7528-preload-\u5c07-user-\u4e2d\u95dc\u806f\u7684-product-\u53d6\u51fa",children:"Read: \u4f7f\u7528 Preload \u5c07 User \u4e2d\u95dc\u806f\u7684 Product \u53d6\u51fa"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:["\u4f7f\u7528 ",(0,d.jsx)(n.code,{children:"db.Preload(clause.Associations)"})," \u53ef\u4ee5\u4e00\u6b64\u628a\u6240\u6709\u548c User \u76f8\u95dc\u9023\u7684\u6b04\u4f4d\uff08\u5373\uff0cProduct\uff09\u4e00\u4f75\u6488\u51fa"]}),"\n",(0,d.jsxs)(n.li,{children:["\u4f7f\u7528 ",(0,d.jsx)(n.code,{children:'db.Preload("Products"'})," \u5247\u53ef\u4ee5\u6307\u5b9a\u8981\u4e00\u4f75\u6488\u51fa\u7684\u6b04\u4f4d\u540d\u7a31)"]}),"\n"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:"// database/user.go\nfunc (d *GormDatabase) GetUserByID(userID uuid.UUID) (*model.User, error) {\n\tuser := &model.User{}\n\tif err := d.DB.Preload(clause.Associations).Take(&user, userID).Error; err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn user, nil\n}\n"})}),"\n",(0,d.jsx)(n.p,{children:"\u53d6\u5f97\u7684\u7d50\u679c\u6703\u50cf\u9019\u6a23\uff1a"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-json",children:'{\n  "name": "aaron",\n  "products": [\n    {\n      "name": "Product 2",\n      "price": "200",\n      "sn": 2,\n      "comment": "Second Product",\n      "userId": "61ecf82b-8385-4606-83e9-70e13a4cdb5d"\n    },\n    {\n      "name": "Product 3",\n      "price": "300",\n      "sn": 3,\n      "comment": "Third Product",\n      "userId": "61ecf82b-8385-4606-83e9-70e13a4cdb5d"\n    }\n  ]\n}\n'})}),"\n",(0,d.jsx)(n.h4,{id:"create",children:"Create"}),"\n",(0,d.jsx)(n.p,{children:"\u5efa\u7acb\u8cc7\u6599\u7684\u6642\u5019\uff0c\u53ea\u9700\u8981\u628a User \u4e2d\u7684 Product \u5e36\u5165\u5f8c\u5373\u6703\u81ea\u52d5\u5efa\u7acb\u548c User \u76f8\u95dc\u9023\u7684 Product\uff1a"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:"// database/user.go\n// CreateUser \u6703\u81ea\u52d5\u628a nested \u7684 Product \u4e00\u4f75\u5efa\u7acb\u8d77\u4f86\nfunc (d *GormDatabase) CreateUser(user *model.User) error {\n\treturn d.DB.Create(user).Error\n}\n"})}),"\n",(0,d.jsx)(n.p,{children:"\u4f7f\u7528\u6642\u76f4\u63a5\u628a\u548c User \u6709\u95dc\u806f\u4e86 Products \u653e\u5165\u5373\u53ef\uff1a"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:"// api/user.go\nfunc TestUserHasManyProducts() {\n  assertWithT := assert.New(s.T())\n\tmockUser := mock.GetUser()\n\tmockProducts := mock.GetProductsWithoutUser()\n  // \u76f4\u63a5\u628a\u548c User \u6709\u95dc\u806f\u4e86 Products \u653e\u5165\u5373\u53ef\n\tmockUser.Products = []model.Product{\n\t\tmockProducts[0],\n\t\tmockProducts[1],\n\t}\n\n\t/* create patient with contacts */\n\tassertWithT.NoError(s.db.CreateUser(&mockUser))\n}\n"})}),"\n",(0,d.jsx)(n.h4,{id:"update",children:"Update"}),"\n",(0,d.jsxs)(n.blockquote,{children:["\n",(0,d.jsxs)(n.p,{children:["\u4f7f\u7528 ",(0,d.jsx)(n.code,{children:"Update"})," \u8981\u5c0f\u5fc3 zero value \u4e0d\u6703\u88ab\u66f4\u65b0\u7684\u3002"]}),"\n"]}),"\n",(0,d.jsxs)(n.p,{children:["UpdateUser \u6642\uff0c\u7576 user \u4e2d\u7684 Product\uff08\u4e0b\u9762\u7684 ",(0,d.jsx)(n.code,{children:"id"})," \u662f\u6307 ",(0,d.jsx)(n.code,{children:"Product"})," \u7684 ID\uff09\uff1a"]}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsx)(n.li,{children:"\u6c92\u6709\u5e36 id \u6642\u6703\u81ea\u52d5\u5efa\u7acb\u65b0\u7684"}),"\n",(0,d.jsx)(n.li,{children:"\u6709\u5e36 id \u4f46\u6b64 id \u4e0d\u5b58\u5728\u6642\uff0c\u6703\u81ea\u52d5\u5efa\u7acb\u65b0\u7684"}),"\n",(0,d.jsx)(n.li,{children:"\u6709\u5e36 id \u4e14\u6b64 id \u5b58\u5728\u6642\uff0c\u6703\u66f4\u65b0\u6b64 product \u7684 UserID"}),"\n"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:"// database/user.go\nfunc (d *GormDatabase) UpdateUser(user *model.User) error {\n\treturn d.DB.Updates(user).Error\n}\n"})}),"\n",(0,d.jsx)(n.p,{children:"\u5982\u679c\u60f3\u8981\u5728\u66f4\u65b0 User \u6642\u4e00\u4f75\u66f4\u65b0 nested \u7684 Product \u53ef\u4ee5\u81ea\u5df1\u5224\u65b7\uff1a"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:["\u4f7f\u7528 ",(0,d.jsx)(n.code,{children:"db.Updates()"})," \u7684\u8a71\uff0cUser \u6216 Contact \u4e2d\u7684 zero value \u90fd\u4e0d\u6703\u66f4\u65b0\u5230"]}),"\n",(0,d.jsxs)(n.li,{children:["\u4f7f\u7528 ",(0,d.jsx)(n.code,{children:"db.Save()"})," \u7684\u8a71\uff0c\u96d6\u7136\u6240\u6709 zero value \u90fd\u6703\u8655\u7406\u5f97\u5230\uff0c\u4f46\u5728 save contact \u7684\u6642\u5019\uff0cContact \u6b04\u4f4d\u4e2d\u4e00\u5b9a\u8981\u63d0\u4f9b UserID\uff0c\u4e0d\u7136"]}),"\n",(0,d.jsx)(n.li,{children:"\u6703\u51fa\u73fe foreign key error"}),"\n"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:"// database/user.go\n// SaveUserAndProduct \u6703\u
166f4\u65b0\u6240\u6709\u6b04\u4f4d\uff08\u5305\u542b zero value\uff09\nfunc (d *GormDatabase) SaveUserAndProduct(userToBeUpdate *model.User) (*model.User, error) {\n  // \u6700\u5916\u5c64\u7528 Transaction \u5305\u8d77\u4f86\n\terr := d.DB.Transaction(func(tx *gorm.DB) error {\n\n\t\t// \u79fb\u9664 products\uff08\u539f\u672c\u6709\uff0c\u5f8c\u4f86\u6c92\u6709\u7684\uff0c\u8981\u522a\u9664\uff09\n\t\tuser := &model.User{}\n\t\tif err := d.DB.Preload(clause.Associations).Take(user, userToBeUpdate.ID).Error; err != nil {\n\t\t\treturn err\n\t\t}\n\t\tproductToBeDelete := filter(user.Products, func(c model.Product) bool {\n\t\t\treturn !contains(userToBeUpdate.Products, c)\n\t\t})\n\t\tif len(productToBeDelete) > 0 {\n\t\t\tif err := d.DB.Delete(&productToBeDelete).Error; err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\t\t// \u66f4\u65b0 products\uff08\u539f\u672c\u6709\uff0c\u5f8c\u4f86\u4e5f\u6709\u7684\uff0c\u8981\u66f4\u65b0\uff09\n\t\tuser = &model.User{}\n\t\tif err := d.DB.Preload(clause.Associations).Take(user, userToBeUpdate.ID).Error; err != nil {\n\t\t\treturn err\n\t\t}\n\t\tproductToBeUpdate := filter(userToBeUpdate.Products, func(c model.Product) bool {\n\t\t\treturn contains(user.Products, c)\n\t\t})\n\t\tif len(productToBeUpdate) > 0 {\n\t\t\tfor _, c := range productToBeUpdate {\n\t\t\t\terr := d.DB.Save(c).Error\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}
1\n\n\t\t// \u66f4\u65b0 user \u4e26\u65b0\u589e\u4e0d\u5b58\u5728\u7684 product\n    // Product \u4e2d\u4e00\u5b9a\u6a23\u63d0\u4f9b UserID \u624d\u80fd\u6210\u529f\u5efa\u7acb Product\n\t\tif err := d.DB.Save(userToBeUpdate).Error; err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\treturn nil\n\t})\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tupdatedUser := &model.User{}\n\tif err := d.DB.Preload(clause.Associations).Take(updatedUser, userToBeUpdate.ID).Error; err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn updatedUser, nil\n}\n\n// utils\nfunc filter(searchElement []model.Contact, handler func(contact model.Contact) bool) []model.Contact {\n\tn := 0\n\tfor _, element := range searchElement {\n\t\tif handler(element) {\n\t\t\tsearchElement[n] = element\n\t\t\tn++\n\t\t}\n\t}\n\treturn searchElement[:n]\n}\n\nfunc contains(searchElement []model.Contact, target model.Contact) bool {\n\tfor _, element := range searchElement {\n\t\tif element.ID == target.ID {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"})}),"\n",(0,d.jsx)(n.h4,{id:"delete",children:"Delete"}),"\n",(0,d.jsxs)(n.p,{children:["\u8981\u628a\u8207 User \u95dc\u806f\u7684 Product \u4e00\u4f75\u522a\u9664\uff0c\u53ea\u9700\u8981\u5728\u522a\u9664\u7684\u65b9\u6cd5\u4e2d\u52a0\u4e0a ",(0,d.jsx)(n.code,{children:"db.Select(clause.Associations)"}),"\uff1a"]}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:["\u4f7f\u7528 ",(0,d.jsx)(n.code,{children:"db.Select(clause.Associations)"})," \u6703\u76f4\u63a5\u628a\u6240\u6709\u548c User \u95dc\u806f\u7684 nested model \u4e00\u4f75\u522a\u9664"]}),"\n",(0,d.jsxs)(n.li,{children:["\u4f7f\u7528 ",(0,d.jsx)(n.code,{children:'db.Select("Product")'})," \u5247\u53ea\u6703\u522a\u9664\u548c User \u95dc\u806f\u7684 Product Model"]}),"\n",(0,d.jsx)(n.li,{children:(0,d.jsxs)(n.strong,{children:["\u82e5\u5e0c\u671b\u4fdd\u7559\u76f8\u95dc\u9023\u7684 Model \u800c\u4e0d\u8981\u4e00\u4f75\u522a\u9664\uff0c\u5247",(0,d.jsx)("u",{children:"\u4e0d\u8981"}),"\u4f7f\u7528 ",(0,d.jsx)(n.code,{children:"db.Select()"})]})}),"\n"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:"// database/user.go\nfunc (d *GormDatabase) DeleteUserByID(userID uuid.UUID) error {\n\treturn d.DB.Select(clause.Associations).Delete(&model.User{\n\t\tID: userID,\n\t}).Error\n}\n"})}),"\n",(0,d.jsx)(n.h2,{id:"method-chaining",children:"Method Chaining"}),"\n",(0,d.jsxs)(n.h5,{id:"keywords-method-chaining-immediate-methods-scope",children:["keywords: ",(0,d.jsx)(n.code,{children:"method chaining"}),", ",(0,d.jsx)(n.code,{children:"immediate methods"}),", ",(0,d.jsx)(n.code,{children:"scope"})]}),"\n",(0,d.jsxs)(n.blockquote,{children:["\n",(0,d.jsxs)(n.p,{children:[(0,d.jsx)(n.a,{href:"http://gorm.io/docs/method_chaining.html",children:"Method Chaining"})," @ GORM"]}),"\n"]}),"\n",(0,d.jsx)(n.h3,{id:"\u628a\u689d\u4ef6\u586b\u5165-sql",children:"\u628a\u689d\u4ef6\u586b\u5165 SQL"}),"\n",(0,d.jsxs)(n.p,{children:["\u53ef\u4ee5\u4f7f\u7528 Method Chaining \u7684\u65b9\u5f0f\u4e32\u9023\u591a\u500b where \u689d\u4ef6\uff0c\u9019\u4e9b\u689d\u4ef6\u53ea\u6709\u5728 immediate method \u88ab\u547c\u53eb\u6642\u624d\u6703\u7522\u6536 SQL query \u4e26\u50b3\u9001\u5230 database \u4e2d\u88ab\u57f7\u884c\u3002",(0,d.jsx)(n.strong,{children:"immediate method"})," \u591a\u662f CRUD \u6642\u4f7f\u7528\uff0c\u4f8b\u5982\uff1a",(0,d.jsx)(n.code,{children:"Create"}),", ",(0,d.jsx)(n.code,{children:"First"}),", ",(0,d.jsx)(n.code,{children:"Find"}),", ",(0,d.jsx)(n.code,{children:"Take"}),", ",(0,d.jsx)(n.code,{children:"Save"}),", ",(0,d.jsx)(n.code,{children:"UpdateXXX"}),", ",(0,d.jsx)(n.code,{children:"Delete"}),", ",(0,d.jsx)(n.code,{children:"Scan"}),", ",(0,d.jsx)(n.code,{children:"Row"}),", `Rows\u3002"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:'func (d *GormDatabase) GetActivitiesGroupByDate(begin int64, end int64) (\n\t[]model.ActivityResp, error,\n) {\n\tvar activities []model.ActivityDaily\n\n  // tx := d.DB.Where("")\n\ttx := d.DB.Table("activities").  // \u4e5f\u53ef\u4ee5\u5beb tx := d.DB.Model(&model.Activity{})\n\t\tSelect("patient_id, date_trunc(\'day\', TO_TIMESTAMP(recorded_at)) AS date, SUM(count) as count")\n\n\tif begin != 0 {\n\t\ttx.Where("recorded_at >= ?", begin)\n\t}\n\n\tif end != 0 {\n\t\ttx.Where("recorded_at <= ?", end)\n\t}\n\n  // start query with finish method "Find"\n\ttx.Group("patient_id, date").Find(&activities)\n\n\treturn activitiesResp, nil\n}\n'})}),"\n",(0,d.jsx)(n.h3,{id:"\u628a\u689d\u4ef6\u76f4\u63a5\u5e36\u5165-orm",children:"\u628a\u689d\u4ef6\u76f4\u63a5\u5e36\u5165 ORM"}),"\n",(0,d.jsxs)(n.ul,{children:["\n",(0,d.jsxs)(n.li,{children:["\u5728 ",(0,d.jsx)(n.code,{children:"GetProducts"})," \u65b9\u6cd5\u53c3\u6578 ",(0,d.jsx)(n.code,{children:"condition"})," \u53ef\u4ee5\u63a5\u6536\u8a31\u591a\u7684 condition"]}),"\n",(0,d.jsxs)(n.li,{children:["\u642d\u914d ",(0,d.jsx)(n.code,{children:".Where"})," \u7684 method chaining"]}),"\n",(0,d.jsxs)(n.li,{children:[(0,d.jsx)(n.code,{children:".Where"})," \u7b2c\u4e00\u500b\u53c3\u6578\u4e00\u5b9a\u8981\u7d66\uff1b\u7b2c\u4e8c\u500b\u9910\u6578\u5247\u53ef\u4ee5\u7528\u9663\u5217\u5c55\u958b\uff0c\u56e0\u6b64\u6839\u64da\u689d\u4ef6\u6578\u76ee\uff08",(0,d.jsx)(n.code,{children:"len(conditions)"}),"\uff09\u9032\u884c\u5224\u65b7"]}),"\n"]}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:"// ./database/product\n// https://github.com/gotify/server/blob/master/database/user.go\nfunc (d *GormDatabase) GetProducts(conditions ...interface{}) ([]*model.Product, error) {\n\tvar products []*model.Product\n\n\ttx := d.DB.Model(&model.Product{})\n\n\tif len(condition) == 1 {\n\t\ttx.Where(conditions[0])\n\t} else if len(condition) > 1 {\n\t\ttx.Where(conditions[0], conditions[1:]...)\n\t}\n\n\tif err := tx.Find(&products).Error; err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn products, nil\n}\n"})}),"\n",(0,d.jsx)(n.p,{children:"\u5728 API \u7684\u5730\u65b9\u53ef\u4ee5\u76f4\u63a5\u5c0d\u65bc\u6c92\u6709\u8981\u67e5\u8a62\u7684\u689d\u4ef6\u53ef\u4ee5\u76f4\u63a5\u9810\u8a2d\u503c\uff1a"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:"// ./runner/product\ntype ProductQuery struct {\n\tName    str
1ing\n\tPrice   uint\n\tSN      uint\n\tComment string\n}\n\nfunc (r *ProductRunner) GetProducts(\n\tqs ProductQuery,\n) ([]*model.Product, error) {\n\n  // \u5982\u679c qs \u4e2d\u7684\u6b04\u4f4d\u662f zero value \u5247\u4e0d\u6703\u9032\u884c\u67e5\u8a62\n\tproducts, err := r.DB.GetProducts(\n    &model.Product{\n      Name: qs.Name,\n      SN: qs.SN,\n      Price: qs.Price,\n      Comment: qs.Comment,\n    }\n\t)\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn products, nil\n}\n"})}),"\n",(0,d.jsx)(n.p,{children:"\u4f7f\u7528\u6642\u53ef\u4ee5\u76f4\u63a5\u5e36\u5165 struct\uff1a"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:'func main() {\n  // \u76f4\u63a5\u5efa\u7acb query \u7684 struct\n\tqs := model.ProductQuery{\n\t\tSN:      2,\n\t\tComment: "first",\n\t}\n\n  // \u76f4\u63a5\u628a qs \u5e36\u5165\u5373\u53ef\u67e5\u8a62\u7b26\u5408\u689d\u4ef6\u7684\u8cc7\u6599\n  products, _ := productRunner.GetProducts(qs)\n}\n'})}),"\n",(0,d.jsx)(n.h3,{id:"\u7c21\u6613\u7684\u4f7f\u7528-where-\u4e32\u9023\u689d\u4ef6",children:"\u7c21\u6613\u7684\u4f7f\u7528 where \u4e32\u9023\u689d\u4ef6"}),"\n",(0,d.jsx)(n.p,{children:"\u5982\u679c\u689d\u4ef6\u6c92\u6709\u592a\u8907\u96dc\uff0c\u4e5f\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528 where \u4e32\u9023\uff1a"}),"\n",(0,d.jsx)(n.pre,{children:(0,d.jsx)(n.code,{className:"language-go",children:'func getCount(t Tag, db *gorm.DB) (int64, error) {\n  var count int64\n  if t.Name != "" {\n    db = db.Where("name = ?", t.Name)\n  }\n\n  db = db.Where("state = ?", t.State)\n  err := db.Model(&t).Where("is_del = ?", 0).Count(&count).Error\n  if err != nil {\n    return 0, err\n  }\n\n  return count, nil\n}\n'})})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(a,{...e})}):a(e)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.