You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

307 lines
6.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package gormExample
import (
"context"
"database/sql"
"fmt"
"github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/schema"
"log"
"reflect"
"strings"
"time"
)
type Post struct{ gorm.Model }
type Category struct{ gorm.Model }
type PostCategory struct{ gorm.Model }
type Box struct{ gorm.Model }
func (Box) TableName() string {
return "my_box"
}
type TypeMap struct {
gorm.Model
FInt int
FUInt uint
FFloat32 float32
FFloat64 float64
FString string
FTime time.Time
FByteSlice []byte
FIntP *int
FUIntP *uint
FFloat32P *float32
FFloat64P *float64
FStringP *string
FTimeP *time.Time
}
func Migrate() {
if err := DB.Debug().AutoMigrate(&Blog{}, &Service{}, &IAndC{}, &FieldTag{}, &TypeMap{}, &Post{}, &Category{}, &PostCategory{}, &Box{}); err != nil {
log.Fatal(err)
}
}
func PointerDiff() {
// 模型的零值
typeMap := &TypeMap{}
fmt.Printf("%+v\n", typeMap)
fmt.Println("=================================")
// 查询数据NULL对应的值
DB.First(typeMap, 1)
fmt.Printf("%+v\n", typeMap)
}
type CustomTypeModel struct {
gorm.Model
FTime time.Time
FNullTime sql.NullTime
FString string
FNullString sql.NullString
FUUID uuid.UUID
FNullUUID uuid.NullUUID
}
func CustomType() {
//id := uuid.UUID{}
//id.Scan() // Scanner
//id.Value() // Valuer
// 初始化模型
ctm := &CustomTypeModel{}
// 迁移数据表
DB.AutoMigrate(ctm)
// 创建
ctm.FTime = time.Now() // 当前时间
ctm.FNullTime = sql.NullTime{} // 零值Valid默认为false
ctm.FString = ""
ctm.FNullString = sql.NullString{}
ctm.FUUID = uuid.New()
ctm.FNullUUID = uuid.NullUUID{}
DB.Create(ctm)
// 查询
DB.First(ctm, ctm.ID)
// 判定字段是否为NULL
if ctm.FString == "" {
fmt.Println("FString is NULL")
} else {
fmt.Println("FString is NOT NULL")
}
if ctm.FNullString.Valid == false {
fmt.Println("FNullString is NULL")
} else {
fmt.Println("FNullString is NOT NULL")
}
}
type FieldTag struct {
//Field string `gorm:"" json:"" bson:"" xml:""` // Tag
gorm.Model
// string 类型的处理
FStringDefault string `gorm:""`
FTypeChar string `gorm:"type:char(32)"`
FTypeVarchar string `gorm:"type:varchar(255)"`
FTypeText string `gorm:"type:text"`
FTypeBlob []byte `gorm:"type:blob"`
FTypeEnum string `gorm:"type:enum('Go', 'GORM', 'MySQL')"`
FTypeSet string `gorm:"type:set('Go', 'GORM', 'MySQL')"`
FColNum string `gorm:"column:custom_column_name"`
// 默认是NULl
FColNotNull string `gorm:"type:varchar(255);not null;"`
FColDefault string `gorm:"type:varchar(255);not null;default:gorm middle ware;"`
FColComment string `gorm:"type:varchar(255);comment:带有注释的字段"`
}
type IAndC struct {
// 基础索引类型
ID uint `gorm:"primaryKey"`
Email string `gorm:"type:varchar(255);uniqueIndex"` // unique
Age uint8 `gorm:"index;check:age >= 18 AND email is not null"`
// 复合索引
FirstName string `gorm:"index:name"`
LastName string `gorm:"index:name"`
// 顺序关键顺序
// 默认的 priority:10
FirstName1 string `gorm:"index:name1,priority:2"`
LastName1 string `gorm:"index:name1,priority:1"`
// 索引选项前缀长度排序方式comment
Height float32 `gorm:"index:,sort:desc"`
AddressHash string `gorm:"index:,length:12,comment:前12个字符作为索引关键字"`
}
func IAndCCreate() {
iac := &IAndC{}
iac.Age = 18
if err := DB.Create(iac).Error; err != nil {
log.Fatal(err)
}
fmt.Printf("%+v\n", iac)
}
type Service struct {
gorm.Model
//Url string `gorm:"-"` // -:all
Url string `gorm:"-:migration; type:varchar(255)"`
Schema string
Host string `gorm:"<-:false"`
Path string `gorm:"<-:update"`
QueryString string `gorm:"->:false"`
}
func ServiceCRUD() {
s := &Service{}
s.Schema = "http"
s.Host = "www.mashibing.com"
s.Path = "/"
s.Url = "http://www.mashibing.com/"
DB.Create(s)
}
func PaperCrud() {
if err := DB.AutoMigrate(&Paper{}); err != nil {
log.Fatal(err)
}
// 常规操作
paper := &Paper{}
paper.Subject = "使用Serializer操作Tags字段"
paper.Tags = []string{"Go", "Serializer", "Gorm", "MySQL"}
// create 会执行序列化工作,serialize
if err := DB.Create(paper).Error; err != nil {
log.Fatal(err)
}
// 查询
newPaper := &Paper{}
// First会执行反序列化工作unserialize
DB.First(newPaper, 5)
fmt.Printf("%+v\n", newPaper)
}
// 1.定义实现了序列化器接口的类型
type CSVSerializer struct{}
// 实现Scanunserialize时执行
// ctx Context对象
// field 模型的字段对应的类型
// dst 目标值最终结果赋值到dst
// dbValue 从数据库读取的值
// 错误
func (CSVSerializer) Scan(ctx context.Context, field *schema.Field, dst reflect.Value, dbValue interface{}) error {
// 初始化一个用来存储字段值的变量
var fieldValue []string
// 一:解析读取到的数据表的数据
if dbValue != nil { // 不是 NULL
// 支持解析的只有string和[]byte
// 使用类型检测进行判定
var str string
switch v := dbValue.(type) {
case string:
str = v
case []byte:
str = string(v)
default:
return fmt.Errorf("failed to unmarshal CSV value: %#v", dbValue)
}
// 二:核心:将数据表中的字段使用逗号分割,形成 []string
fieldValue = strings.Split(str, ",")
}
// 三将处理好的数据设置到dst上
field.ReflectValueOf(ctx, dst).Set(reflect.ValueOf(fieldValue))
return nil
}
// 实现Value, serialize时执行
// fieldValue 模型的的字段值
func (CSVSerializer) Value(ctx context.Context, field *schema.Field, dst reflect.Value, fieldValue interface{}) (interface{}, error) {
// 将字段值转换为可存储的CSV结构
return strings.Join(fieldValue.([]string), ","), nil
}
type Paper struct {
gorm.Model
Subject string
//Tags []string
// 使用 json 序列化器进行处理
Tags []string `gorm:"serializer:json"`
// 使用自定义的编码器
Categories []string `gorm:"serializer:csv"`
}
// 2.注册到GORM中
// 3.测试
func CustomSerializer() {
// 注册序列化器
schema.RegisterSerializer("csv", CSVSerializer{})
// 测试
if err := DB.AutoMigrate(&Paper{}); err != nil {
log.Fatal(err)
}
// 常规操作
paper := &Paper{}
paper.Subject = "使用自定义的Serializer操作Categories字段"
paper.Tags = []string{"Go", "Serializer", "Gorm", "MySQL"}
paper.Categories = []string{"Go", "Serializer", "Gorm", "MySQL"}
// create 会执行序列化工作,serialize
if err := DB.Create(paper).Error; err != nil {
log.Fatal(err)
}
// 查询
newPaper := &Paper{}
// First会执行反序列化工作unserialize
DB.First(newPaper, paper.ID)
fmt.Printf("%+v\n", newPaper)
}
// 用于处理Blog新增的请求模型
type BlogPost struct {
BlogBasic
}
// 用于更新
type BlogPut struct {
ID uint
BlogBasic
}
// 用于DB表交互的模型
type Blog struct {
gorm.Model
BlogBasic
Author `gorm:"embeddedPrefix:author_"`
}
type BlogBasic struct {
Subject string
Summary string
Content string
}