mongodb - Go 和 MongoDB : generic DAO implementation issue

标签 mongodb go dao mgo

在当前项目中,我们通过 mgo 驱动程序使用 Go 和 MongoDB。 对于每个实体,我们都必须实现 DAO 来进行 CRUD 操作,这基本上是复制粘贴,例如

func (thisDao ClusterDao) FindAll() ([]*entity.User, error) {
    session, collection := thisDao.getCollection()
    defer session.Close()
    result := []*entity.User{} //create a new empty slice to return 
    q := bson.M{}
    err := collection.Find(q).All(&result)
    return result, err
}

对于所有其他实体,除了结果类型之外,其他实体都相同。

既然Go没有泛型,我们如何避免代码重复?

我尝试传递结果接口(interface){}参数,而不是在方法中创建它,并像这样调用该方法:

dao.FindAll([]*entity.User{})

但是collection.Find().All()方法需要一个 slice 作为输入,而不仅仅是接口(interface):

[restful] recover from panic situation: - result argument must be a slice address
/usr/local/go/src/runtime/asm_amd64.s:514
/usr/local/go/src/runtime/panic.go:489
/home/dds/gopath/src/gopkg.in/mgo.v2/session.go:3791
/home/dds/gopath/src/gopkg.in/mgo.v2/session.go:3818

然后我尝试使这个参数result []interface{},但在这种情况下不可能传递[]*entity.User{}:

cannot use []*entity.User literal (type []*entity.User) as type []interface {} in argument to thisDao.GenericDao.FindAll

知道如何在 Go 中实现通用 DAO 吗?

最佳答案

您应该能够将结果接口(interface){}传递给您的FindAll函数,然后将其传递给mgo的Query.All方法,因为参数具有相同的类型。

func (thisDao ClusterDao) FindAll(result interface{}) error {
    session, collection := thisDao.getCollection()
    defer session.Close()
    q := bson.M{}
    // just pass result as is, don't do & here
    // because that would be a pointer to the interface not
    // to the underlying slice, which mgo probably doesn't like
    return collection.Find(q).All(result)
}

// ...

users := []*entity.User{}
if err := dao.FindAll(&users); err != nil { // pass pointer to slice here
    panic(err)
}
log.Println(users)

关于mongodb - Go 和 MongoDB : generic DAO implementation issue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43191883/

相关文章:

javascript - Node js Mongodb findOne 不同步工作

docker - 使用默认docker文件构建beego docker镜像时,报错: `godep: No Godeps found (or in any parent directory)`

reactjs - 如何从 LinkedIn oAuth2 读取 accessToken

go - Go 中联合的最佳实践

android - DAO 查询不适用于 MIN MAX 函数

java - 我应该为 DAO 测试类使用@Transactional 还是@Rollback?

java - DAO Hibernate Java Select All rows into a collection

javascript - 从 mongodb Node js 搜索记录时出现问题?

node.js - 为 MEAN 应用程序生成 Mongoose DTO

python - 无法使用 pymongo 客户端在 Docker 中连接 MongoDB 和 Flask