Gorm model定义: string VS *string

string vs *string

各种数据类型及对应的默认值

  • 指针类型的默认值为nil
package main

import "fmt"

func main() {
    
    
	var b bool
	var i int
	var f32 float32
	var f64 float64
	var c64 complex64
	var c128 complex128
	var s string
	var a [3]int
	var sl []int
	var m map[string]int
	var p struct {
    
    
		x int
		y float64
	}
	var pStr *string

	fmt.Printf("bool: %v\n", b)          // 输出:bool: false
	fmt.Printf("int: %v\n", i)           // 输出:int: 0
	fmt.Printf("float32: %v\n", f32)     // 输出:float32: 0
	fmt.Printf("float64: %v\n", f64)     // 输出:float64: 0
	fmt.Printf("complex64: %v\n", c64)   // 输出:complex64: (0+0i)
	fmt.Printf("complex128: %v\n", c128) // 输出:complex128: (0+0i)
	fmt.Printf("string: %q\n", s)        // 输出:string: ""
	fmt.Printf("array: %v\n", a)         // 输出:array: [0 0 0]
	fmt.Printf("slice: %v\n", sl)        // 输出:slice: []
	fmt.Printf("map: %v\n", m)           // 输出:map: map[]
	fmt.Printf("struct: %+v\n", p)       // 输出:struct: {x:0 y:0}
	fmt.Printf("pointer: %v\n", pStr)    // 输出:struct: {x:0 y:0}
}

下面通过简单的案例看二者的区别。

case1: 数据表字段可以为null

建表语句

create table user
(
    id   int auto_increment primary key,
    name varchar(20) null
);

string类型

数据库表 users 对应的 结构体中 name为string类型

type User struct {
    
    
    ID   int    `gorm:"column:id"`
    Name string `gorm:"column:name"`
}

插入记录

package main

import (
	"fmt"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type User struct {
    
    
	ID   int    `gorm:"column:id"`
	Name string `gorm:"column:name"`
}

func main() {
    
    
	dsn := "root:123456@tcp(127.0.0.1:3306)/example?utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
    
    })
	if err != nil {
    
    
		return
	}

	// 插入一条记录
	db.Debug().Create(&User{
    
    })

	// 读取一条数据
	var user User
	db.Debug().First(&user)
	fmt.Printf("%+v\n", user)
	fmt.Println(user.Name == "")
}

执行的 sql: 插入的 name值赋值为 空字符串''
image.png

数据库表中的情况,name为空字符串

image.png


*string类型

数据库表 users 对应的 结构体中 name为string类型

type User struct {
    
    
	ID   int     `gorm:"column:id"`
	Name *string `gorm:"column:name"`
}
package main

import (
    "fmt"

    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

type User struct {
    
    
    ID   int     `gorm:"column:id"`
    Name *string `gorm:"column:name"`
}

func main() {
    
    
    dsn := "root:123456@tcp(127.0.0.1:3306)/example?utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
    
    })
    if err != nil {
    
    
        return
    }

    // 插入一条记录
    db.Debug().Create(&User{
    
    })

    // 读取一条数据
    var user User
    db.Debug().First(&user)
    fmt.Printf("%+v\n", user)
}

执行结果:
image.png
image.png

由于 name是 *string类型,未初始化默认为nil,插入时作为NULL插入,读取出来的 Name值也是nil



case2: 数据库字段不为null

建表语句

create table users
(
    id   int auto_increment primary key,
    name varchar(20) not null
);



string类型

Name为string类型

type User struct {
    
    
	ID   int    `gorm:"column:id"`
	Name string `gorm:"column:name"`
}
package main

import (
	"fmt"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type User struct {
    
    
	ID   int    `gorm:"column:id"`
	Name string `gorm:"column:name"`
}

func main() {
    
    
	dsn := "root:123456@tcp(127.0.0.1:3306)/example?utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
    
    })
	if err != nil {
    
    
		return
	}

	// 插入一条记录
	db.Debug().Create(&User{
    
    })

	// 读取一条数据
	var user User
	db.Debug().First(&user)
	fmt.Printf("%+v\n", user)
}

image.png
image.png

写入、读取的都是空字符串



*string类型(重点⭐️)
type User struct {
    
    
	ID   int     `gorm:"column:id"`
	Name *string `gorm:"column:name"`
}
package main

import (
	"fmt"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type User struct {
    
    
	ID   int     `gorm:"column:id"`
	Name *string `gorm:"column:name"`
}

func main() {
    
    
	dsn := "root:123456@tcp(127.0.0.1:3306)/example?utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
    
    })
	if err != nil {
    
    
		return
	}

	// 插入一条记录
	db.Debug().Create(&User{
    
    })

	// 读取一条数据
	var user User
	db.Debug().First(&user)
	fmt.Printf("%+v\n", user)
}

image.png
image.png

当 go对象类型为 *string 且为nil时,对应插入语句值为NULL,而由于数据库表定义的name字段不为NULL,故插入失败。

总结

  • 数据库字段可以null时,映射到go的数据类型应为指针类型
  • 数据库字段不可以null时,映射到go的数据类型应为非指针类型


go初学者,写的不一定正确, 如发现错误欢迎评论区交流,thanks

猜你喜欢

转载自blog.csdn.net/VariatioZbw/article/details/132072448