go 学习之gorm
gorm是一个饱受好评的orm框架,此处数据库我们以mysql为例
import ( "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) var db *gorm.DB
func init() { var err error db, err = gorm.Open("mysql", "<user>:<password>/<database>?charset=utf8&parseTime=True&loc=Local")#非常简便就创建了一个数据库连接 if err != nil { panic(err) } }
光创建连接还不够,我们还需要model
type User struct { gorm.Model Name string Age sql.NullInt64 # import "dataase/sql" Birthday *time.Time # import time Email string `gorm:"type:varchar(100);unique_index"` Role string `gorm:"size:255"` // 设置字段大小为255 MemberNumber *string `gorm:"unique;not null"` // 设置会员号(member number)唯一并且不为空 Num int `gorm:"AUTO_INCREMENT"` // 设置 num 为自增类型 Address string `gorm:"index:addr"` // 给address字段创建名为addr的索引 IgnoreMe int `gorm:"-"` // 忽略本字段 }
#这个结构体就对应我们的数据库表
下一步我们就开始迁移数据库
方法一 手动创建表: if !db.HasTable(&User{}) { db.Set("gorm:table_options", "ENGINE=InnoDB DEFAULT CHARSET=utf8").CreateTable(&User{}) } 方法二 自动迁移命令: db.AutoMigrate(&User{}) //注意:自动迁移 只会 创建表、缺失的列、缺失的索引, 不会 更改现有列的类型或删除未使用的列,以此来保护您的数据。
//也就是说我们修改user结构体 注销age属性,添加一个sex属性,自动迁移后,表结构还是存在age字段,添加sex字段
然后我们来简单说说增删改查
#增 user := User{Name: "Jinzhu",Sex:"1", Age: 18} db.Create(&user) #查询 var user [] User // 获取第一条记录,按主键排序 db.First(&user) //// SELECT * FROM users ORDER BY id LIMIT 1; // 获取最后一条记录,按主键排序 db.Last(&user) //// SELECT * FROM users ORDER BY id DESC LIMIT 1; // 获取所有记录 db.Find(&users) //// SELECT * FROM users; // 使用主键获取记录 db.First(&user, 10) //// SELECT * FROM users WHERE id = 10; Where查询条件 (简单SQL) // 获取第一个匹配记录 db.Where("name = ?", "jinzhu").First(&user) //// SELECT * FROM users WHERE name = 'jinzhu' limit 1; // 获取所有匹配记录 db.Where("name = ?", "jinzhu").Find(&users) //// SELECT * FROM users WHERE name = 'jinzhu'; db.Where("name <> ?", "jinzhu").Find(&users) // IN db.Where("name in (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users) // LIKE db.Where("name LIKE ?", "%jin%").Find(&users) // AND db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users) // Time db.Where("updated_at > ?", lastWeek).Find(&users) db.Where("created_at BETWEEN ? AND ?", lastWeek, today).Find(&users) Where查询条件 (Struct & Map) 注意:当使用struct查询时,GORM将只查询那些具有值的字段 // Struct db.Where(&User{Name: "jinzhu", Age: 20}).First(&user) //// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 LIMIT 1; // Map db.Where(map[string]interface{}{"name": "jinzhu", "age": 20}).Find(&users) //// SELECT * FROM users WHERE name = "jinzhu" AND age = 20; // 主键的Slice db.Where([]int64{20, 21, 22}).Find(&users) //// SELECT * FROM users WHERE id IN (20, 21, 22); 1.2.3. Not条件查询 db.Not("name", "jinzhu").First(&user) //// SELECT * FROM users WHERE name <> "jinzhu" LIMIT 1; // Not In db.Not("name", []string{"jinzhu", "jinzhu 2"}).Find(&users) //// SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2"); // Not In slice of primary keys db.Not([]int64{1,2,3}).First(&user) //// SELECT * FROM users WHERE id NOT IN (1,2,3); db.Not([]int64{}).First(&user) //// SELECT * FROM users; // Plain SQL db.Not("name = ?", "jinzhu").First(&user) //// SELECT * FROM users WHERE NOT(name = "jinzhu"); // Struct db.Not(User{Name: "jinzhu"}).First(&user) //// SELECT * FROM users WHERE name <> "jinzhu"; #user为查询的结果数组 删除操作 // 删除存在的记录 db.Delete(&email) //// DELETE from emails where id=10; // 为Delete语句添加额外的SQL选项 db.Set("gorm:delete_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Delete(&email) //// DELETE from emails where id=10 OPTION (OPTIMIZE FOR UNKNOWN); 批量删除 删除所有匹配记录 db.Where("email LIKE ?", "%jinzhu%").Delete(Email{}) //// DELETE from emails where email LIKE "%jinhu%"; db.Delete(Email{}, "email LIKE ?", "%jinzhu%") //// DELETE from emails where email LIKE "%jinhu%"; 软删除 如果模型有DeletedAt字段,它将自动获得软删除功能! 那么在调用Delete时不会从数据库中永久删除,而是只将字段DeletedAt的值设置为当前时间。 db.Delete(&user) //// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111; // 批量删除 db.Where("age = ?", 20).Delete(&User{}) //// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20; // 软删除的记录将在查询时被忽略 db.Where("age = 20").Find(&user) //// SELECT * FROM users WHERE age = 20 AND deleted_at IS NULL; // 使用Unscoped查找软删除的记录 db.Unscoped().Where("age = 20").Find(&users) //// SELECT * FROM users WHERE age = 20; // 使用Unscoped永久删除记录 db.Unscoped().Delete(&order) //// DELETE FROM orders WHERE id=10; 更新操作 更新全部字段 Save将包括执行更新SQL时的所有字段,即使它没有更改 db.First(&user) user.Name = "jinzhu 2" user.Age = 100 db.Save(&user) //// UPDATE users SET name='jinzhu 2', age=100, birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=111; 更新更改字段 如果只想更新更改的字段,可以使用Update, Updates 更新单个属性(如果更改) db.Model(&user).Update("name", "hello") //// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111; // 使用组合条件更新单个属性 db.Model(&user).Where("active = ?", true).Update("name", "hello") //// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true; // 使用`map`更新多个属性,只会更新这些更改的字段 db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false}) //// UPDATE users SET name='hello', age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111; // 使用`struct`更新多个属性,只会更新这些更改的和非空白字段 db.Model(&user).Updates(User{Name: "hello", Age: 18}) //// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111; // 警告:当使用struct更新时,FORM将仅更新具有非空值的字段 // 对于下面的更新,什么都不会更新为"",0,false是其类型的空白值 db.Model(&user).Updates(User{Name: "", Age: 0, Actived: false}) 更新选择的字段 如果您只想在更新时更新或忽略某些字段,可以使用Select, Omit db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false}) //// UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111; db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false}) //// UPDATE users SET age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111; 更新更改字段但不进行Callbacks 以上更新操作将执行模型的BeforeUpdate, AfterUpdate方法,更新其UpdatedAt时间戳,在更新时保存它的Associations,如果不想调用它们,可以使用UpdateColumn, UpdateColumns // 更新单个属性,类似于`Update` db.Model(&user).UpdateColumn("name", "hello") //// UPDATE users SET name='hello' WHERE id = 111; // 更新多个属性,与“更新”类似 db.Model(&user).UpdateColumns(User{Name: "hello", Age: 18}) //// UPDATE users SET name='hello', age=18 WHERE id = 111; Batch Updates 批量更新 Callbacks在批量更新时不会运行 db.Table("users").Where("id IN (?)", []int{10, 11}).Updates(map[string]interface{}{"name": "hello", "age": 18}) //// UPDATE users SET name='hello', age=18 WHERE id IN (10, 11); // 使用struct更新仅适用于非零值,或使用map[string]interface{} db.Model(User{}).Updates(User{Name: "hello", Age: 18}) //// UPDATE users SET name='hello', age=18; // 使用`RowsAffected`获取更新记录计数 db.Model(User{}).Updates(User{Name: "hello", Age: 18}).RowsAffected