1、背景描述
用beego的ORM框架对sqllite进行库操作。项目中配置表存放在sqlite数据中,这样就存对每个表需要进行增删改查的操作。若按照beego提供方式对每一张表去实现增删改查的操作,这样会有很多的重复代码。例如,插入记录代码中,每个插入操作中都有相似的一段代码。为了代码更加的简洁,需要对重复代码进行封装。
2、实现方式
2.1、公共实现部分
利用golang的语言特性,面向接口编程,对公共操作提取接口:
type Repo interface {
SubscribeUpdateChange(func()) error
SubscribeDeleteChange(func()) error
Update(obj interface{}) (err error)
Delete(obj interface{}) (err error)
}
实现接口的结构:
type BaseRepo struct {
funcsUpdate []func()
funcsDelete []func()
}
//parameter is slice ([]StructName) or ptr(&aObj)
func (r BaseRepo) Update(obj interface{}) (err error) {
defer func() { r.UpdateChanged(err) }()
o := orm.NewOrm()
ms := TransToSlice(obj)//利用反射把入参处理成切片,需要自己实现
for _, m := range ms {
val := reflect.ValueOf(m)
if val.Kind() == reflect.Ptr {
val = val.Elem()
}
id := val.FieldByName("Id").Int()
if id == 0 {
_, err = o.Insert(m)
} else {
_, err = o.Update(m)
}
if err != nil {
return err
}
}
return nil
}
2.2、应用部分
各个配置表依据自己的需求进行接口定义[golang中组合来复用子结构的方法]:
type XxxxRepo interface {
repo.Repo
GetRecord(userName, host string) (xxxx, error)
}
type xxxxRepo struct {
repo.BaseRepo
}
func NewXxxxRepo() XxxxRepo {
return &xxxxRepo{}
}
func (this *xxxxRepo)(userName, host string) (xxxx,error){
//..........
return xxx,nil
}
3、总结
- 公共代码的提取,减少重复代码【clean code】
- golang面向接口编程,罗列接口代码更加清晰
- repo层的思考