Huh is designed to be a light-weight, full-featured and user-friendly ORM library for Golang. Huh is part of my Go learning plan, not an ORM for production ^
- Basic CRUD support
- Callback hooks (BeforeCreate, AfterCreate etc.)
- Transactions and Embeded transactions
- SQL Builder
- Master & Slave DB support
- TODO Raw sql execution
- TODO Explain and index usage checker
- TODO database migration and schema auto-generate
- TODO query cache
- TODO validator
- TODO table relationships
- TODO multiple database dialect support
go get -u github.com/xufeisofly/huhConfig a database connection.
huh.Config("mysql", huh.DBConfig{
Master: "master:pwd@localhost/mysite?charset=utf8&parseTime=True&loc=local",
Slaves: []string{
"slave1:pwd@localhost/mysite?charset=utf8&parseTime=True&loc=local",
},
})
defer huh.Close()Set max connections, idle connections and connection life time.
huh.SetMaxOpenConns(5)
huh.SetMaxIdleConns(2)
huh.SetConnMaxLifetime(time.Second)type User struct {
ID uint32 `huh:"pk"`
Email string
CreatedAt time.Time `huh:"readonly"`
UpdatedAt time.Time `huh:"readonly"`
}
func (u *User) TableName() string {
return "users"
}user := User{ID: 1, Email: "create@huh.com"}
huh.New().Create().Do(ctx, &user)Must create with error raise
huh.New().MustCreate().Do(ctx, &user)Update id = 1 user’s email to update@huh.com.
user := User{ID: 1}
huh.New().Update("email", "update@huh.com").Do(ctx, &user)Update several user’s columns.
user := User{ID: 1}
huh.New().Update("col1", "newValue1", "col2", "newValue2").Do(ctx, &user)Bulk update users
huh.New().Where("email = ?", "sofly@huh.com").Update("email", "update@huh.com").Do(ctx, User{})Must update with error raise
huh.New().MustUpdate("col1", "newValue1", "col2", "newValue2").Do(ctx, &user)Find by Primary Key
user = User{}
huh.New().Get(1).Do(ctx, &user)Find one record by column equality
user = User{}
huh.New().GetBy("email", "sofly@huh.com").Do(ctx, &user)Find records by where condition
users = []User{}
huh.New().Where("email = ?", "sofly@huh.com").Where("created_at > ?", "2019-01-01 00:00:00").Do(ctx, &users)Use map instead of multiple where
huh.New().Where(map[string]interface{}{
"email = ?": "sofly@huh.com",
"created_at > ?": "2019-01-01 00:00:00",
}).Do(ctx, &users)Use And
huh.New().Where("email = ?", "sofly@huh.com").And("created_at > ?", "2019-01-01 00:00:00").Do(ctx, &users)Use Or
huh.New().Where("email = ?", "sofly@huh.com").Or("created_at > ?", "2019-01-01 00:00:00").Do(ctx, &users)huh.New().Get(1).Do(ctx, &user)
huh.New().Destroy().Do(ctx, &user)Bulk destroy users
huh.New().Where("email = ?", "sofly@huh.com").Destroy().Do(ctx, model.User{})Must destroy with error raise
huh.New().MustDestroy().Do(ctx, &user)Selected fields
huh.New().Select("id").Where("email = ?", "sofly@huh.com").Do(ctx, &users)Offset & limit
o.Where("email = ?", "sofly@huh.com").Limit(1).Offset(1).Do(ctx, &users)Order by
o.Where("email = ?", "sofly@huh.com").Order("id desc").Do(ctx, &users)normal transaction
huh.New().Transaction(ctx, func(o *huh.Orm) {
o.Create().Do(ctx, &user)
})nested transaction
huh.New().Transaction(ctx, func(o *huh.Orm) {
o.MustCreate().Do(ctx, &user)
o.Transaction(ctx, func(o *huh.Orm) {
o.MustCreate().Do(ctx, &user2)
})
})Define Callbacks
type User struct {
ID uint32 `huh:"pk"`
Email string
CreatedAt time.Time `huh:"readonly"`
UpdatedAt time.Time `huh:"readonly"`
}
func (u *User) TableName() string {
return "users"
}
func (u User) BeforeCreate(ctx context.Context) error {
if u.ID == 1 {
return errors.New("before create error")
}
return nil
}
func (u *User) BeforeSave(ctx context.Context) error {
u.Email = "update3@huh.com"
return nil
}With callbacks
huh.New().Create().WithCallbacks().Do(ctx, &user)user := User{ID: 1, Email: "sofly@huh.com"}
sql, _ := huh.New().Create().Of(ctx, &user)
fmt.Println(sql)
# => INSERT INTO `users` (`id`, `email`, `created_at`, `updated_at`) VALUES (1, "sofly@huh.com", "2019-01-01 00:00:00", "2019-01-01 00:00:00")