model define

main
han-joker 1 year ago
parent 3a354c2134
commit cc82193e20

@ -4,6 +4,7 @@ go 1.20
require (
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
gorm.io/driver/mysql v1.4.7 // indirect

@ -1,5 +1,7 @@
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=

@ -66,4 +66,6 @@ func init() {
}
DB = db
// 注册序列化器
schema.RegisterSerializer("csv", CSVSerializer{})
}

@ -1,9 +1,15 @@
package gormExample
import (
"context"
"database/sql"
"fmt"
"github.com/google/uuid"
"gorm.io/gorm"
"gorm.io/gorm/schema"
"log"
"reflect"
"strings"
"time"
)
@ -36,7 +42,7 @@ type TypeMap struct {
}
func Migrate() {
if err := DB.Debug().AutoMigrate(&TypeMap{}, &Post{}, &Category{}, &PostCategory{}, &Box{}); err != nil {
if err := DB.Debug().AutoMigrate(&Service{}, &IAndC{}, &FieldTag{}, &TypeMap{}, &Post{}, &Category{}, &PostCategory{}, &Box{}); err != nil {
log.Fatal(err)
}
}
@ -52,3 +58,224 @@ func PointerDiff() {
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)
}

@ -9,3 +9,23 @@ func TestMigrate(t *testing.T) {
func TestPointerDiff(t *testing.T) {
PointerDiff()
}
func TestCustomType(t *testing.T) {
CustomType()
}
func TestIAndCCreate(t *testing.T) {
IAndCCreate()
}
func TestServiceCRUD(t *testing.T) {
ServiceCRUD()
}
func TestPaperCrud(t *testing.T) {
PaperCrud()
}
func TestCustomSerializer(t *testing.T) {
CustomSerializer()
}

Loading…
Cancel
Save