Go和MongoDB:泛型DAO实现问题

时间:2017-04-03 18:31:48

标签: mongodb go dao mgo

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

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没有泛型,我们怎么能避免代码重复?

我试图传递result interface{} param而不是在方法中创建它,并调用这样的方法:

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

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

[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{}

  

不能在[thisDao.GenericDao.FindAll

的参数中使用[] * entity.User literal(type [] * entity.User)作为类型[] interface {}

任何想法如何在Go中实现通用DAO?

1 个答案:

答案 0 :(得分:1)

您应该能够将result 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) 同类型。

List<int>() numbers = new List<int>();
int num;
while(int.TryParse(Console.ReadLine(), out num))
{
    numbers.Add(num);
}