
在 go 无泛型时代,通过接口参数 + 指针传递可安全复用 mongodb crud 逻辑,避免为每个实体重复编写 findall 等方法;关键在于向 mgo.all() 传入指向具体切片的指针,而非 interface{} 值或 []interface{}。
在 go 无泛型时代,通过接口参数 + 指针传递可安全复用 mongodb crud 逻辑,避免为每个实体重复编写 findall 等方法;关键在于向 mgo.all() 传入指向具体切片的指针,而非 interface{} 值或 []interface{}。
要实现真正可复用的泛型 DAO,核心在于理解 mgo 的 Query.All() 方法对参数类型的严格要求:它必须接收一个指向具体切片类型的指针(如 *[]*User),而非 interface{} 值本身,更不能是 []interface{}。常见误区是误传 interface{} 变量(导致 panic:“result argument must be a slice address”),或试图用 []interface{} 作中间类型(因 Go 类型系统不支持隐式切片转换而编译失败)。
✅ 正确做法是:将 FindAll 方法设计为接收 interface{} 类型参数,并在调用方显式传入 切片变量的地址。DAO 内部直接将该 interface{} 转发给 collection.Find().All() —— 因为 interface{} 可承载任意指针类型,且 All() 在运行时能正确解包并写入底层内存。
以下是推荐的泛型 DAO 实现:
// GenericDao 是通用 DAO 基础结构(可嵌入具体 DAO)
type GenericDao struct {
sessionFunc func() (*mgo.Session, *mgo.Collection)
}
// FindAll 查询全部文档,result 必须为指向切片的指针,例如 &[]*User{}
func (g GenericDao) FindAll(result interface{}) error {
session, collection := g.sessionFunc()
defer session.Close()
err := collection.Find(bson.M{}).All(result)
if err != nil {
return fmt.Errorf("failed to find all: %w", err)
}
return nil
}
// 使用示例
func main() {
// 初始化 DAO(假设已封装好 session/collection 获取逻辑)
dao := GenericDao{
sessionFunc: func() (*mgo.Session, *mgo.Collection) {
// 返回有效的 session 和对应 collection
session := getSession() // 你的会话获取逻辑
return session, session.DB("mydb").C("users")
},
}
// ✅ 正确:声明具体切片变量,传其地址
var users []*entity.User
if err := dao.FindAll(&users); err != nil {
log.Fatal(err)
}
log.Printf("Found %d users", len(users))
// ✅ 同样适用于其他实体
var clusters []*entity.Cluster
if err := dao.FindAll(&clusters); err != nil {
log.Fatal(err)
}
}⚠️ 注意事项:
-
永远不要对
interface{}参数取地址(如&result),这会产生*interface{},而非目标切片的指针; - 切片变量必须预先声明(如
var users []*User),不可直接传&[]*User{}字面量(会导致编译错误:cannot take the address of …); - 若需支持带条件查询,可扩展为
FindAll(query bson.M, result interface{}) error; -
mgo已归档(v2 为最后版本),生产环境建议迁移至官方mongo-go-driver,其Cursor.All()同样接受interface{},用法一致,且支持 context 控制。
总结:Go 的“伪泛型” DAO 不依赖语言特性,而依赖对指针语义和接口承载能力的精准把握。一次正确封装,即可让 User、Product、Order 等任意实体共享同一套数据访问逻辑,大幅提升代码可维护性与一致性。

















