Gorm特性
- 全特性 ORM (几乎包含所有特性)
- 模型关联 (一对一, 一对多,一对多(反向), 多对多, 多态关联)
- 钩子 (Before/After Create/Save/Update/Delete/Find)
- 预加载
- 事务
- 复合主键
- SQL 构造器
- 自动迁移
- 日志
- 基于GORM回调编写可扩展插件
- 全特性测试覆盖
- 开发者友好
Gorm安装
go get -u gorm.io/gorm
Gorm连接数据库
Gorm的github网址
Gorm目前支持的数据库:
-
Mysql数据库。Mysql数据库的DSN为
username:password@protocol(address:port)/dbname?parm=value
。例:
gorm:gorm@tcp(localhost:3306)/gorm?charset=utf-8&parseTime=True&loc=Local
。 -
PostgresSQL。PostgresSQL数据库的DSN为
user=<username> password=<password> dbname=<dbname> host=<localhost> port=<port>
。例:
user=gorm password=gorm dbname=gorm host=localhost port=9920 sslmode=disable TimeZone=Asia/Shanghai
-
Sqlserver。sqlserver数据库的DSN为
sqlserver://<username>:<password>@<address>:<port>?database=<databasename>
。例:
sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm
通过gorm.Open(对应数据库驱动打开的Dialector)
连接获取数据库
// studydeom/db/mysql.go
import (
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var DB *gorm.DB
func init() {
//连接数据库
var err error
//parseTime的作用:由于在mysql数据库当中时间的存储格式是字符串,该参数可以将时间字符串转化为时间戳返回
DB, err = gorm.Open(mysql.Open("root:password@tcp(127.0.0.1:3306)/gorm_test?charset=utf-8&parseTime=True"))
if err != nil {
panic(err)
}
}
Gorm的模型定义
模型一般都是普通的Golang的结构体,Go的基本数据类型,或者指针。sql.Scanner
和driver.Valuer
,同时也支持接口。
注:在使用gorm的结构体时,字段的首字母需要大写
type User struct {
Id sql.NullInt64 `gorm:"PRIMARY_KEY;AUTO_INCREAMENT"` //id为主键,类型为非空int64位,同时是自增类型 多个字段使用PRIMARY_KEY时,可以使用联合主键
Name string `gorm:"UNIQUE"`
Birthday time.Time
Email string `gorm:"type:varchar(100);unique_index"` //Email的大小位100位,且为唯一索引
Address string `gorm:"index:addr"` //给Address字段建立名为`addr`的索引
IgnoreMe int `gorm:"-"` //忽略该字段
}
Gorm标签
标签 | 说明 |
---|---|
Column | 指定列的名称 |
Type | 指定列的类型 |
Size | 指定列的大小,默认是 255 |
PRIMARY_KEY | 指定一个列作为主键 |
UNIQUE | 指定一个唯一的列 |
DEFAULT | 指定一个列的默认值 |
PRECISION | 指定列的数据的精度 |
NOT NULL | 指定列的数据不为空 |
AUTO_INCREMENT | 指定一个列的数据是否自增 |
INDEX | 创建带或不带名称的索引,同名创建复合索引 |
UNIQUE_INDEX | 类似 索引 ,创建一个唯一的索引 |
EMBEDDED | 将 struct 设置为 embedded |
EMBEDDED_PREFIX | 设置嵌入式结构的前缀名称 |
- | 忽略这些字段 |
关于通过Gorm创建的表
Gorm根据结构体名创建表,创建的表名为结构体名的复数形式(即结构体名为
User
,则表名为users
),且仅对结构体下首字母大写的值创建字段。修改表结构:
与ORM对应的结构体绑定指定表名
func (u User) TableName() string { return "rename_user_oncreate" //可以根据User中不同的属性放入不同的表 }
通过
DB.Migrator()
操作表DB.Table("rename_user").Migrator().CreateTable(&User{}) //create table rename_user {......} var users []User DB.Table("rename_user").Find(&users) //注意:这里传入的是指针 //select * from `rename_user`
Gorm的CRUD
增
testuser := User{Name: "测试用户名", Birthday: time.Now()}
err := DB.Create(&testuser).Error
if err != nil {
fmt.Printf("%v", err)
}//判断是否插入成功
fmt.Printf("%v", testuser) //从执行结果可以看出,在插入数据之后自动填充了插入id 若传入的为数组,则会批量插入
查
关于数据库的简单查询,在执行完查询方法,如First、Take、Find等操作后,会返回一个*grom.DB类型的指针,该指针中的Error属性可以用来判断该操作是否正常执行。
var user User
err := DB.First(&user).Error
if err != nil {
fmt.Printf("%v", err)
}
//select * from users order by id limit 1
err = DB.Take(&user).Error
//select * from users limit 1
if err != nil {
fmt.Printf("%v", err)
}
err = DB.Last(&user).Error
//select * from users order by id DESC limit 1
if err != nil {
fmt.Printf("%v", err)
}
//查询多条记录
var users []User
err = DB.Find(&users).Error
//select * from users
if err != nil {
fmt.Printf("%v", err)
}
err = DB.First(&user, 10).Error
//select * from users where {param0}=10
if err != nil {
fmt.Printf("%v", err)
}
Gorm条件查询
//条件查询
DB.Where("name = ?", "测试用户").First(&user)
//在实际生成的statement中会将?替换为args中的参数,即Where方法的作用是直接在原sql语句中添加where + query
//在query中可以实现如IN、LIKE、AND、BETWEEN等操作
改
注:使用修改数据库中数据时若数据不存在时并不会出现Error
,可以通过*gorm.DB
中的RowsAffected
查看是否有对应的数据行受到影响。
-
先查询要修改的对象,再修改
user := User{Name: "测试用户名"} DB.First(&user) user.Email = "123456@email.com" DB.Save(&user)
-
通过
DB.Model()
更新数据库user := User{Name: "测试用户名"} user.Email = "123456@email.com" rowaffect := DB.Save(&user).RowsAffected if rowaffect != 0{ fmt.Printf("%v",rowaffect) } rowaffect = DB.Model(&user).Where("name = ?", user.Name).Update("email", "654321@email.com") if rowaffect != 0{ fmt.Printf("%v",rowaffect) }
删
err := DB.Delete(&User{Id: sql.NullInt64{
Int64: 1,
Valid: true,
}}).Error
if err != nil{
fmt.Printf("%v",err)
}