ORM优缺点
优点
- 提高开发效率
缺点
- 牺牲执行性能
- 牺牲灵活性
- 弱化SQL能力
创建数据表
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type UserInfo struct {
ID int
Name string
Gender string
Hobby string
}
func main() {
// 连接数据库
db,err := gorm.Open("mysql","root:root@tcp(192.168.19.11:3306)/userinfo")
if err !=nil{
panic(err)
}
defer db.Close()
// 创建表 自动迁移 (把结构体和数据表进行对应)
db.AutoMigrate(&UserInfo{})
//增加
u1 := UserInfo{ID: 1,Name: "jibu",Gender: "男",Hobby:"钢琴"}
db.Create(&u1)
// 查询
var u UserInfo
db.First(&u)
fmt.Printf("u:%#v\n",u)
//更新
db.Model(&u).Update("hobby","健身")
// 删除
db.Delete(&u)
}
Gorm Model定义
在使用orm工具时,通常我们需要在代码中定义模型与数据库进行映射,在Gorm重模型通常是正常定义的结构体,基本的go类型或它们的指针,
为了方便模型定义,GORM内置类一个gorm.Model结构体.gorm.Model是一个包含了ID,createAT,updateat,deleteat四个字段的goland结构体
// gorm.Model 定义
type Model struct{
ID unit 'gorm:"primary_key"'
CreateAt time.Time
UpdateAt time.Time
DeleteAt *time.Time
}
可以将它嵌入到自己的模型中
// 将 ID CreateAt UpdateAt DeleteAt
type User struct{
gorm.Model
Name string
}
当然也可以完全自己定义模型
type User struct{
ID int
Name string
}
package main
import (
"database/sql"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
"time"
)
type User struct {
gorm.Model
Name string
Age sql.NullInt64
Birthday *time.Time
Email string `gorm:"type:varchar(100);unique_index"`
Role string `gorm:"size:255"`
MemberNumber *string `gorm:"unique;not null"`
Num int `gorm:"AUTO_INCREMENT"`
Address string `gorm:"index:addr"`
IgnoreMe int `gorm:"index:addr"`
}
func main() {
// 连接数据库
db,err := gorm.Open("mysql","root:root@tcp(127.0.0.1:3306)/userinfo")
if err !=nil{
panic(err)
}
defer db.Close()
// 创建表 自动迁移 (把结构体和数据表进行对应)
db.AutoMigrate(&User{})
//增加
//u1 := UserInfo{ID: 1,Name: "jibu",Gender: "男",Hobby:"钢琴"}
//db.Create(&u1)
查询
//var u UserInfo
//db.First(&u)
//fmt.Printf("u:%#v\n",u)
更新
//db.Model(&u).Update("hobby","健身")
删除
//db.Delete(&u)
}
主键 表名 列名的约定
主键
GORM默认会使用名为ID的字段作为表的主键
type User struct{
ID string // 名为ID的字段默认作为表的主键
Name string
}
type User struct{
AnimalID string int64 'gorm:"primary_key"'
Name string
}
表名
表名默认就是结构体名称的复数
User ==》 users
type User struct{
ID string // 名为ID的字段默认作为表的主键
Name string
}
当然也可以自己设置表名
func (User) TableName() string{
return user
}
// 使用结构体创建名为delete_users 的表
db.Table('deleted_users').CreateTable(&User{})
列名
列名由字段名称进行下划线分割生成,如果是两个单词在一起默认使用下划线连接
时间戳跟踪
CreateAt
如果模型由CreateAt 字段,该字段的值将会是初次创建记录的时间
db.Create(&user) // 当前时间
// 可以使用Update方法改变CreateAt的值
db.Model(&user).Update("CreatedAt",time.Now())
UpdateAt 同上
DeletedAt
如果模型由DeleteAt字段,调用Delete删除该记录时,将会设置DeletedAt字段为当前时间,而不是直接从数据库删除,它不是真正的删除,但是如果删完后你去查询 查询为空
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
ID int64
Name string
Age int64
}
func main() {
// 连接数据库
db,err := gorm.Open("mysql","root:root@tcp(192.168.19.11:3306)/userinfo")
if err !=nil{
panic(err)
}
defer db.Close()
// 把模型与数据库重的表对应起来、
db.AutoMigrate(&User{})
//创建
u := User{Name:"jibu",Age: 10} //在代码层创建一个User对象
// 判断主键是否为空
fmt.Println(db.NewRecord(&u))
db.Create(&u)
fmt.Println(db.NewRecord(&u))
}
当代码实际执行的SQL语句是INsert into users(“ages” ) values(“99”);排除了零值字段Name,而在数据库重这一条数据会使用设置的默认值毛蛋作为Name字段的值
注意:所有字段的零值,比如 0 “" false 或者其他零值,都不会保存倒数据库内,但是会使用它们的默认值。如果想避免这种情况,可以考虑使用指针或实现scanner/value接口
使用指针方式将零值存入数据库
type User struct {
ID int64
Name string `gorm:"default:'毛蛋'"`
Age int64
}
user :=User{Name:new(string),Age:18}
db.Create(&User) //此时数据库重该条记录name字段的值是""
type User struct {
ID int64
// sql.NullSting 实现了Scanner/value接口
Name sql.BUllString `gorm:"default:'毛蛋'"`
Age int64
}
user :=User{Name:new(string),Age:18}
db.Create(&User) //此时数据库重该条记录name字段的值是""