{"id":13366936,"url":"https://github.com/Go-xorm/xorm","last_synced_at":"2025-03-12T18:31:45.143Z","repository":{"id":8378928,"uuid":"9950667","full_name":"go-xorm/xorm","owner":"go-xorm","description":"Simple and Powerful ORM for Go, support mysql,postgres,tidb,sqlite3,mssql,oracle, Moved to https://gitea.com/xorm/xorm","archived":true,"fork":false,"pushed_at":"2020-04-03T01:12:12.000Z","size":4278,"stargazers_count":6659,"open_issues_count":307,"forks_count":758,"subscribers_count":266,"default_branch":"master","last_synced_at":"2024-03-27T04:53:48.532Z","etag":null,"topics":["golang","mssql","mysql","orm","postgres","postgresql","sqlite","tidb"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/go-xorm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-05-09T02:35:04.000Z","updated_at":"2024-03-26T10:35:37.000Z","dependencies_parsed_at":"2022-07-14T21:46:51.467Z","dependency_job_id":null,"html_url":"https://github.com/go-xorm/xorm","commit_stats":null,"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-xorm%2Fxorm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-xorm%2Fxorm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-xorm%2Fxorm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-xorm%2Fxorm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/go-xorm","download_url":"https://codeload.github.com/go-xorm/xorm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221309874,"owners_count":16795828,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","mssql","mysql","orm","postgres","postgresql","sqlite","tidb"],"created_at":"2024-07-30T00:01:34.507Z","updated_at":"2024-10-24T11:30:40.134Z","avatar_url":"https://github.com/go-xorm.png","language":"Go","readme":"# xorm HAS BEEN MOVED TO https://gitea.com/xorm/xorm . THIS REPOSITORY WILL NOT BE UPDATED ANY MORE.\n\n[中文](https://github.com/go-xorm/xorm/blob/master/README_CN.md)\n\nXorm is a simple and powerful ORM for Go.\n\n[![CircleCI](https://circleci.com/gh/go-xorm/xorm.svg?style=shield)](https://circleci.com/gh/go-xorm/xorm) [![codecov](https://codecov.io/gh/go-xorm/xorm/branch/master/graph/badge.svg)](https://codecov.io/gh/go-xorm/xorm)\n[![](https://goreportcard.com/badge/github.com/go-xorm/xorm)](https://goreportcard.com/report/github.com/go-xorm/xorm) \n[![Join the chat at https://img.shields.io/discord/323460943201959939.svg](https://img.shields.io/discord/323460943201959939.svg)](https://discord.gg/HuR2CF3)\n\n## Features\n\n* Struct \u003c-\u003e Table Mapping Support\n\n* Chainable APIs\n\n* Transaction Support\n\n* Both ORM and raw SQL operation Support\n\n* Sync database schema Support\n\n* Query Cache speed up\n\n* Database Reverse support, See [Xorm Tool README](https://github.com/go-xorm/cmd/blob/master/README.md)\n\n* Simple cascade loading support\n\n* Optimistic Locking support\n\n* SQL Builder support via [xorm.io/builder](https://xorm.io/builder)\n\n* Automatical Read/Write seperatelly\n\n* Postgres schema support\n\n* Context Cache support\n\n## Drivers Support\n\nDrivers for Go's sql package which currently support database/sql includes:\n\n* Mysql: [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql)\n\n* MyMysql: [github.com/ziutek/mymysql/godrv](https://github.com/ziutek/mymysql/tree/master/godrv)\n\n* Postgres: [github.com/lib/pq](https://github.com/lib/pq)\n\n* Tidb: [github.com/pingcap/tidb](https://github.com/pingcap/tidb)\n\n* SQLite: [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3)\n\n* MsSql: [github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb)\n\n* Oracle: [github.com/mattn/go-oci8](https://github.com/mattn/go-oci8) (experiment)\n\n## Installation\n\n\tgo get github.com/go-xorm/xorm\n\n## Documents\n\n* [Manual](http://xorm.io/docs)\n\n* [GoDoc](http://godoc.org/github.com/go-xorm/xorm)\n\n## Quick Start\n\n* Create Engine\n\n```Go\nengine, err := xorm.NewEngine(driverName, dataSourceName)\n```\n\n* Define a struct and Sync2 table struct to database\n\n```Go\ntype User struct {\n    Id int64\n    Name string\n    Salt string\n    Age int\n    Passwd string `xorm:\"varchar(200)\"`\n    Created time.Time `xorm:\"created\"`\n    Updated time.Time `xorm:\"updated\"`\n}\n\nerr := engine.Sync2(new(User))\n```\n\n* Create Engine Group\n\n```Go\ndataSourceNameSlice := []string{masterDataSourceName, slave1DataSourceName, slave2DataSourceName}\nengineGroup, err := xorm.NewEngineGroup(driverName, dataSourceNameSlice)\n```\n\n```Go\nmasterEngine, err := xorm.NewEngine(driverName, masterDataSourceName)\nslave1Engine, err := xorm.NewEngine(driverName, slave1DataSourceName)\nslave2Engine, err := xorm.NewEngine(driverName, slave2DataSourceName)\nengineGroup, err := xorm.NewEngineGroup(masterEngine, []*Engine{slave1Engine, slave2Engine})\n```\n\nThen all place where `engine` you can just use `engineGroup`.\n\n* `Query` runs a SQL string, the returned results is `[]map[string][]byte`, `QueryString` returns `[]map[string]string`, `QueryInterface` returns `[]map[string]interface{}`.\n\n```Go\nresults, err := engine.Query(\"select * from user\")\nresults, err := engine.Where(\"a = 1\").Query()\n\nresults, err := engine.QueryString(\"select * from user\")\nresults, err := engine.Where(\"a = 1\").QueryString()\n\nresults, err := engine.QueryInterface(\"select * from user\")\nresults, err := engine.Where(\"a = 1\").QueryInterface()\n```\n\n* `Exec` runs a SQL string, it returns `affected` and `error`\n\n```Go\naffected, err := engine.Exec(\"update user set age = ? where name = ?\", age, name)\n```\n\n* `Insert` one or multiple records to database\n\n```Go\naffected, err := engine.Insert(\u0026user)\n// INSERT INTO struct () values ()\n\naffected, err := engine.Insert(\u0026user1, \u0026user2)\n// INSERT INTO struct1 () values ()\n// INSERT INTO struct2 () values ()\n\naffected, err := engine.Insert(\u0026users)\n// INSERT INTO struct () values (),(),()\n\naffected, err := engine.Insert(\u0026user1, \u0026users)\n// INSERT INTO struct1 () values ()\n// INSERT INTO struct2 () values (),(),()\n```\n\n* `Get` query one record from database\n\n```Go\nhas, err := engine.Get(\u0026user)\n// SELECT * FROM user LIMIT 1\n\nhas, err := engine.Where(\"name = ?\", name).Desc(\"id\").Get(\u0026user)\n// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1\n\nvar name string\nhas, err := engine.Table(\u0026user).Where(\"id = ?\", id).Cols(\"name\").Get(\u0026name)\n// SELECT name FROM user WHERE id = ?\n\nvar id int64\nhas, err := engine.Table(\u0026user).Where(\"name = ?\", name).Cols(\"id\").Get(\u0026id)\nhas, err := engine.SQL(\"select id from user\").Get(\u0026id)\n// SELECT id FROM user WHERE name = ?\n\nvar valuesMap = make(map[string]string)\nhas, err := engine.Table(\u0026user).Where(\"id = ?\", id).Get(\u0026valuesMap)\n// SELECT * FROM user WHERE id = ?\n\nvar valuesSlice = make([]interface{}, len(cols))\nhas, err := engine.Table(\u0026user).Where(\"id = ?\", id).Cols(cols...).Get(\u0026valuesSlice)\n// SELECT col1, col2, col3 FROM user WHERE id = ?\n```\n\n* `Exist` check if one record exist on table\n\n```Go\nhas, err := testEngine.Exist(new(RecordExist))\n// SELECT * FROM record_exist LIMIT 1\n\nhas, err = testEngine.Exist(\u0026RecordExist{\n\t\tName: \"test1\",\n\t})\n// SELECT * FROM record_exist WHERE name = ? LIMIT 1\n\nhas, err = testEngine.Where(\"name = ?\", \"test1\").Exist(\u0026RecordExist{})\n// SELECT * FROM record_exist WHERE name = ? LIMIT 1\n\nhas, err = testEngine.SQL(\"select * from record_exist where name = ?\", \"test1\").Exist()\n// select * from record_exist where name = ?\n\nhas, err = testEngine.Table(\"record_exist\").Exist()\n// SELECT * FROM record_exist LIMIT 1\n\nhas, err = testEngine.Table(\"record_exist\").Where(\"name = ?\", \"test1\").Exist()\n// SELECT * FROM record_exist WHERE name = ? LIMIT 1\n```\n\n* `Find` query multiple records from database, also you can use join and extends\n\n```Go\nvar users []User\nerr := engine.Where(\"name = ?\", name).And(\"age \u003e 10\").Limit(10, 0).Find(\u0026users)\n// SELECT * FROM user WHERE name = ? AND age \u003e 10 limit 10 offset 0\n\ntype Detail struct {\n    Id int64\n    UserId int64 `xorm:\"index\"`\n}\n\ntype UserDetail struct {\n    User `xorm:\"extends\"`\n    Detail `xorm:\"extends\"`\n}\n\nvar users []UserDetail\nerr := engine.Table(\"user\").Select(\"user.*, detail.*\").\n    Join(\"INNER\", \"detail\", \"detail.user_id = user.id\").\n    Where(\"user.name = ?\", name).Limit(10, 0).\n    Find(\u0026users)\n// SELECT user.*, detail.* FROM user INNER JOIN detail WHERE user.name = ? limit 10 offset 0\n```\n\n* `Iterate` and `Rows` query multiple records and record by record handle, there are two methods Iterate and Rows\n\n```Go\nerr := engine.Iterate(\u0026User{Name:name}, func(idx int, bean interface{}) error {\n    user := bean.(*User)\n    return nil\n})\n// SELECT * FROM user\n\nerr := engine.BufferSize(100).Iterate(\u0026User{Name:name}, func(idx int, bean interface{}) error {\n    user := bean.(*User)\n    return nil\n})\n// SELECT * FROM user Limit 0, 100\n// SELECT * FROM user Limit 101, 100\n\nrows, err := engine.Rows(\u0026User{Name:name})\n// SELECT * FROM user\ndefer rows.Close()\nbean := new(Struct)\nfor rows.Next() {\n    err = rows.Scan(bean)\n}\n```\n\n* `Update` update one or more records, default will update non-empty and non-zero fields except when you use Cols, AllCols and so on.\n\n```Go\naffected, err := engine.ID(1).Update(\u0026user)\n// UPDATE user SET ... Where id = ?\n\naffected, err := engine.Update(\u0026user, \u0026User{Name:name})\n// UPDATE user SET ... Where name = ?\n\nvar ids = []int64{1, 2, 3}\naffected, err := engine.In(\"id\", ids).Update(\u0026user)\n// UPDATE user SET ... Where id IN (?, ?, ?)\n\n// force update indicated columns by Cols\naffected, err := engine.ID(1).Cols(\"age\").Update(\u0026User{Name:name, Age: 12})\n// UPDATE user SET age = ?, updated=? Where id = ?\n\n// force NOT update indicated columns by Omit\naffected, err := engine.ID(1).Omit(\"name\").Update(\u0026User{Name:name, Age: 12})\n// UPDATE user SET age = ?, updated=? Where id = ?\n\naffected, err := engine.ID(1).AllCols().Update(\u0026user)\n// UPDATE user SET name=?,age=?,salt=?,passwd=?,updated=? Where id = ?\n```\n\n* `Delete` delete one or more records, Delete MUST have condition\n\n```Go\naffected, err := engine.Where(...).Delete(\u0026user)\n// DELETE FROM user Where ...\n\naffected, err := engine.ID(2).Delete(\u0026user)\n// DELETE FROM user Where id = ?\n```\n\n* `Count` count records\n\n```Go\ncounts, err := engine.Count(\u0026user)\n// SELECT count(*) AS total FROM user\n```\n\n* `FindAndCount` combines function `Find` with `Count` which is usually used in query by page\n\n```Go\nvar users []User\ncounts, err := engine.FindAndCount(\u0026users)\n```\n\n* `Sum` sum functions\n\n```Go\nagesFloat64, err := engine.Sum(\u0026user, \"age\")\n// SELECT sum(age) AS total FROM user\n\nagesInt64, err := engine.SumInt(\u0026user, \"age\")\n// SELECT sum(age) AS total FROM user\n\nsumFloat64Slice, err := engine.Sums(\u0026user, \"age\", \"score\")\n// SELECT sum(age), sum(score) FROM user\n\nsumInt64Slice, err := engine.SumsInt(\u0026user, \"age\", \"score\")\n// SELECT sum(age), sum(score) FROM user\n```\n\n* Query conditions builder\n\n```Go\nerr := engine.Where(builder.NotIn(\"a\", 1, 2).And(builder.In(\"b\", \"c\", \"d\", \"e\"))).Find(\u0026users)\n// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?)\n```\n\n* Multiple operations in one go routine, no transation here but resue session memory\n\n```Go\nsession := engine.NewSession()\ndefer session.Close()\n\nuser1 := Userinfo{Username: \"xiaoxiao\", Departname: \"dev\", Alias: \"lunny\", Created: time.Now()}\nif _, err := session.Insert(\u0026user1); err != nil {\n    return err\n}\n\nuser2 := Userinfo{Username: \"yyy\"}\nif _, err := session.Where(\"id = ?\", 2).Update(\u0026user2); err != nil {\n    return err\n}\n\nif _, err := session.Exec(\"delete from userinfo where username = ?\", user2.Username); err != nil {\n    return err\n}\n\nreturn nil\n```\n\n* Transation should on one go routine. There is transaction and resue session memory\n\n```Go\nsession := engine.NewSession()\ndefer session.Close()\n\n// add Begin() before any action\nif err := session.Begin(); err != nil {\n    // if returned then will rollback automatically\n    return err\n}\n\nuser1 := Userinfo{Username: \"xiaoxiao\", Departname: \"dev\", Alias: \"lunny\", Created: time.Now()}\nif _, err := session.Insert(\u0026user1); err != nil {\n    return err\n}\n\nuser2 := Userinfo{Username: \"yyy\"}\nif _, err := session.Where(\"id = ?\", 2).Update(\u0026user2); err != nil {\n    return err\n}\n\nif _, err := session.Exec(\"delete from userinfo where username = ?\", user2.Username); err != nil {\n    return err\n}\n\n// add Commit() after all actions\nreturn session.Commit()\n```\n\n* Or you can use `Transaction` to replace above codes.\n\n```Go\nres, err := engine.Transaction(func(session *xorm.Session) (interface{}, error) {\n    user1 := Userinfo{Username: \"xiaoxiao\", Departname: \"dev\", Alias: \"lunny\", Created: time.Now()}\n    if _, err := session.Insert(\u0026user1); err != nil {\n        return nil, err\n    }\n\n    user2 := Userinfo{Username: \"yyy\"}\n    if _, err := session.Where(\"id = ?\", 2).Update(\u0026user2); err != nil {\n        return nil, err\n    }\n\n    if _, err := session.Exec(\"delete from userinfo where username = ?\", user2.Username); err != nil {\n        return nil, err\n    }\n    return nil, nil\n})\n```\n\n* Context Cache, if enabled, current query result will be cached on session and be used by next same statement on the same session.\n\n```Go\n\tsess := engine.NewSession()\n\tdefer sess.Close()\n\n\tvar context = xorm.NewMemoryContextCache()\n\n\tvar c2 ContextGetStruct\n\thas, err := sess.ID(1).ContextCache(context).Get(\u0026c2)\n\tassert.NoError(t, err)\n\tassert.True(t, has)\n\tassert.EqualValues(t, 1, c2.Id)\n\tassert.EqualValues(t, \"1\", c2.Name)\n\tsql, args := sess.LastSQL()\n\tassert.True(t, len(sql) \u003e 0)\n\tassert.True(t, len(args) \u003e 0)\n\n\tvar c3 ContextGetStruct\n\thas, err = sess.ID(1).ContextCache(context).Get(\u0026c3)\n\tassert.NoError(t, err)\n\tassert.True(t, has)\n\tassert.EqualValues(t, 1, c3.Id)\n\tassert.EqualValues(t, \"1\", c3.Name)\n\tsql, args = sess.LastSQL()\n\tassert.True(t, len(sql) == 0)\n\tassert.True(t, len(args) == 0)\n```\n\n## Contributing\n\nIf you want to pull request, please see [CONTRIBUTING](https://github.com/go-xorm/xorm/blob/master/CONTRIBUTING.md). And we also provide [Xorm on Google Groups](https://groups.google.com/forum/#!forum/xorm) to discuss.\n\n## Credits\n\n### Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n\u003ca href=\"graphs/contributors\"\u003e\u003cimg src=\"https://opencollective.com/xorm/contributors.svg?width=890\u0026button=false\" /\u003e\u003c/a\u003e\n\n### Backers\n\nThank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/xorm#backer)]\n\n\u003ca href=\"https://opencollective.com/xorm#backers\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/xorm/backers.svg?width=890\"\u003e\u003c/a\u003e\n\n### Sponsors\n\nSupport this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/xorm#sponsor)]\n\n## Changelog\n\n* **v0.7.0**\n    * Some bugs fixed\n\n* **v0.6.6**\n    * Some bugs fixed\n\n* **v0.6.5**\n    * Postgres schema support\n    * vgo support\n    * Add FindAndCount\n    * Database special params support via NewEngineWithParams\n    * Some bugs fixed\n\n* **v0.6.4**\n    * Automatical Read/Write seperatelly\n    * Query/QueryString/QueryInterface and action with Where/And\n    * Get support non-struct variables\n    * BufferSize on Iterate\n    * fix some other bugs.\n\n[More changes ...](https://github.com/go-xorm/manual-en-US/tree/master/chapter-16)\n\n## Cases\n\n* [studygolang](http://studygolang.com/) - [github.com/studygolang/studygolang](https://github.com/studygolang/studygolang)\n\n* [Gitea](http://gitea.io) - [github.com/go-gitea/gitea](http://github.com/go-gitea/gitea)\n\n* [Gogs](http://try.gogits.org) - [github.com/gogits/gogs](http://github.com/gogits/gogs)\n\n* [grafana](https://grafana.com/) - [github.com/grafana/grafana](http://github.com/grafana/grafana)\n\n* [github.com/m3ng9i/qreader](https://github.com/m3ng9i/qreader)\n\n* [Wego](http://github.com/go-tango/wego)\n\n* [Docker.cn](https://docker.cn/)\n\n* [Xorm Adapter](https://github.com/casbin/xorm-adapter) for [Casbin](https://github.com/casbin/casbin) - [github.com/casbin/xorm-adapter](https://github.com/casbin/xorm-adapter)\n\n* [Gorevel](http://gorevel.cn/) - [github.com/goofcc/gorevel](http://github.com/goofcc/gorevel)\n\n* [Gowalker](http://gowalker.org) - [github.com/Unknwon/gowalker](http://github.com/Unknwon/gowalker)\n\n* [Gobuild.io](http://gobuild.io) - [github.com/shxsun/gobuild](http://github.com/shxsun/gobuild)\n\n* [Sudo China](http://sudochina.com) - [github.com/insionng/toropress](http://github.com/insionng/toropress)\n\n* [Godaily](http://godaily.org) - [github.com/govc/godaily](http://github.com/govc/godaily)\n\n* [YouGam](http://www.yougam.com/)\n\n* [GoCMS - github.com/zzboy/GoCMS](https://github.com/zzdboy/GoCMS)\n\n* [GoBBS - gobbs.domolo.com](http://gobbs.domolo.com/)\n\n* [go-blog](http://wangcheng.me) - [github.com/easykoo/go-blog](https://github.com/easykoo/go-blog)\n\n## LICENSE\n\nBSD License [http://creativecommons.org/licenses/BSD/](http://creativecommons.org/licenses/BSD/)\n","funding_links":["https://opencollective.com/xorm"],"categories":["ORM"],"sub_categories":["高级控制台界面","高級控制台界面"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FGo-xorm%2Fxorm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FGo-xorm%2Fxorm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FGo-xorm%2Fxorm/lists"}