Go の強力な ORM「ent」を徹底解説!【入門から実践まで】
1. ent
とは?
ent
は Facebook(Meta)によって開発された Go のエンティティ駆動 ORM(Object-Relational Mapper) です。
GORM などの ORM と比べて 静的型安全 や コード生成 を重視しており、高速かつ堅牢なデータモデルを構築できます。
特徴
✅ 型安全性: Go の型システムを活用し、SQL クエリのエラーをコンパイル時に検出
✅ コード生成: スキーマ定義から自動生成されるため、開発効率が向上
✅ リレーション対応: 1対多、多対多などのリレーションをシンプルに扱える
✅ 高パフォーマンス: GORM よりも高速なクエリを生成
✅ GraphQL / REST API との統合: 簡単にエンティティを API にマッピング可能
2. ent
のインストール
まずは ent
をプロジェクトに導入しましょう。
go get entgo.io/ent/cmd/ent
go install entgo.io/ent/cmd/ent
その後、スキーマを格納する ent/schema
ディレクトリを作成します。
mkdir -p ent/schema
3. スキーマの定義
ent
は スキーマ(schema) を Go の構造体として定義し、そこから ORM のコードを生成します。
例として、ユーザー(User)モデル を作成します。
ent new User
すると、ent/schema/User.go
が生成されます。
このファイルを編集して、データベースのカラムを定義します。
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
)
// User スキーマの定義
type User struct {
ent.Schema
}
// Fields は User テーブルのカラムを定義
func (User) Fields() []ent.Field {
return []ent.Field{
field.Int("id"),
field.String("name").NotEmpty(),
field.String("email").Unique(),
field.Int("age").Positive(),
}
}
4. コードの生成
スキーマ定義後、ent
のコードを生成します。
go run entgo.io/ent/cmd/ent generate ./ent/schema
これにより、以下のようなファイルが自動生成されます。
ent/
├── client.go
├── user/
│ ├── user.go
│ ├── user_create.go
│ ├── user_query.go
│ ├── user_update.go
│ ├── user_delete.go
│ └── user_hooks.go
└── runtime.go
この ent.Client
を使って、DB 操作ができるようになります。
5. データベースのセットアップ
ent
は PostgreSQL、MySQL、SQLite など複数のデータベースをサポートしています。
まず、go-sqlite3
などのドライバをインストールしましょう。(今回は SQLite を使用)
go get github.com/mattn/go-sqlite3
次に、DB に接続するための main.go
を作成します。
package main
import (
"context"
"log"
"example.com/ent_sample/ent"
_ "github.com/mattn/go-sqlite3"
)
func main() {
// SQLite に接続
client, err := ent.Open("sqlite3", "file:ent.db?mode=memory&cache=shared&_fk=1")
if err != nil {
log.Fatalf("failed to connect to database: %v", err)
}
defer client.Close()
// DB のマイグレーション
ctx := context.Background()
if err := client.Schema.Create(ctx); err != nil {
log.Fatalf("failed to create schema: %v", err)
}
log.Println("Database schema created successfully!")
}
これで go run main.go
を実行すると、スキーマが DB に作成されます。
6. CRUD 操作(作成・取得・更新・削除)
6.1 データの作成
user, err := client.User.Create().
SetName("Taro").
SetEmail("taro@example.com").
SetAge(25).
Save(ctx)
if err != nil {
log.Fatalf("failed to create user: %v", err)
}
log.Println("User created:", user)
6.2 データの取得
user, err := client.User.Query().
Where(user.Email("taro@example.com")).
Only(ctx)
if err != nil {
log.Fatalf("failed to fetch user: %v", err)
}
log.Println("User found:", user)
6.3 データの更新
updatedUser, err := client.User.UpdateOneID(user.ID).
SetAge(30).
Save(ctx)
if err != nil {
log.Fatalf("failed to update user: %v", err)
}
log.Println("User updated:", updatedUser)
6.4 データの削除
err := client.User.DeleteOneID(user.ID).Exec(ctx)
if err != nil {
log.Fatalf("failed to delete user: %v", err)
}
log.Println("User deleted successfully!")
7. リレーション(1対多、多対多)
ent
では、テーブルのリレーション も簡単に定義できます。
たとえば、User
と Post
(投稿)の 1対多 関係を作成するとします。
ent new Post
次に、Post
スキーマを編集します。
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/edge"
"entgo.io/ent/schema/field"
)
// Post スキーマ
type Post struct {
ent.Schema
}
func (Post) Fields() []ent.Field {
return []ent.Field{
field.String("title"),
field.String("content"),
}
}
// ユーザーとの関係を定義(1対多)
func (Post) Edges() []ent.Edge {
return []ent.Edge{
edge.From("author", User.Type).
Ref("posts").
Unique(),
}
}
このように edge.From()
を使ってリレーションを定義 できます。
まとめ
ent
を使うと、型安全な ORM を簡単に実装できます。
特に コード生成の仕組み により、エンティティの管理がしやすく、GORM よりも高パフォーマンスな設計が可能です。
学んだポイント
✅ ent
は Go 向けの強力な ORM
✅ ent new User
でスキーマを作成
✅ ent generate
でコードを自動生成
✅ ent.Client
で CRUD 操作が可能
✅ 1対多、多対多のリレーションも簡単に定義
Golang での ORM に悩んでいる方は、ぜひ ent
を試してみてください!