实际项目开发中,需要各个层的数据流转,entity转换到domain,domain转换到response,常见实现的方式基本都是通过反射机制实现,例如Spring BeanUtils. copyProperties,Golang的copier第三方库,反射的效率众所周知,基本都是惨不忍睹。
当然也可以手动一个个的赋值
type User struct {
ID int
Mobile string
Level int
Name string
RegisterTime time.Time
}
func (u *User) Mapping (from *User) {
u.ID = from.ID
u.Mobile = from.Mobile
u.Level = from.Level
u.Name = from.Name
u.RegisterTime = from.RegisterTime
}
对比一下手动赋值和反射的效率
## Benchmarks
| Benchmark name | (1) | (2) | (3) | (4) |
| ------------------------------ | ---------| ---------------| ------------| ---------------|
| BenchmarkMapper | 1000000000 | 0.3679 ns/op | 0 B/op | 0 allocs/op |
| BenchmarkCopier | 163282 | 6852 ns/op | 3000 B/op | 48 allocs/op |
反射每次耗时6852ns,手动赋值0.36ns,效率差距还是巨大的。
structmapper小工具因此应运而生,structmapper是通过 go:generate 自动生成Mapping函数。
//go:generate go run github.com/wizardshan/structmapper -toName User -fromName User -toPath ./response -fromPath ./domain -toVar resp -fromVar dom
//go:generate go run github.com/wizardshan/structmapper -toName Orders -fromName Orders -toPath ./response -fromPath ./domain -toVar resp -fromVar dom
package response
type User struct {
ID int `json:"id"`
CreateTime DateTime `json:"createTime"`
UpdateTime *DateTime `json:"updateTime"`
DeleteTime *DateTime `json:"deleteTime"`
Mobile string `json:"mobile"`
Nickname string `json:"nickname"`
Money Money `json:"money"`
Level int `json:"level"`
}
package domain
type User struct {
ID int
CreateTime time.Time
UpdateTime *time.Time
Mobile string
Nickname string
Money int
}
func (dom *User) Level() int {
return 1
}
user_mapping.go
func (resp *User) Mapping(dom *domain.User) {
/**************** mapping start ****************/
resp.ID = dom.ID
resp.CreateTime = DateTime(dom.CreateTime)
if dom.UpdateTime != nil {
updateTime := DateTime(*dom.UpdateTime)
resp.UpdateTime = &(updateTime)
}
//resp.DeleteTime = fromStruct property not exist
resp.Mobile = dom.Mobile
resp.Nickname = dom.Nickname
resp.Money = Money(dom.Money)
resp.Level = dom.Level()
/**************** mapping end ****************/
}
希望大家多提意见 项目地址