{"id":13600208,"url":"https://github.com/mylxsw/eloquent","last_synced_at":"2025-05-05T23:44:15.967Z","repository":{"id":69884855,"uuid":"192756998","full_name":"mylxsw/eloquent","owner":"mylxsw","description":"Eloquent is a ORM framework for golang","archived":false,"fork":false,"pushed_at":"2024-03-21T03:53:49.000Z","size":264,"stargazers_count":22,"open_issues_count":1,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-31T00:51:12.300Z","etag":null,"topics":["database","eloquent","golang","laravel","migrate","orm"],"latest_commit_sha":null,"homepage":"https://godoc.org/github.com/mylxsw/eloquent","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mylxsw.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-19T15:16:28.000Z","updated_at":"2025-03-17T06:58:48.000Z","dependencies_parsed_at":"2023-11-29T03:25:42.773Z","dependency_job_id":"557ff223-e692-486c-9bea-7cdcadf7e3a2","html_url":"https://github.com/mylxsw/eloquent","commit_stats":{"total_commits":51,"total_committers":2,"mean_commits":25.5,"dds":"0.43137254901960786","last_synced_commit":"078fd0565e534338ca67e1a8e4d6d0a6697da089"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mylxsw%2Feloquent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mylxsw%2Feloquent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mylxsw%2Feloquent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mylxsw%2Feloquent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mylxsw","download_url":"https://codeload.github.com/mylxsw/eloquent/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252596322,"owners_count":21773842,"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":["database","eloquent","golang","laravel","migrate","orm"],"created_at":"2024-08-01T18:00:32.101Z","updated_at":"2025-05-05T23:44:15.908Z","avatar_url":"https://github.com/mylxsw.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Eloquent ORM\n\nEloquent 是一款为 Golang 开发的基于代码生成的数据库 ORM 框架，它的设计灵感来源于著名的 PHP 开发框架 Laravel，支持 MySQL 等数据库。\n\n## 模型定义\n\nEloquent 使用 YAML 文件来定义模型结构，通过代码生成的方式来创建模型对象。下面是模型定义的基本格式：\n\n```yaml\npackage: models                   // 当前模型所在的包名\nimports:                          // 要 import 的包，当 models.definition.fields 中包含外部类型时，在这里引入外部的包，可选\n- github.com/mylxsw/eloquent\nmeta:\n  table_prefix: el_               // 表前缀，默认为空，可选\nmodels:                           // 模型定义部分\n- name: user                      // 模型名称，也是默认表名，模型对象会转换为首字母大写的驼峰命名格式\n  relations:                      // 模型关联定义，可选\n  - model: role\n    rel: n-1\n    foreign_key: role_id\n    owner_key: id\n    local_key: \"\"\n    table: \"\"\n    package: \"\"\n    method: \"\"\n  definition:                     // 模型基本信息\n    table_name: user              // 对应的数据库表名，不指定该选项则默认使用模型名\n    without_create_time: false    // 不添加 created_at 字段，默认会自动添加该字段，类型为 time.Time，插入数据时自动更新\n    without_update_time: false    // 不添加 updated_at 字段，默认会自动添加该字段，类型为 time.Time，更新数据时自动更新\n    soft_delete: false            // 是否启用软删除支持，启用软删除后，会自动添加 deleted_at 字段，类型为 time.Time\n    fields:                       // 表字段对应关系\n    - name: id                    // 主键 ID\n      type: int64                 // 主键 ID 类型\n      tag: json:\"id\"              // 主键 ID 类型的 Tags\n    - name: name                  // 其它字段名\n      type: string                // 其它字段类型\n      tag: json:\"name\"            // 其它字段的 Tags\n    - name: age\n      type: int64\n      tag: json:\"age\"\n```\n\n你可以使用命令行工具 `eloquent create-model` 来生成模型定义文件\n\n```bash\n$ eloquent create-model -h\nNAME:\n    create-model - 创建表模型定义文件\n\nUSAGE:\n    create-model [command options] [arguments...]\n\nOPTIONS:\n   --table value         表名\n   --package value       包名\n   --output value        输出目录\n   --table-prefix value  表前缀\n   --no-created_at       不自动添加 created_at 字段\n   --no-updated_at       不自动添加 updated_at 字段\n   --soft-delete         启用软删除支持\n   --import value        引入包\n```\n\n比如创建一个用户模型定义文件，表名为 `users`，包名为 `models`，启用软删除支持，输出到当前目录\n\n```bash\n$ eloquent create-model --table users --package models --soft-delete --output .\n$ ls -al\ntotal 8\n-rwxr-xr-x  1 mylxsw  wheel   162B  6 17 21:32 users.yml\n```\n\n模型定义创建之后，默认是只有主键 id 的，我们手动修改模型定义文件，添加几个额外的字段，\n\n```yaml\npackage: models\nmodels:\n- name: users\n  definition:\n    table_name: users\n    soft_delete: true\n    fields:\n    - name: id\n      type: int64\n      tag: json:\"id\"\n    - name: name \n      type: string\n    - name: age\n      type: int\n```\n\n使用 `eloquent gen` 命令来生成模型文件\n\n```bash\n$ eloquent gen -h\nNAME:\n    gen - 根据模型文件定义生成模型对象\n\nUSAGE:\n    gen [command options] [arguments...]\n\nOPTIONS:\n   --source value  模型定义所在文件的 Glob 表达式，比如 ./models/*.yml\n```\n\n比如上面我们创建的 `users.yml` 模型定义，执行下面的命令创建模型对象\n\n```bash\n$ eloquent gen --source './*.yml'\nusers.orm.go\n$ ls -al\ntotal 40\ndrwxr-xr-x   4 mylxsw  wheel    128  6 17 21:36 .\ndrwxrwxrwt  17 root    wheel    544  6 17 21:32 ..\n-rwxr-xr-x   1 mylxsw  wheel  15614  6 17 21:36 users.orm.go\n-rwxr-xr-x   1 mylxsw  wheel    162  6 17 21:32 users.yml\n```\n\n生成的模型对象会包含两个模型定义的结构体，一个是模型名称本身命名的结构体 Xxx，用于与数据库进行交互\n\n```go\ntype User struct {\n\tId            null.Int `json:\"id\"`\n\tName          null.String\n \tAge           null.Int\n\tCreatedAt     null.Time\n\tUpdatedAt     null.Time\n\tDeletedAt     null.Time\n}\n```\n\n\u003e 这里的结构体字段类型使用了 `gopkg.in/guregu/null.v3` 对基本类型的封装，解决 Golang 基本类型字段不支持 `null` 值的问题，但是这样也给使用者带来了不便，我们必须使用 `Name.ValueOrZero()` 这种方式来获取字段的基本类型值。\n\n另一个结构体是 XxxPlain，该结构体将 `null` 值转换为了字段的基本类型，当数据库中为 null 时，会返回字段的默认值。通过模型对象的 `ToXxxPlain()` 方法可以将模型对象转换为该结构体。\n\n```go\ntype UserPlain struct {\n\tId            int64\n\tName          string\n \tAge           int\n\tCreatedAt     time.Time\n\tUpdatedAt     time.Time\n\tDeletedAt     time.Time\n}\n```\n\n## 模型使用\n\n本文的讲解将基于前面创建的用户模型（`users.yml`），假定我们的模型目录为 `models`。在使用模型的 API 之前，需要先创建数据库连接对象，我们使用 Golang 标准库的 `database/sql` 包来创建\n\n```go\ndb, err := sql.Open(\"mysql\", connURI)\nif err != nil {\n  panic(err)\n}\n\ndefer db.Close()\n```\n\n### 创建模型实例\n\n创建模型定义文件和生成模型对象文件后，使用 `models.NewXxxModel(db query.Database)` 来创建一个模型对象。\n\n```go\n// 创建用户模型对象\nuserModel := models.NewUsersModel(db)\n```\n\n### 查询条件\n\n在 Eloquent 中，查询条件使用 `query.Builder()` 方法来构建，该方法会生成一个 `SQLBuilder` 对象，使用它我们可以使用链式语法来构建查询条件\n\n```go\nbuilder := query.Builder()\n```\n\n`SQLBuilder` 对象提供了一系列的方法来帮助我们构建灵活的查询条件\n\n- `WhereColumn(field, operator string, value string) Condition`\n- `OrWhereColumn(field, operator string, value string) Condition`\n- `OrWhereNotExist(subQuery SubQuery) Condition`\n- `OrWhereExist(subQuery SubQuery) Condition`\n- `WhereNotExist(subQuery SubQuery) Condition`\n- `WhereExist(subQuery SubQuery) Condition`\n- `OrWhereNotNull(field string) Condition`\n- `OrWhereNull(field string) Condition`\n- `WhereNotNull(field string) Condition`\n- `WhereNull(field string) Condition`\n- `OrWhereRaw(raw string, items ...interface{}) Condition`\n- `WhereRaw(raw string, items ...interface{}) Condition`\n- `OrWhereNotIn(field string, items ...interface{}) Condition`\n- `OrWhereIn(field string, items ...interface{}) Condition`\n- `WhereNotIn(field string, items ...interface{}) Condition`\n- `WhereIn(field string, items ...interface{}) Condition`\n- `WhereGroup(wc ConditionGroup) Condition`\n- `OrWhereGroup(wc ConditionGroup) Condition`\n- `Where(field string, value ...interface{}) Condition`\n- `OrWhere(field string, value ...interface{}) Condition`\n- `WhereBetween(field string, min, max interface{}) Condition`\n- `WhereNotBetween(field string, min, max interface{}) Condition`\n- `OrWhereBetween(field string, min, max interface{}) Condition`\n- `OrWhereNotBetween(field string, min, max interface{}) Condition`\n- `WhereCondition(cond sqlCondition) Condition`\n- `When(when When, cg ConditionGroup) Condition`\n- `OrWhen(when When, cg ConditionGroup) Condition`\n- `Get() []sqlCondition`\n- `Append(cond Condition) Condition`\n- `Resolve(tableAlias string) (string, []interface{})`\n\n比如我们要查询用户名模糊匹配 `Tom`，年龄大于 30 岁的用户\n\n```go\nquery.Builder().Where(model.UserFieldName, \"LIKE\", \"%Tom%\").Where(\"age\", \"\u003e\", 30)\n```\n\n### CRUD\n\n查询用户列表\n\n```go\nusers, err := model.NewUsersModel(s.db).Get()\nfor _, user := range users {\n  // user.Id.ValueOrZero() \n  // user.Name.ValueOrZero()\n\n  // user.ToUserPlain().Name\n}\n```\n\n查询第一个匹配的用户\n\n```go\nuser, err := model.NewUserModel(s.db).First(query.Builder().Where(model.UserFieldName, username))\n```\n\n创建一个用户\n\n```go\nuserID, err := model.NewUserModel(s.db).Save(model.User{\n  Account:  null.StringFrom(username),\n  Status:   null.IntFrom(int64(UserStatusEnabled)),\n  Password: null.StringFrom(password),\n})\n\n// 也可以这样\nuserID, err := model.NewUserModel(s.db).Create(query.KV{\n  model.UserFieldUuid:     userInfo.Uuid,\n  model.UserFieldName:     userInfo.Name,\n  model.UserFieldAccount:  username,\n  model.UserFieldStatus:   userInfo.Status,\n  model.UserFieldPassword: userInfo.Password,\n})\n\n// 还可以这样\nuser := models.UserPlain{\n  Name: \"Tom\",\n  Age: 32,\n}\n\nuserID, err := userModel.Save(user.ToUser())\n```\n\n## 数据库迁移\n\nEloquent 支持与 Laravel 框架类似的数据库迁移功能，使用语法也基本一致。\n\n```go\nm := migrate.NewManager(db).Init()\n\nm.Schema(\"202104222322\").Create(\"user\", func(builder *migrate.Builder) {\n  builder.Increments(\"id\")\n  builder.String(\"uuid\", 255).Comment(\"用户 uuid\")\n  builder.String(\"name\", 100).Comment(\"用户名\")\n  builder.Timestamps(0)\n})\nm.Schema(\"202106100943\").Table(\"user\", func(builder *migrate.Builder) {\n  builder.String(\"account\", 100).Comment(\"账号名\")\n  builder.TinyInteger(\"status\", false, true).Default(migrate.RawExpr(\"1\")).Comment(\"状态：0-禁用 1-启用\")\n})\nm.Schema(\"202106102309\").Table(\"user\", func(builder *migrate.Builder) {\n  builder.String(\"password\", 256).Nullable(true).Comment(\"密码\")\n})\n\nif err := m.Run(); err != nil {\n  panic(err)\n}\n```\n\n## 示例项目\n\n- [tech-share](https://github.com/mylxsw/tech-share) 这是一个简单的 web 项目，用于企业内部对技术分享的管理","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmylxsw%2Feloquent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmylxsw%2Feloquent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmylxsw%2Feloquent/lists"}