2017-04-03 159 views
1

在当前项目中,我们通过mgo驱动程序使用Go和MongoDB。 对于每个实体,我们都必须实施用于CRUD操作的DAO,并且它基本上是复制粘贴的,例如,Go和MongoDB:通用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 

然后我试图使这个PARAM result []interface{},但在这种情况下,它不可能通过[]*entity.User{}

不能使用[] * entity.User文字(输入[* entity.User)类型[]接口{}在争论thisDao.GenericDao.FindAll

任何想法,我怎么可能实现通用DAO在Go?

回答

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) 
+0

不,它不起作用。结果:'[restful]从恐慌情况中恢复: - 结果参数必须是分片地址 /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' – dds

+0

看,在你的示例代码中,你没有传递一个指向片的指针'dao.FindAll( [] * entity.User {})'< - 这就是为什么你得到这个错误,这不是一个指向切片的指针,它是对用户结构的一个指向,好吗?在我的示例中,我添加了一些注释,指出了这一点......只是在我的示例中测试了代码,它可以工作。如果您确定要传递指向片的指针,请分享更多代码,以便我可以提供帮助。 – mkopriva

+0

@dds这是它的一个例子http://imgur.com/dbKWJZB – mkopriva