Gorm:是否可以为公共db操作定义共享方法(例如通过id获取)?
在项目中使用Gorm:是否可以为公共db操作定义共享方法(例如通过id获取)?,go,inheritance,go-gorm,code-reuse,Go,Inheritance,Go Gorm,Code Reuse,在项目中使用go和gorm 我创建了一个dao级别来包装数据库操作,每个表都有自己的dao类型 现行代码 从FirstDao中获取方法,用于first表和FirstModel: func (dao *FirstDao) Get(id uint64) (*model.FirstModel, error) { } func (dao *SecondDao) Get(id uint64) (*model.SecondModel, error) { } 从SecondDao中获取方法,用于se
go
和gorm
我创建了一个dao
级别来包装数据库操作,每个表都有自己的dao类型
现行代码
从
中获取FirstDao
方法,用于
表和first
:FirstModel
func (dao *FirstDao) Get(id uint64) (*model.FirstModel, error) { }
func (dao *SecondDao) Get(id uint64) (*model.SecondModel, error) { }
从
中获取SecondDao
方法,用于
表和second
:SecondModel
func (dao *FirstDao) Get(id uint64) (*model.FirstModel, error) { }
func (dao *SecondDao) Get(id uint64) (*model.SecondModel, error) { }
我想要达到的目标 想知道是否可以用一个
Get()
方法在go中编写一个BaseDao
,这样我就不必编写这段代码两次了
这在Java中非常容易,但由于go非常不同,并且不支持真正的继承(我猜),所以不确定这是否可能
我试过的
- 定义模型接口,并尝试使用反射。但是失败了。
主要原因:在
方法中,它仍然需要原始特定结构的实例,例如Get()
,我将其作为接口model.FirstModel{}
传递,不能将其用作原始类型model.model
- 结构嵌入
- 谷歌搜索
问题
- 有可能这样做吗
- 若否,原因为何
- 如果是,如何进行
类型BaseDao结构{
第一刀
二道
}
func(dao*BaseDao)Get(id uint64)(*model.SecondModel,错误){
}
只是写下我的想法。这可能会帮助您找到解决方案键入BaseDao结构{
第一刀
二道
}
func(dao*BaseDao)Get(id uint64)(*model.SecondModel,错误){
}
只是写下我的想法。这可能会帮助您找到解决方案如果您试图完全绕过为每个DAO编写
Get()
方法,那么您唯一的解决方案就是从此方法返回接口{}
。
然而,这种方法产生了两个问题:
- 您需要在任何地方手动强制转换
接口{}
- 你在亵渎类型安全
接口{}
转换为类型安全值
例子
首先使用泛型Get()
方法创建基本DAO。
Go中没有类型泛型,因此您应该在此处返回接口{}
type BaseDAO结构{}
func(*BaseDAO)Get(id uint64)(接口{},错误){}
然后,对于每种类型的数据,创建一个特定的DAO实现,嵌入BaseDAO
:
type FooModel=string
类型FooDAO结构{
//通过不在此字段上指定名称来增强BaseDAO
//可以从FooDAO实例调用BaseDAO方法
BaseDAO
}
func(foo*FooDAO)Get(id uint64)(FooModel,error){
//从BaseDAO调用shared Get()方法。
//您可以看到这就像Java中的'super.Get()'调用一样。
结果:=foo.BaseDAO.Get(id)
返回结果(FooModel),无
}
如果您试图完全绕过为每个DAO编写Get()
方法,那么您唯一的解决方案就是从此方法返回接口{}
。
然而,这种方法产生了两个问题:
- 您需要在任何地方手动强制转换
接口{}
- 你在亵渎类型安全
接口{}
转换为类型安全值
例子
首先使用泛型Get()
方法创建基本DAO。
Go中没有类型泛型,因此您应该在此处返回接口{}
type BaseDAO结构{}
func(*BaseDAO)Get(id uint64)(接口{},错误){}
然后,对于每种类型的数据,创建一个特定的DAO实现,嵌入BaseDAO
:
type FooModel=string
类型FooDAO结构{
//通过不在此字段上指定名称来增强BaseDAO
//可以从FooDAO实例调用BaseDAO方法
BaseDAO
}
func(foo*FooDAO)Get(id uint64)(FooModel,error){
//从BaseDAO调用shared Get()方法。
//您可以看到这就像Java中的'super.Get()'调用一样。
结果:=foo.BaseDAO.Get(id)
返回结果(FooModel),无
}
这通常是接口{}
的用途。我不熟悉gorm,但是所有的go编码/解码和封送/解封送函数都已经使用了gorm,所以您不必担心任何反射。@super-Yep,已经找到了解决方案。这通常是接口{}
的用途。我不熟悉gorm,但所有的go编码/解码和封送/解封送函数都已经使用了gorm,因此您不必担心任何反射。@super-yesp,已经找到了解决方案。我已经重构了代码,与答案描述的类似。现在子DAO的代码更加整洁。顺便说一句,在答案结果中,:=foo.BaseDAO.Get(id)
,应该将模型作为第一个参数传递。我重构了与答案描述类似的代码。现在子DAO的代码更加整洁。顺便说一句,在回答结果中,u:=foo.BaseDAO.Get(id)
,应该将模型作为第一个参数传递。