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

2 years ago
package gormExample
import (
2 years ago
"context"
"database/sql"
2 years ago
"fmt"
2 years ago
"github.com/google/uuid"
2 years ago
"gorm.io/gorm"
2 years ago
"gorm.io/gorm/schema"
2 years ago
"log"
2 years ago
"reflect"
"strings"
2 years ago
"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() {
2 years ago
if err := DB.Debug().AutoMigrate(&Blog{}, &Service{}, &IAndC{}, &FieldTag{}, &TypeMap{}, &Post{}, &Category{}, &PostCategory{}, &Box{}); err != nil {
2 years ago
log.Fatal(err)
}
}
func PointerDiff() {
// 模型的零值
typeMap := &TypeMap{}
fmt.Printf("%+v\n", typeMap)
fmt.Println("=================================")
// 查询数据NULL对应的值
DB.First(typeMap, 1)
fmt.Printf("%+v\n", typeMap)
}
2 years ago
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)
}
2 years ago
// 用于处理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
}