entを試してみた その2(関連テーブル追加とJOIN)
前回のブログでentの基本的なCRUDの使い方がなんとなくわかったので今回は関連テーブルがある場合についてを検証したブログとなる。
前回 https://miyazi888.hatenablog.com/entry/2023/05/05/114518
関連テーブルを追加
ent new Comment
スキーマ変更
この段階で指定するEdgesというのがどうやらテーブルのリレーションを定義する部分っぽい。
ent/shcema/comment.go
package schema import ( "entgo.io/ent" "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" ) // Comment holds the schema definition for the Comment entity. type Comment struct { ent.Schema } // Fields of the Comment. func (Comment) Fields() []ent.Field { return []ent.Field{ field.Int("user_id"), field.String("comment").Default("unknown"), } } // Edges of the Comment. func (Comment) Edges() []ent.Edge { return []ent.Edge{ edge.From("user", User.Type). Ref("comments"). Unique(). Required(). Field("user_id"), } }
ent/schema/user.go
package schema import ( "entgo.io/ent" "entgo.io/ent/dialect/entsql" "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" ) // User holds the schema definition for the User entity. type User struct { ent.Schema } // Fields of the User. func (User) Fields() []ent.Field { return []ent.Field{ field.String("name").Default("unknown"), field.Int("age").Positive(), field.String("nickname").Default("unknown"), } } // Edges of the User. func (User) Edges() []ent.Edge { return []ent.Edge{ edge.To("comments", Comment.Type). Annotations(entsql.Annotation{ OnDelete: entsql.Cascade, }), } }
上記スキーマを元にentityを生成
go generate ./ent
DBに反映する為にmigrate
go run migrate/migrate.go
動作検証
main.go
func cleanUp() { client := db.NewDBClient() ctx := context.Background() _, err := client.Debug().User.Delete().Exec(ctx) if err != nil { fmt.Printf("failed deleting user: %v", err) return } db.CloseDB(client) } func addUserAndComment() { client := db.NewDBClient() ctx := context.Background() // 1件追加 usr, err := client.Debug().User. Create(). SetName("user2"). SetAge(30). Save(ctx) if err != nil { fmt.Printf("failed creating user: %v", err) return } // コメント1件追加 _, err = client.Debug().Comment. Create(). SetUserID(usr.ID). SetComment("comment1"). Save(ctx) if err != nil { fmt.Printf("failed creating comment: %v", err) return } // コメント1件追加 _, err = client.Debug().Comment. Create(). SetUserID(usr.ID). SetComment("comment2"). Save(ctx) if err != nil { fmt.Printf("failed creating comment: %v", err) return } // user2のコメントを全件取得 comments, err := usr.QueryComments().All(ctx) if err != nil { fmt.Printf("failed getting comments: %v", err) return } for _, comment := range comments { fmt.Println(comment.Comment) // comment1, comment2 } // 'comment2'を持つユーザー一覧を取得 usrs, err := client.Debug().User.Query().Where(func(s *sql.Selector) { t := sql.Table(comment.Table) s.Join(t).On(s.C(user.FieldID), t.C(comment.FieldUserID)) s.Where(sql.EQ(t.C(comment.FieldComment), "comment2")) }).All(ctx) if err != nil { fmt.Printf("failed getting users: %v", err) return } for _, usr := range usrs { fmt.Println(usr.Name) // user2 } db.CloseDB(client) } func main() { cleanUp() // crud() addUserAndComment() }
これを実行するとusersテーブルにuser2が追加され、commentsテーブルにコメントが2件追加される。
go run main.go