java automapper 使用_AutoMapper入门使用
AutoMapper入门使用
在应用开发的过程中,首先要了解整个系统中各个系统的组件的作用,然后了解系统的工作流(workflow),最后需要梳理一遍数据流(dataflow),而在整理数据流的过程中,数据的转化常常是最难理解写起来相当枯燥乏味的部分,AutoMapper的功能就是实现映射一个对象到另一个对象的自动化工具,最常见的就是DTO (Data Transfer Object)与MO(ModelObject)之间的转换,这里我先介绍一下DTO与MO的关系,然后才介绍AutoMapper工具的使用。
理解DTO
以下是我总结的几个不同平台的解释:
百度百科:
数据传输对象(DTO)(Data Transfer Object),是一种设计模式之间传输数据的软件应用系统。数据传输目标往往是数据访问对象从数据库中检索数据。数据传输对象与数据交互对象或数据访问对象之间的差异是一个以不具有任何行为除了存储和检索的数据(访问和存取器)
维基百科:
数据传输对象(DTO)是在两个进程之间承载数据的对象。数据传输和业务对象或数据访问对象之间的区别在于,DTO除了存储和检索其自身的数据(调制器和访问器)之外没有任何行为。DTO是不应该包含任何需要测试的业务逻辑的简单对象。
博客园dax.net:
表现层于应用层之间是通过DTO来进行交互的,数据传输对象是没有行为的POCO对象,他的目的是为了对领域对象进行数据封装,实现层与层之间的数据传递。简单来说Model面向业务,我们是通过业务来定义Model的。而DTO是面向UI,通过UI的需求来定义的,通过DTO我们实现了表现层与Model层之间的解耦,表现层不引用Model。如果开发过程中我们的模型变了,而界面没变,我们只需改Model而不需要去改动表现层。
看了这些解释,应该还是有点蒙?
先来看看为什么要使用DTO,我总结了三点
隔离领域模型,使用封装(包括数据结构的精简和合并)的DTO实现改动领域模型而不影响UI,保持领域模型的安全,不暴露业务逻辑。
在分布式模式下,相同的数据结构在不同的场景使用相同的数据结构有不同的需求。
DTO的存在也为了帮助减少客户端请求而降低服务器压力,提升效率。
不是所有的时候都需要用到DTO,如果为所有的不同需求都建一个DTO,那么一个概念所对应的DTO可能多达5,6种,非常难于管理,当页面所需要的数据与数据库中的数据不一致的情况如果常常出现,那么我们就需要开始着手准备添加对DTO的支持,并且DTO可以设当的冗余设计来减少DTO种类
在系统中添加DTO主要有以下几部分工作需要完成
设计和添加DTO类。
添加从MO到DTO的转化逻辑。
将原本对MO的使用转换为对DTO的使用。(这里可以看出,要尽早的预判是否需要DTO,以免将来麻烦)
关于DTO就了解到这,下面开始回归正题,介绍AutoMapper工具的使用
AutoMapper入门
安装AutoMapper
从包管理器控制台安装
打开程序包管理器控制台,然后输入命令:Install-PackageAutoMapper
从包管理器界面安装
在界面中搜索需要安装的程序集,如AutoMapper.dll
安装完成之后添加到程序集引用中即可。
如何使用AutoMapper
首先,您需要使用源类型和目标类型。目标类型的设计可能受其所在层的影响,但只要成员的名称与源类型的成员匹配,AutoMapper就可以发挥最佳效果。如果您有一个名为“FirstName”的源成员,它将自动映射到名称为“FirstName”的目标成员。AutoMapper也支持拼合。
一旦你有了你的类型,你可以使用MapperConfiguration或者静态Mapper实例和CreateMap为这两种类型创建一个映射。MapperConfiguration通常每个AppDomain只需要一个实例,并且应该在启动过程中实例化。
创建映射的两种方式(左侧的类型是源类型,右侧的类型是目标类型):
静态方式:
Mapper.Initialize(cfg => cfg.CreateMap());
如果您使用的是静态Mapper方法,则每个AppDomain只能进行一次配置。这意味着放置配置代码的最佳位置是在应用程序启动时,例如ASP.NET应用程序的Global.asax文件
实例方式
var config = new MapperConfiguration(cfg => cfg.CreateMap());
要执行映射又可以使用静态或实例映射器方法:
IMappermapper = config.CreateMapper();
IMappermapper = new Mapper(config);
大多数应用程序可以使用依赖注入来注入创建的IMapper实例。
可以添加配置到配置类中,方便统一管理(AddProfile),然后通过自己写一下泛型返回自己想要的类型转换,这样可以一次性实例化多种类型映射:
Mapper.Initialize(cfg => cfg.AddProfile(new MyProfile()));
Mapper.Initialize(cfg => cfg.AddProfile());
var config = new MapperConfiguration(fig => fig.AddProfile(new MyProfile()));
var config = new MapperConfiguration(fig => fig.AddProfile());
处理下面几种情况的方式
属性名称相同
扁平化映射
投影(指定字段)
简单类型映射
使用Profile配置
属性名称不同
条件映射:
空值替换NullSubstitute
忽略属性Ignore
目标属性多于源属性,可以进行预设值
类型转换ITypeConverter
usingAutoMapper;
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading.Tasks;
namespaceAutoMapperDemo
{
publicstaticclassAutoMapperInitialize
{
staticAutoMapperInitialize()
{
Mapper.Initialize(fig =>fig.AddProfile());
}
publicclassUser
{
publicintId {set;get; }
publicstringName {set;get; }
publicintAge {set;get; }
publicUser(inti)
{
Id =i;
Name ="muphy-"+i;
Age = 15 +i;
}
publicUser()
{
Id = 1;
Name ="muphy";
Age = 15;
}
publicoverridestringToString()
{
return"[Name:"+ Name +",Age:"+ Age +"]";
}
}
publicclassUserDto
{
publicstringName {set;get; }
publicintAge {set;get; }
publicoverridestringToString()
{
return"[Name:"+ Name +",Age:"+ Age +"]";
}
}
publicclassAzi:User
{
publicstringLike {set;get; }
publicAzi(inti) :base(i) { Like ="QiaoFeng"; }
publicAzi() { }
publicoverridestringToString()
{
return"[Name:"+ Name +",Age:"+ Age +"]";
}
}
publicclassProduct
{
publicSupplierSupplier{set;get; }
publicdecimalGetPrice()
{
return10;
}
publicProduct()
{
Supplier =newSupplier();
}
}
publicclassSupplier
{
publicstringName {get;set; }
publicSupplier()
{
Name ="伟创力";
}
}
publicclassProductDto
{
publicstringSupplierName{set;get; }
publicdecimalPrice {set;get; }
publicoverridestringToString()
{
return"[Price:"+ Price +",SupplierName:"+SupplierName+"]";
}
}
publicclassBook:Product
{
publicDateTimeBuyTime{get{returnDateTime.Now; } }
}
publicclassBookDto:ProductDto
{
publicDateTimeDate {get;set; }
publicintHour {get;set; }
publicintMinute {get;set; }
publicoverridestringToString()
{
return"[Price:"+ Price +",SupplierName:"+SupplierName+",Date:"+ Date +"]";
}
}
publicclassSource
{
publicstringName {get{return"muphy"; } }
publicintWidth {set;get; }
}
publicclassDestination
{
publicstringName {get;set; }
publicstringlike {get;set; }
publicoverridestringToString()
{
returnName +" Like "+ like;
}
}
publicclassMyProfile:Profile
{
publicMyProfile()
{
//类型字段系统
CreateMap();
//扁平化映射
CreateMap();
//投影
CreateMap()
.ForMember(desc=>desc.Date, opt =>opt.MapFrom(src=>src.BuyTime.Date))
.ForMember(desc=>desc.Hour, opt =>opt.MapFrom(src=>src.BuyTime.Hour))
.ForMember(desc=>desc.Minute, opt =>opt.MapFrom(src=>src.BuyTime.Minute));
//条件映射
CreateMap().ForMember(desc=>desc.Age, opt =>opt.MapFrom(src=>src.Age< 21));
//可设置默认值
CreateMap().ForMember(desc=>desc.like, opt =>opt.MapFrom(src=>"azi"));
//可忽视多余值
CreateMap().ForMember(desc=>desc.Width, opt =>opt.Ignore());
//空值替换
CreateMap().ForMember(desc=>desc.Name, opt =>opt.NullSubstitute("azi"));
//其他设置
CreateMap()
.BeforeMap((src,desc) =>src.Age+= 50)
.AfterMap((src,desc)=>desc.Age-= 35)//设置转换前后的行为
.ReverseMap();//设置反向映射
}
}
// 1.简单静态的方式初始化映射使用Initialize两个方法:CreateMapAddProfile(稍后)
publicstaticUserDtoAutoMapperConfig1()
{
//Mapper.Initialize(cfg=>cfg.CreateMap());
//Mapper.Initialize(cfg=>cfg.AddProfile(newMyProfile()));
//Mapper.Initialize(cfg=>cfg.AddProfile());
UserDtodto=Mapper.Map(newUser(1));
returndto;
}
// 2.简单实例的方式初始化方式映射使用MapperConfiguration也有两种方式:CreateMapper方法和Mpapper构造函数
publicstaticUserDtoAutoMapperConfig2()
{
MapperConfigurationconfig=newMapperConfiguration(fig =>fig.CreateMap());
varmapper =config.CreateMapper();
//IMappermapper = newMapper(config);
returnmapper.Map(newUser(2));
}
// 3.使用继承Profile的配置属性方式映射AddProfile方法
publicstaticUserDtoAutoMapperConfig3()
{
MapperConfigurationconfig=newMapperConfiguration(fig =>fig.AddProfile());
IMappermapper =newMapper(config);
returnmapper.Map(newUser(3));
}
// 4.使用继承Profile的配置属性+泛型方式映射效果会更好
publicstaticTAutoMapperConfig4(Kk)
{
returnMapper.Map(k);
}
// 5.扁平化映射
publicstaticProductDtoAutoMapperConfig5()
{
MapperConfigurationconfig=newMapperConfiguration(fig =>fig.AddProfile());
varmapper =config.CreateMapper();
returnmapper.Map(newProduct());
}
}
}
java automapper 使用_AutoMapper入门使用相关推荐
- java automapper 使用_AutoMapper使用
前言:前篇搭建了下WCF的代码,就提到了DTO的概念,对于为什么要有这么一个DTO的对象,上章可能对于这点不太详尽,在此不厌其烦再来提提它的作用: 从安全上面考虑,领域Model都带有领域业务,让Cl ...
- java automapper 使用_AutoMapper实际项目运用
AutoMapper是对象到对象的映射工具.在完成映射规则之后,AutoMapper可以将源对象转换为目标对象. 配置AutoMapper映射规则 AutoMapper是基于约定的,因此在实用映射之前 ...
- java automapper 使用_AutoMapper 使用总结
初识AutoMapper 在开始本篇文章之前,先来思考一个问题:一个项目分多层架构,如显示层.业务逻辑层.服务层.数据访问层.层与层访问需要数据载体,也就是类.如果多层通用一个类,一则会暴露出每层的字 ...
- java和php哪个运行更快,java和php哪个入门快?-php教程
跟着互联网的高速倒退,愈来愈多的人开端抉择处置较量争论机行业,而想要处置相干工作的话,理解相干编程言语也是必备的一项技艺.可是有不少冤家正在抉择要学习的编程言语时就被难到了,想晓得哪一种言语入门更快, ...
- 《Java 2D游戏编程入门》—— 1.5 创建一个主动渲染的窗口
本节书摘来异步社区<Java 2D游戏编程入门>一书中的第1章,第1.5节,作者:[美]Timothy Wright(莱特),更多章节内容可以访问云栖社区"异步社区"公 ...
- java消息头,Java网络编程从入门到精通:HTTP消息头字段
Java网络编程从入门到精通:HTTP消息头字段 一.通用头字段 1. Connection 这个字段只在HTTP1.1协议中存在.它决定了客户端和服务器进行了一次会话后, 服务器是否立即关闭网络连接 ...
- JSOUP 教程—— Java爬虫,简易入门,秒杀htmlparser
转载自 JSOUP 教程-- Java爬虫,简易入门,秒杀htmlparser 关于爬虫,之前一直用做第一个站的时候,记得那时候写的 爬虫 是爬sina 的数据,用的就是 htmlparser 可 ...
- WebService 理论详解、JWS(Java Web Service) 快速入门
目录 WebService (web服务)概述 WebService 平台技术 WebService 工作原理 WebService 开发流程 常见 Web Service 框架 JWS(Java W ...
- java教程分享-我赢职场2018年 曹雪松老师java零基础最佳入门视频教程
要论编程语言哪家强,还属我们的java,尽管现在人工智能很火,从而带动了python语言的火热,但论跨平台能力还是首选java,其中javase,javaee,javame强大的功能即可以满足桌面应用 ...
最新文章
- 新版CCNP中文版教材--ISCW
- springMVC 时间、js、html处理
- PHP 获取IP地址 获取当前时间 写文件
- mysql和php数据交互_php mysql交互
- 【渝粤教育】国家开放大学2018年秋季 2405T现代汉语(1) 参考试题
- vscode调试redis源码
- 新rust怎么拆除围墙_“问题围挡”拆除 街道变漂亮了
- mysql5.5主从复制总结
- Oracle 11g RAC oc4j/gsd Offline
- udp java 检测连接_java创建udp连接 java udp怎样测试是否连接
- 2008年10月试题电子商务与电子政务全国
- GET和POST区别详解
- zTree插件setting配置详解
- 二进制计量单位#K,M,G,T的换算
- linux去掉锁屏密码,安卓手机锁屏密码清除方法 android7.0锁屏密码怎么去除
- 如何删除我们的应用在 AppStore 中的负面评论
- ubuntu 下的pdfcrop功能不(pdf剪切)
- java取模数_java – 快速乘法和减法模数
- enumerate用法总结
- 微型计算机主要技术指标是啥,微型计算机的主要技术指标