在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:toyorm开源软件地址:https://gitee.com/bigpigeon/toyorm开源软件介绍:Toyormthis is powerful sql orm library for Golang, have some funny features
Support databaseGo versionversion go-1.9 A Simple ExampleWebsite ExampleDatabase connectionimport database driver // if database is mysql_ "github.com/go-sql-driver/mysql"// if database is sqlite3_ "github.com/mattn/go-sqlite3"// when database is postgres_ "github.com/lib/pq" create a toy // if database is mysql, make sure your mysql have toyorm_example schematoy, err = toyorm.Open("mysql", "root:@tcp(localhost:3306)/toyorm_example?charset=utf8&parseTime=True")// if database is sqlite3toy,err = toyorm.Open("sqlite3", "toyorm_test.db")// when database is postgrestoy, err = toyorm.Open("postgres", "user=postgres dbname=toyorm sslmode=disable") Model definitionexampletype Extra map[string]interface{}func (e Extra) Scan(value interface{}) error { switch v := value.(type) { case string: return json.Unmarshal([]byte(v), e) case []byte: return json.Unmarshal(v, e) default: return errors.New("not support type") }}func (e Extra) Value() (driver.Value, error) { return json.Marshal(e)}type UserDetail struct { ID int `toyorm:"primary key;auto_increment"` UserID uint `toyorm:"index"` MainPage string Extra Extra `toyorm:"type:VARCHAR(1024)"`}type Blog struct { toyorm.ModelDefault UserID uint `toyorm:"index"` Title string `toyorm:"index"` Content string}type User struct { toyorm.ModelDefault Name string `toyorm:"unique index"` Age int Sex string Detail *UserDetail Friends []*User Blog []Blog} type translateif sql type is not match, toyorm will ignore it in Sql Operation you can use <type:sql_type> field tag to specified their sql type the following type will auto translate to sql type
special fields
field tags
other custom TAG will append to end of CREATE TABLE field Bind models
brick := toy.Model(&User{})// orbrick := toy.Model(User{}) Sql Operationcreate tablevar err error_, err = toy.Model(&User{}).Debug().CreateTable()// CREATE TABLE user (id BIGINT AUTO_INCREMENT,created_at TIMESTAMP NULL,updated_at TIMESTAMP NULL,deleted_at TIMESTAMP NULL,name VARCHAR(255),age BIGINT ,sex VARCHAR(255) , PRIMARY KEY(id))// CREATE INDEX idx_user_deletedat ON user(deleted_at)// CREATE UNIQUE INDEX udx_user_name ON user(name)_, err =toy.Model(&UserDetail{}).Debug().CreateTable()// CREATE TABLE user_detail (id BIGINT AUTO_INCREMENT,user_id BIGINT,main_page Text,extra VARCHAR(1024), PRIMARY KEY(id))// CREATE INDEX idx_user_detail_userid ON user_detail(user_id)_, err =toy.Model(&Blog{}).Debug().CreateTable()// CREATE TABLE blog (id BIGINT AUTO_INCREMENT,created_at TIMESTAMP NULL,updated_at TIMESTAMP NULL,deleted_at TIMESTAMP NULL,user_id BIGINT,title VARCHAR(255),content VARCHAR(255) , PRIMARY KEY(id))// CREATE INDEX idx_blog_deletedat ON blog(deleted_at)// CREATE INDEX idx_blog_userid ON blog(user_id)// CREATE INDEX idx_blog_title ON blog(title) drop tablevar err error_, err =toy.Model(&User{}).Debug().DropTable()// DROP TABLE user_, err =toy.Model(&UserDetail{}).Debug().DropTable()// DROP TABLE user_detail_, err =toy.Model(&Blog{}).Debug().DropTable()// DROP TABLE blog insert/save data// insert with autoincrement will set id to source data user := &User{ Name: "bigpigeon", Age: 18, Sex: "male",}_, err = toy.Model(&User{}).Debug().Insert(&user)// INSERT INTO user(created_at,updated_at,name,age,sex) VALUES(?,?,?,?,?) , args:[]interface {}{time.Time{wall:0xbe8df5112e7f07c8, ext:210013499, loc:(*time.Location)(0x141af80)}, time.Time{wall:0xbe8df5112e7f1768, ext:210017044, loc:(*time.Location)(0x141af80)}, "bigpigeon", 18, "male"}// print user format with json/* { "ID": 1, "CreatedAt": "2018-01-11T20:47:00.780077+08:00", "UpdatedAt": "2018-01-11T20:47:00.780081+08:00", "DeletedAt": null, "Name": "bigpigeon", "Age": 18, "Sex": "male", "Detail": null, "Friends": null, "Blog": null}*/ // save data use "REPLACE INTO" when primary key exist users := []User{ { ModelDefault: toyorm.ModelDefault{ID: 1}, Name: "bigpigeon", Age: 18, Sex: "male", }, { Name: "fatpigeon", Age: 27, Sex: "male", },}_, err = toy.Model(&User{}).Debug().Save(&user)// SELECT id,created_at FROM user WHERE id IN (?), args:[]interface {}{0x1}// REPLACE INTO user(id,created_at,updated_at,name,age,sex) VALUES(?,?,?,?,?,?) , args:[]interface {}{0x1, time.Time{wall:0x0, ext:63651278036, loc:(*time.Location)(nil)}, time.Time{wall:0xbe8dfb5511465918, ext:302600558, loc:(*time.Location)(0x141af80)}, "bigpigeon", 18, "male"}// INSERT INTO user(created_at,updated_at,name,age,sex) VALUES(?,?,?,?,?) , args:[]interface {}{time.Time{wall:0xbe8dfb551131b7d8, ext:301251230, loc:(*time.Location)(0x141af80)}, time.Time{wall:0xbe8dfb5511465918, ext:302600558, loc:(*time.Location)(0x141af80)}, "fatpigeon", 27, "male"} updatetoy.Model(&User{}).Debug().Update(&User{ Age: 4,})// UPDATE user SET updated_at=?,age=? WHERE deleted_at IS NULL, args:[]interface {}{time.Time{wall:0xbe8df4eb81b6c050, ext:233425327, loc:(*time.Location)(0x141af80)}, 4} findfind one var user User_, err = toy.Model(&User{}).Debug().Find(&user}// SELECT id,created_at,updated_at,deleted_at,name,age,sex FROM user WHERE deleted_at IS NULL LIMIT 1, args:[]interface {}(nil)// print user format with json/* { "ID": 1, "CreatedAt": "2018-01-11T12:47:01Z", "UpdatedAt": "2018-01-11T12:47:01Z", "DeletedAt": null, "Name": "bigpigeon", "Age": 4, "Sex": "male", "Detail": null, "Friends": null, "Blog": null}*/ find multiple var users []User_, err = brick.Debug().Find(&users)fmt.Printf("find users %s\n", JsonEncode(&users))// SELECT id,created_at,updated_at,deleted_at,name,age,sex FROM user WHERE deleted_at IS NULL, args:[]interface {}(nil) deletedelete with primary key _, err = brick.Debug().Delete(&user)// UPDATE user SET deleted_at=? WHERE id IN (?), args:[]interface {}{(*time.Time)(0xc4200f0520), 0x1} delete with condition _, err = brick.Debug().Where(toyorm.ExprEqual, Offsetof(User{}.Name), "bigpigeon").DeleteWithConditions()// UPDATE user SET deleted_at=? WHERE name = ?, args:[]interface {}{(*time.Time)(0xc4200dbfa0), "bigpigeon"} ToyBrickuse toy.Model will create a ToyBrick, you need use it to build grammar and operate the database Where conditionaffective update/find/delete operation usagewhere will clean old conditions and make new one brick.Where(<expr>, <Key>, [value]) whereGroup add multiple condition with same expr brick.WhereGroup(<expr>, <group>) conditions will copy conditions and clean old conditions brick.Conditions(<toyorm.Search>) or & and condition will use or/and to link new condition when current condition is not nil brick.Or().Condition(<expr>, <Key>, [value])brick.Or().ConditionGroup(<expr>, <group>)brick.And().Condition(<expr>, <Key>, [value]) or & and conditions will use or/and to link new conditions brick.Or().Conditions(<toyorm.Search>)brick.And().Conditions(<toyorm.Search>) SearchExpr
examplesingle condition brick = brick.Where(toyorm.ExprEqual, Offsetof(Product{}.Tag), "food")or use stringbrick = brick.Where("=", Offsetof(Product{}.Tag), "food")// WHERE tag = "food" combination condition brick = brick.Where(toyorm.ExprEqual, Offsetof(Product{}.Count), 2).And(). Condition(toyorm.ExprGreater, Offsetof(Product{}.Price), 3).Or(). Condition(toyorm.ExprEqual, Offsetof(Product{}.Count), 4)or use stringbrick = brick.Where("=", Offsetof(Product{}.Count), 2).And(). Condition(">", Offsetof(Product{}.Price), 3).Or(). Condition("=", Offsetof(Product{}.Count), 4)// WHERE count = 2 and price > 3 or count = 4 priority condition brick.Where(toyorm.ExprGreater, Offsetof(Product{}.Price), 3).And().Conditions( brick.Where(toyorm.ExprEqual, Offsetof(Product{}.Count), 2).Or(). Condition(toyorm.ExprEqual, Offsetof(Product{}.Count), 1).Search)or use stringbrick.Where(">", Offsetof(Product{}.Price), 3).And().Conditions( brick.Where("=", Offsetof(Product{}.Count), 2).Or(). Condition("=", Offsetof(Product{}.Count), 1).Search)// WHERE price > 3 and (count = 2 or count = 1) brick.Conditions( brick.Where(toyorm.ExprEqual, Offsetof(Product{}.Count), 2).Or(). Condition(toyorm.ExprEqual, Offsetof(Product{}.Count), 1).Search,).And().Conditions( brick.Where(toyorm.ExprEqual, Offsetof(Product{}.Price), 3).Or(). Condition(toyorm.ExprEqual, Offsetof(Product{}.Price), 4).Search,)or use stringbrick.Conditions( brick.Where("=", Offsetof(Product{}.Count), 2).Or(). Condition("=", Offsetof(Product{}.Count), 1).Search,).And().Conditions( brick.Where("=", Offsetof(Product{}.Price), 3).Or(). Condition("=", Offsetof(Product{}.Price), 4).Search,)// WHERE (count = ? OR count = ?) AND (price = ? OR price = ?) limit & offset brick := brick.Offset(2).Limit(2)// LIMIT 2 OFFSET 2 order by brick = brick.OrderBy(Offsetof(Product{}.Name))// ORDER BY name order by desc brick = brick.OrderBy(brick.ToDesc(Offsetof(Product{}.Name)))// ORDER BY name DESC Template Fieldsometimes the condition of sql is not a normal field, use TempField to wrapper normal field brick = brick.Where("=", brick.TempField(Offsetof(Product{}.Name), "LOWER(%s)"), "name")// WHERE LOWER(name) = ? Transactionstart a transaction brick = brick.Begin() rollback all sql action err = brick.Rollback() commit all sql action err = brick.Commit() Debugif Set debug all sql action will have log brick = brick.Debug() IgnoreModewhen I Update or Search with struct that have some zero value, did I update it ? use IgnoreMode to differentiate what zero value should update brick = brick.IgnoreMode(toyorm.Mode("Update"), toyorm.IgnoreZero ^ toyorm.IgnoreZeroLen)// ignore all zeor value but excloud zero len slice// now field = []int(nil) will ignore when update// but field = []int{} will update when update// now field = map[int]int(nil) will ignore when update// but field = map[int]int{} will update when update In default
All of IgnoreMode
BindFieldsif bind a not null fields, the IgnoreMode will failure { var p Product result, err := brick.BindDefaultFields(Offsetof(p.Price), Offsetof(p.UpdatedAt)).Update(&Product{ Price: 0, }) // process error ...}var products []Productresult, err = brick.Find(&products)// process error...for _, p := range products { fmt.Printf("product name %s, price %v\n", p.Name, p.Price)} Scopeuse scope to do some custom operation // desc all order by fieldsbrick.Scope(func(t *ToyBrick) *ToyBrick{ newOrderBy := make([]*ModelFields, len(t.orderB |
请发表评论