farseer-go/mapper 实体类对象的优雅转换(赋值)

573 阅读3分钟

mapper对象转换

English Document中文文档English Documentgithub Source

包:"github.com/farseer-go/mapper"

1、概述

我们在开发当中经常会遇到DTO实体与PO数据库实体实体集合与实体集合、以及各种各样的相互转换问题。

该组件很好的解决了上述转换过程中需要每个字段单独赋值的繁琐代码。

组件支持 Map之间的转换,支持 数组之间的转换,支持 数组转List ,支持实体转Map ,支持List转List

另一个重要的功能是支持子属性的转换:一个实体包含子实体,支持转换到一个展开的实体对象。

2、使用场景

一般来说,在应用系统中都会有很多实体类对象,比如数据库的实体类。

有时候从数据库查出来的对象,我们不希望把所有字段都返回给前端(接口)

比如UserPO数据库对象,其中包含了密码字段,我们要把这个对象返回给前端,肯定不会把密码字段返回出去的。

这个时候可能会定义一个UserDTO实体(没有密码字段)。这个时候我们希望直接通过简单的方法,让UserPO数据直接转换到UserDTO中。

3、示例类型

type ClientVO struct {
    Id   int64
    Ip   string
    Name string
}

type UserVO struct {
    Id   int64
    Name string
}

type TaskDO struct {
   Id           int
   Client       ClientVO   // struct结构
   Status       State
   UserId       int64
   UserName     string
   Data         collections.Dictionary[string, string]
   CreateAt     time.Time
   IsEnable     bool
}

type TaskDTO struct {
   Id           int
   ClientId     int64
   ClientIp     string
   ClientName   string
   Status       State
   User         UserVO // struct结构
   Data         collections.Dictionary[string, string]
   CreateAt     time.Time
   UpdateAt     time.Time
   IsEnable     bool
}

这是两个对象,我们的目的是要让TaskDO、TaskDTO之间能快速的转换。

可以看出在TaskDO.Client、TaskDTO.User两个子属性,他们都是struct结构,我们的目的是让子属性也能支持这种优雅的转换

4、Single

单个对象之间的转换,对象可以是:struct、map

函数定义

// Single 单个转换
func Single[TEntity any](fromObjPtr any) TEntity

用法:

dto := TaskDTO{
    Id:         1,
    ClientId:   1000,
    ClientIp:   "127.0.0.1",
    ClientName: "node",
    Status:     Pending,
    User: UserVO {
    Id:   88,
    Name: "steden",
    },
    Data: collections.NewDictionaryFromMap(map[string]string{"age": "18", "price": "88.88"}),
}

taskDO := mapper.Single[TaskDO](dto)

TaskDTOTaskDO对象

5、Array

将切片对象转换成另一个切片对象

函数定义

// Array 数组转换
// fromSlice=数组切片
func Array[T any](fromSlice any) []T

用法:

arrDto := []TaskDTO{{
      Id:         1,
      ClientId:   1000,
      ClientIp:   "127.0.0.1",
      ClientName: "node",
      Status:     Pending,
      User:       UserVO{Id: 88, Name: "steden"},
      Data:       collections.NewDictionaryFromMap(map[string]string{"age": "18", "price": "88.88"}),
   }, {
      Id:         2,
      ClientId:   1000,
      ClientIp:   "127.0.0.1",
      ClientName: "node",
      Status:     Pending,
      User:       UserVO{Id: 20, Name: "steden1"},
      Data:       collections.NewDictionaryFromMap(map[string]string{"age": "18", "price": "88.88"}),
   }}

arrDO := mapper.Array[TaskDO](arrDto)

[]TaskDTO[]TaskDO切片

6、ToMap

结构对象转成map类型

函数定义

// ToMap 结构体转Map
func ToMap[K comparable, V any](entity any) map[K]V

用法:

dto := TaskDTO{
    Id:         1,
    ClientId:   1000,
    ClientIp:   "127.0.0.1",
    ClientName: "node",
    Status:     Pending,
    User: UserVO{Id: 20, Name: "steden1"},
    Data: collections.NewDictionaryFromMap(map[string]string{"age": "18", "price": "88.88"}),
}
dic := mapper.ToMap[string, any](dto)

TaskDTOmap[string]any类型

7、ToPageList

collections.PageList集合类型转换

函数定义

// ToPageList 转换成core.PageList
// fromSlice=数组切片
func ToPageList[TEntity any](sliceOrListOrListAny any, recordCount int64) collections.PageList[TEntity]

用法:

arrDto := []TaskDTO{{
    Id:         1,
    ClientId:   1000,
    ClientIp:   "127.0.0.1",
    ClientName: "node",
    Status:     Pending,
    User:       UserVO{Id: 88, Name: "steden"},
    Data:       collections.NewDictionaryFromMap(map[string]string{"age": "18", "price": "88.88"}),
}, {
    Id:         2,
    ClientId:   1000,
    ClientIp:   "127.0.0.1",
    ClientName: "node",
    Status:     Pending,
    User:       UserVO{Id: 20, Name: "steden1"},
    Data:       collections.NewDictionaryFromMap(map[string]string{"age": "18", "price": "88.88"}),
}}

lst := mapper.ToPageList[TaskDO](arrDto, 10)

collections.PageList类型

// PageList 用于分页数组,包含总记录数
type PageList[TData any] struct {
   // 总记录数
   RecordCount int64
   // 数据列表
   List List[TData]
}

这是带记录总数的数据集

collections.PageList[TaskDTO]collections.PageList[TaskDO]

8、方法ToList

函数定义

// 转换成List
func ToList[TEntity any](sliceOrListOrListAny any) collections.List[TEntity] 

用法:

arrDto := []TaskDTO{{
    Id:         1,
    ClientId:   1000,
    ClientIp:   "127.0.0.1",
    ClientName: "node",
    Status:     Pending,
    User:       UserVO{Id: 88, Name: "steden"},
    Data:       collections.NewDictionaryFromMap(map[string]string{"age": "18", "price": "88.88"}),
}, {
    Id:         2,
    ClientId:   1000,
    ClientIp:   "127.0.0.1",
    ClientName: "node",
    Status:     Pending,
    User:       UserVO{Id: 20, Name: "steden1"},
    Data:       collections.NewDictionaryFromMap(map[string]string{"age": "18", "price": "88.88"}),
}}
lst := collections.NewList(arrDto...)
lstDO := mapper.ToList[TaskDO](lst)

collections.List[TaskDTO]collections.List[TaskDO]

9、ToListAny

函数定义

// 切片转ToListAny
func ToListAny(sliceOrList any) collections.ListAny

用法:

arrDto := []TaskDTO{{
    Id:         1,
    ClientId:   1000,
    ClientIp:   "127.0.0.1",
    ClientName: "node",
    Status:     Pending,
    User:       UserVO{Id: 88, Name: "steden"},
    Data:       collections.NewDictionaryFromMap(map[string]string{"age": "18", "price": "88.88"}),
}, {
    Id:         2,
    ClientId:   1000,
    ClientIp:   "127.0.0.1",
    ClientName: "node",
    Status:     Pending,
    User:       UserVO{Id: 20, Name: "steden1"},
    Data:       collections.NewDictionaryFromMap(map[string]string{"age": "18", "price": "88.88"}),
}}
listAny := mapper.ToListAny(arrDto)

[]TaskDTOcollections.ListAny