{"id":36738902,"url":"https://github.com/wenj91/gobatis","last_synced_at":"2026-01-12T12:27:06.590Z","repository":{"id":30194140,"uuid":"123930860","full_name":"wenj91/gobatis","owner":"wenj91","description":"golang mybatis, 简单便捷","archived":false,"fork":false,"pushed_at":"2022-06-15T01:24:18.000Z","size":360,"stargazers_count":57,"open_issues_count":0,"forks_count":14,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-06-19T01:53:54.910Z","etag":null,"topics":["database","go","gobatis","golang","mapper","mysql","orm","sql"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wenj91.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-05T14:24:22.000Z","updated_at":"2023-08-29T06:47:23.000Z","dependencies_parsed_at":"2022-07-24T19:02:15.542Z","dependency_job_id":null,"html_url":"https://github.com/wenj91/gobatis","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/wenj91/gobatis","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wenj91%2Fgobatis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wenj91%2Fgobatis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wenj91%2Fgobatis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wenj91%2Fgobatis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wenj91","download_url":"https://codeload.github.com/wenj91/gobatis/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wenj91%2Fgobatis/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28338976,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T12:22:26.515Z","status":"ssl_error","status_checked_at":"2026-01-12T12:22:10.856Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["database","go","gobatis","golang","mapper","mysql","orm","sql"],"created_at":"2026-01-12T12:27:03.774Z","updated_at":"2026-01-12T12:27:06.585Z","avatar_url":"https://github.com/wenj91.png","language":"Go","readme":"# gobatis\n\n[![CodeQL](https://github.com/wenj91/gobatis/actions/workflows/codeql.yml/badge.svg?branch=master)](https://github.com/wenj91/gobatis/actions/workflows/codeql.yml)\n\n目前代码都是基于类mysql数据库编写测试的,其他数据库暂时还未做兼容处理\n\n- [x] 支持数据库\n  - [x] mysql\n  - [x] tidb\n  - [x] mariadb\n  - [ ] postgres\n  - [ ] sqlite\n- [x] 基础操作\n  - [x] query\n  - [x] insert\n  - [x] update\n  - [x] delete\n\n## ToDo\n\n- 增加更多易用表达式指令，目前已有`$blank`指令用于判别字符串是否为空的指令，比如判断name为空串： test=\"$blank(name)\"\n\n## 模板代码生成\n\n提供了简单的增删改查代码自动生成\n\n具体操作看仓库： [https://github.com/wenj91/mctl.git](https://github.com/wenj91/mctl.git)\n\n## gobatis接口\n\n```go\ntype GoBatis interface {\n\t// Select 查询数据\n\tSelect(stmt string, param interface{}, rowBound ...*rowBounds) func(res interface{}) (int64, error)\n\t// SelectContext 查询数据with context\n\tSelectContext(ctx context.Context, stmt string, param interface{}, rowBound ...*rowBounds) func(res interface{}) (int64, error)\n\t// Insert 插入数据\n\tInsert(stmt string, param interface{}) (lastInsertId int64, affected int64, err error)\n\t// InsertContext 插入数据with context\n\tInsertContext(ctx context.Context, stmt string, param interface{}) (lastInsertId int64, affected int64, err error)\n\t// Update 更新数据\n\tUpdate(stmt string, param interface{}) (affected int64, err error)\n\t// UpdateContext 更新数据with context\n\tUpdateContext(ctx context.Context, stmt string, param interface{}) (affected int64, err error)\n\t// Delete 刪除数据\n\tDelete(stmt string, param interface{}) (affected int64, err error)\n\t// DeleteContext 刪除数据with context\n\tDeleteContext(ctx context.Context, stmt string, param interface{}) (affected int64, err error)\n}\n```\n\n## db数据源配置\n- 支持多数据源配置\n- db子级配置为一个map，map的key即为数据源名称标识  \n- map的value为数据源具体配置，具体配置项如下表\n\n| 配置 | 是否必填配置 | 默认值 | 说明 |\n|:---|:----:|:----:|----|\n| driverName | 是 | | 数据源驱动名，必填配置项\n| dataSourceName | 是 | | 数据源名称，必填配置项，例如: root:123456@tcp(127.0.0.1:3306)/test?charset=utf8\n| maxLifeTime | 否 | 120(单位: s)| 连接最大存活时间，默认值为: 120 单位为: s\n| maxOpenConns | 否 | 10 | 最大打开连接数，默认值为: 10\n| maxIdleConns | 否 | 5 | 最大挂起连接数，默认值为: 5\n\n### 示例\n* db配置示例(配置较之前的有所调整)  \n以下为多数据源配置示例: db.yml\n```yaml\n# 数据库配置\ndb:\n  # 数据源名称1\n  - datasource: ds1\n    # 驱动名\n    driverName: mysql\n    # 数据源\n    dataSourceName: root:123456@tcp(127.0.0.1:3306)/test?charset=utf8\n    # 连接最大存活时间（单位: s）\n    maxLifeTime: 120\n    # 最大open连接数\n    maxOpenConns: 10\n    # 最大挂起连接数\n    maxIdleConns: 5\n  # 数据源名称2\n  - datasource: ds2\n    # 驱动名\n    driverName: mysql\n    # 数据源\n    dataSourceName: root:123456@tcp(127.0.0.1:3306)/test?charset=utf8\n    # 连接最大存活时间（单位: s）\n    maxLifeTime: 120\n    # 最大open连接数\n    maxOpenConns: 10\n    # 最大挂起连接数\n    maxIdleConns: 5\n# 是否显示SQL语句\nshowSql: true\n# 数据表映射文件路径配置\nmappers:\n  # 映射文件路径， 可以为绝对路径，如: /usr/local/mapper/userMapper.xml\n  - mapper/userMapper.xml\n```\n\n* mapper配置  \n1. mapper可以配置namespace属性  \n1. mapper可以包含: select, insert, update, delete标签  \n1. mapper子标签id属性则为标签唯一标识, 必须配置属性\n1. 其中select标签必须包含resultType属性，resultType可以是: map, maps, array, arrays, struct, structs, value\n  \n* 标签说明  \nselect: 用于查询操作   \ninsert: 用于插入sql操作  \nupdate: 用于更新sql操作  \ndelete: 用于删除sql操作\n\n* resultType说明  \nmap: 则数据库查询结果为map  \nmaps: 则数据库查询结果为map数组  \narray: 则数据库查询结果为值数组  \narrays: 则数据库查询结果为多个值数组  \nstruct: 则数据库查询结果为单个结构体  \nstructs: 则数据库查询结果为结构体数组  \nvalue: 则数据库查询结果为单个数值  \n \n以下是mapper配置示例: mapper/userMapper.xml\n```xml\n\u003c?xml version=\"1.0\" encoding=\"utf-8\"?\u003e\n\u003c!DOCTYPE mapper PUBLIC \"gobatis\"\n        \"https://raw.githubusercontent.com/wenj91/gobatis/master/gobatis.dtd\"\u003e\n\u003cmapper namespace=\"userMapper\"\u003e\n    \u003csql id=\"Base_Column_List\"\u003e\n        id, name, crtTm, pwd, email\n    \u003c/sql\u003e\n    \u003cselect id=\"findIncludeMaps\" resultType=\"maps\"\u003e\n        SELECT\n        \t\u003cinclude refid=\"Base_Column_List\" /\u003e\n        FROM user\n        limit 10\n    \u003c/select\u003e\n    \u003cselect id=\"findMapById\" resultType=\"map\"\u003e\n        SELECT id, name FROM user where id=#{id} order by id\n    \u003c/select\u003e\n    \u003cselect id=\"findMapByValue\" resultType=\"map\"\u003e\n            SELECT id, name FROM user where id=#{0} order by id\n    \u003c/select\u003e\n    \u003cselect id=\"findStructByStruct\" resultType=\"struct\"\u003e\n        SELECT id, name, crtTm FROM user where id=#{Id} order by id\n    \u003c/select\u003e\n    \u003cselect id=\"queryStructs\" resultType=\"structs\"\u003e\n        SELECT id, name, crtTm FROM user order by id\n    \u003c/select\u003e\n    \u003cselect id=\"queryStructsByOrder\" resultType=\"structs\"\u003e\n        SELECT id, name, crtTm FROM user order by ${id} desc\n    \u003c/select\u003e\n    \u003cinsert id=\"insertStruct\"\u003e\n        insert into user (name, email, crtTm)\n        values (#{Name}, #{Email}, #{CrtTm})\n    \u003c/insert\u003e\n    \u003cdelete id=\"deleteById\"\u003e\n        delete from user where id=#{id}\n    \u003c/delete\u003e\n    \u003cselect id=\"queryStructsByCond\" resultType=\"structs\"\u003e\n         SELECT id, name, crtTm, pwd, email FROM user\n         \u003cwhere\u003e\n             \u003cif test=\"!$blank(Name)\"\u003eand name = #{Name}\u003c/if\u003e\n         \u003c/where\u003e\n         order by id\n    \u003c/select\u003e\n     \u003cselect id=\"queryStructsByCond2\" resultType=\"structs\"\u003e\n         SELECT id, name, crtTm, pwd, email FROM user\n         \u003ctrim prefixOverrides=\"and\" prefix=\"where\" suffixOverrides=\",\" suffix=\"and 1=1\"\u003e\n              \u003cif test=\"!$blank(Name)\"\u003eand name = #{Name}\u003c/if\u003e\n         \u003c/trim\u003e\n         order by id\n    \u003c/select\u003e\n    \u003cupdate id=\"updateByCond\"\u003e\n        update user\n        \u003cset\u003e\n            \u003cif test=\"!$blank(Name) and !$blank(Name2)\"\u003ename = #{Name},\u003c/if\u003e\n        \u003c/set\u003e\n        where id = #{Id}\n    \u003c/update\u003e\n\u003c/mapper\u003e\n```\n\n## 使用方法\n\n###  使用配置文件配置\nexample1.go\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t_ \"github.com/go-sql-driver/mysql\" // 引入驱动\n\t\"github.com/wenj91/gobatis\"        // 引入gobatis\n)\n\n// 实体结构示例， tag：field为数据库对应字段名称\ntype User struct {\n\tId    gobatis.NullInt64  `field:\"id\"`\n\tName  gobatis.NullString `field:\"name\"`\n\tEmail gobatis.NullString `field:\"email\"`\n\tCrtTm gobatis.NullTime   `field:\"crtTm\"`\n}\n\n\n// User to string\nfunc (u *User) String() string {\n\tbs, _ := json.Marshal(u)\n\treturn string(bs)\n}\n\nfunc main() {\n\t// 初始化db，参数为db.yml路径，如：db.yml\t\n\tgobatis.Init(gobatis.NewFileOption(\"db.yml\"))\n\n\t// 获取数据源，参数为数据源名称，如：datasource1\n\tgb := gobatis.Get(\"ds1\")\n\n\t//传入id查询Map\n\tmapRes := make(map[string]interface{})\n\t// stmt标识为：namespace + '.' + id, 如：userMapper.findMapById\n\t// 查询参数可以是map，也可以是数组，也可以是实体结构\n\t_, err := gb.Select(\"userMapper.findMapById\", map[string]interface{}{\"id\": 1})(mapRes)\n\tfmt.Println(\"userMapper.findMapById--\u003e\", mapRes, err)\n\n\t// 根据传入实体查询对象\n\tparam := User{Id: gobatis.NullInt64{Int64: 1, Valid: true}}\n\tvar structRes *User\n\t_, err = gb.Select(\"userMapper.findStructByStruct\", param)(\u0026structRes)\n\tfmt.Println(\"userMapper.findStructByStruct--\u003e\", structRes, err)\n\n\t// 查询实体列表\n\tstructsRes := make([]*User, 0)\n\t_, err = gb.Select(\"userMapper.queryStructs\", map[string]interface{}{})(\u0026structsRes)\n\tfmt.Println(\"userMapper.queryStructs--\u003e\", structsRes, err)\n\n\tparam = User{\n\t\tId:   gobatis.NullInt64{Int64: 1, Valid: true},\n\t\tName: gobatis.NullString{String: \"wenj1993\", Valid: true},\n\t}\n\n\t// set tag\n\taffected, err := gb.Update(\"userMapper.updateByCond\", param)\n\tfmt.Println(\"updateByCond:\", affected, err)\n\n\tparam = User{Name: gobatis.NullString{String: \"wenj1993\", Valid: true}}\n\t// where tag\n\tres := make([]*User, 0)\n\t_, err = gb.Select(\"userMapper.queryStructsByCond\", param)(\u0026res)\n\tfmt.Println(\"queryStructsByCond\", res, err)\n\n\t// trim tag\n\tres = make([]*User, 0)\n\t_, err = gb.Select(\"userMapper.queryStructsByCond2\", param)(\u0026res)\n\tfmt.Println(\"queryStructsByCond2\", res, err)\n\n\t// include tag\n\tms := make([]map[string]interface{}, 0)\n\t_, err = gb.Select(\"userMapper.findIncludeMaps\", nil)(\u0026ms)\n\tfmt.Println(\"userMapper.findIncludeMaps--\u003e\", ms, err)\n\t\n\t// ${id}\n\tres = make([]*User, 0)\n\t_, err = gb.Select(\"userMapper.queryStructsByOrder\", map[string]interface{}{\n\t\t\"id\":\"id\",\n\t})(\u0026res)\n\tfmt.Println(\"queryStructsByCond\", res, err)\n\n\t// ${id} with count, 传入RowBounds(0, 100)即可返回count总数\n\tres = make([]*User, 0)\n\tcnt, err = gb.Select(\"userMapper.queryStructsByOrder\", map[string]interface{}{\n\t\t\"id\":\"id\",\n\t}, RowBounds(0, 100))(\u0026res)\n\tfmt.Println(\"queryStructsByCond\", cnt, res, err)\n\n\n\t// 开启事务示例\n\ttx, _ := gb.Begin()\n\tdefer tx.Rollback()\n\t_, tx.Select(\"userMapper.findMapById\", map[string]interface{}{\"id\": 1,})(mapRes)\n\tfmt.Println(\"tx userMapper.findMapById--\u003e\", mapRes, err)\n\ttx.Commit()\n}\n```\n\n### 代码配置方式\n\nexample2.go\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t_ \"github.com/go-sql-driver/mysql\" // 引入驱动\n\t\"github.com/wenj91/gobatis\"        // 引入gobatis\n)\n\n// 实体结构示例， tag：field为数据库对应字段名称\ntype User struct {\n\tId    gobatis.NullInt64  `field:\"id\"`\n\tName  gobatis.NullString `field:\"name\"`\n\tEmail gobatis.NullString `field:\"email\"`\n\tCrtTm gobatis.NullTime   `field:\"crtTm\"`\n}\n\nfunc main() {\n\t// 初始化db\n\tds1 := gobatis.NewDataSourceBuilder().\n\t\tDataSource(\"ds1\").\n\t\tDriverName(\"mysql\").\n\t\tDataSourceName(\"root:123456@tcp(127.0.0.1:3306)/test?charset=utf8\").\n\t\tMaxLifeTime(120).\n\t\tMaxOpenConns(10).\n\t\tMaxIdleConns(5).\n\t\tBuild()\n\n\toption := gobatis.NewDSOption().\n\t\tDS([]*gobatis.DataSource{ds1}).\n\t\tMappers([]string{\"examples/mapper/userMapper.xml\"}).\n\t\tShowSQL(true)\n\n\tgobatis.Init(option)\n\n\t// 获取数据源，参数为数据源名称，如：ds1\n\tgb := gobatis.Get(\"ds1\")\n\n\t//传入id查询Map\n\tmapRes := make(map[string]interface{})\n\t// stmt标识为：namespace + '.' + id, 如：userMapper.findMapById\n\t// 查询参数可以是map，也可以是数组，也可以是实体结构\n\t_, err := gb.Select(\"userMapper.findMapById\", map[string]interface{}{\"id\": 1})(mapRes)\n\tfmt.Println(\"userMapper.findMapById--\u003e\", mapRes, err)\n}\n```\n\nexample3.go\n\n```go\npackage main\n\nimport (\n\t\"database/sql\"\n\t\"fmt\"\n\t_ \"github.com/go-sql-driver/mysql\" // 引入驱动\n\t\"github.com/wenj91/gobatis\"        // 引入gobatis\n)\n\n// 实体结构示例， tag：field为数据库对应字段名称\ntype User struct {\n\tId    gobatis.NullInt64  `field:\"id\"`\n\tName  gobatis.NullString `field:\"name\"`\n\tEmail gobatis.NullString `field:\"email\"`\n\tCrtTm gobatis.NullTime   `field:\"crtTm\"`\n}\n\nfunc main() {\n\t// 初始化db\n\tdb, _ := sql.Open(\"mysql\", \"root:123456@tcp(127.0.0.1:3306)/test?charset=utf8\")\n\tdbs := make(map[string]*gobatis.GoBatisDB)\n\tdbs[\"ds1\"] = gobatis.NewGoBatisDB(gobatis.DBTypeMySQL, db)\n\n\toption := gobatis.NewDBOption().\n\t\tDB(dbs).\n\t\tShowSQL(true).\n\t\tMappers([]string{\"examples/mapper/userMapper.xml\"})\n\n\tgobatis.Init(option)\n\n\t// 获取数据源，参数为数据源名称，如：ds1\n\tgb := gobatis.Get(\"ds1\")\n\n\t//传入id查询Map\n\tmapRes := make(map[string]interface{})\n\t// stmt标识为：namespace + '.' + id, 如：userMapper.findMapById\n\t// 查询参数可以是map，也可以是数组，也可以是实体结构\n\t_, err := gb.Select(\"userMapper.findMapById\", map[string]interface{}{\"id\": 1})(mapRes)\n\tfmt.Println(\"userMapper.findMapById--\u003e\", mapRes, err)\n}\n```\n\n## 致谢\n\n感谢jetbrains提供的goland！\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwenj91%2Fgobatis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwenj91%2Fgobatis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwenj91%2Fgobatis/lists"}