在 go 语言的 mvc 实践中,sql 操作不应直接嵌入模型结构体方法中;正确的做法是将数据访问逻辑分离至独立的数据访问层(如 dao),由控制器协调业务流程,模型仅负责数据结构与领域语义。
在 MVC(Model-View-Controller)架构中,清晰的职责划分是可维护性和可测试性的基石。以用户注册场景为例,若将 SQL 代码直接写在 Form 结构体的方法中(如 func (f *Form) registerUser()),会导致多重问题:模型承担了数据持久化职责,违反单一职责原则;SQL 与业务逻辑紧耦合,难以单元测试;数据库驱动变更时需修改模型代码,破坏封装性。
✅ 正确分层实践如下:
-
Model(模型):仅定义领域实体与核心业务规则。例如:
// model/user.go type User struct { ID uint `gorm:"primaryKey"` Username string `gorm:"uniqueIndex;not null"` Password string `gorm:"not null"` } // 可附加领域校验方法(不涉及数据库) func (u *User) Validate() error { if u.Username == "" || len(u.Username) < 3 { return errors.New("username must be at least 3 characters") } return nil } -
DAO(Data Access Object)或 Repository(数据访问层):SQL 代码的唯一合法归属地。它封装所有数据库操作,屏蔽底层细节(如 SQL、ORM 调用)。推荐独立包管理,例如 pkg/repository: