安装方式:使用vs自带的nuget管理工具,搜索AutoMapper ,选择第一个安装到你的项目即可。

我从网上找了一些资料,

参考网址:http://blog.csdn.net/csethcrm/article/details/52934325

下载了个demo,然后自己又写了一遍,我把AutoMapper 的使用分为两种:

1、viewmodel与实体的字段名字是一致的,viewmodel的字段可以与实体中的字段数量不一致。

还有一种情况是:源实体中的字段名字是Getxxx,那么viewmodel中对应的字段可以是xxx,也会自动对应赋值,比如我写的demo中源实体中GetA,viewmodel中的A;

再有一种情况就是实体中的实体赋值,在我写的这个例子中,源实体中包含的实体类字段为Sub,里面包含的字段名字为Age,

那么destmodel中对应的字段名字可以是:SubAge,那么automapper就可以自动为你赋值了,大家看最后的运行结果。

给大家看下我建的源实体:

  1. public class Source1
  2. {
  3. public string Name { set; get; }
  4.  
  5. public string GetA { set; get; }
  6. public string GetD { set; get; }
  7.  
  8. public string SetB { set; get; }
  9.  
  10. public string c { set; get; }
  11.  
  12. public SubSource1 Sub { set; get; }
  13. }
  14.  
  15. public class SubSource1
  16. {
  17. public string Age { set; get; }
  18. }

还有viewmodel(要转化成为你想要的模型):

  1. public class Dest1
  2. {
  3. public string Name { set; get; }
  4.  
  5. public string A { set; get; }
  6.  
  7. public string C { set; get; }
  8.  
  9. public string SubAge { set; get; }
  10.  
  11. public string D { set; get; }
  12. }

我封装的扩展方法:

  1. /// <summary>
  2. /// 类型映射,默认字段名字一一对应
  3. /// </summary>
  4. /// <typeparam name="TDestination">转化之后的model,可以理解为viewmodel</typeparam>
  5. /// <typeparam name="TSource">要被转化的实体,Entity</typeparam>
  6. /// <param name="source">可以使用这个扩展方法的类型,任何引用类型</param>
  7. /// <returns>转化之后的实体</returns>
  8. public static TDestination MapTo<TDestination, TSource>(this TSource source)
  9. where TDestination : class
  10. where TSource : class
  11. {
  12. if (source == null) return default(TDestination);
  13. var config = new MapperConfiguration(cfg => cfg.CreateMap<TSource, TDestination>());
  14. var mapper = config.CreateMapper();
  15. return mapper.Map<TDestination>(source);
  16. }

使用方式:

  1. var source1 = new Source1
  2. {
  3. Name = "source",
  4. Sub = new SubSource1 { Age = "" },
  5. c = "c",
  6. GetA = "A",
  7. SetB = "B"
  8. };
  9.  
  10. var destViewModel = source1.MapTo<Source1,Dest1>();

运行结果:

2.viewmodel与实体字段名字没有全部对应,只有几个字段的名字和源实体中的字段名字是一样的,其他的字段是通过实体中的几个字段组合或者是格式或者是类型转化而来的,

使用方法:不能再使用这个扩展方法了,只能自己额外写代码,代码如下:

  1. var config2 = new MapperConfiguration(
  2. cfg => cfg.CreateMap<SourceUser, DestUser2>()
  3. .ForMember(d => d.DestName, opt => opt.MapFrom(s => s.Name)) //指定字段一一对应
  4. .ForMember(d => d.Birthday, opt => opt.MapFrom(src => src.Birthday.ToString("yy-MM-dd HH:mm")))//指定字段,并转化指定的格式
  5. .ForMember(d => d.Age, opt => opt.Condition(src => src.Age > ))//条件赋值
  6. .ForMember(d => d.A1, opt => opt.Ignore())//忽略该字段,不给该字段赋值
  7. .ForMember(d => d.A1, opt => opt.NullSubstitute("Default Value"))//如果源字段值为空,则赋值为 Default Value
  8. .ForMember(d => d.A1, opt => opt.MapFrom(src => src.Name + src.Age * + src.Birthday.ToString("d"))));//可以自己随意组合赋值
  9. var mapper2 = config2.CreateMapper();

注释中都包含了平时常用的几种情况,其他的我就没有再写。

下面再给大家把list转化的扩展方法代码贴上:

  1. /// <summary>
  2. /// 集合列表类型映射,默认字段名字一一对应
  3. /// </summary>
  4. /// <typeparam name="TDestination">转化之后的model,可以理解为viewmodel</typeparam>
  5. /// <typeparam name="TSource">要被转化的实体,Entity</typeparam>
  6. /// <param name="source">可以使用这个扩展方法的类型,任何引用类型</param>
  7. /// <returns>转化之后的实体列表</returns>
  8. public static IEnumerable<TDestination> MapToList<TSource,TDestination>(this IEnumerable<TSource> source)
  9. where TDestination : class
  10. where TSource : class
  11. {
  12. if (source == null) return new List<TDestination>();
  13. var config = new MapperConfiguration(cfg => cfg.CreateMap<TSource, TDestination>());
  14. var mapper = config.CreateMapper();
  15. return mapper.Map<List<TDestination>>(source);
  16. }

同样的使用方式:

  1. var source1 = new Source1
  2. {
  3. Name = "source",
  4. Sub = new SubSource1 { Age = "" },
  5. c = "c",
  6. GetA = "A",
  7. SetB = "B"
  8. };
  9.           var source3 = new Source1
  10. {
  11. Name = "source3",
  12. Sub = new SubSource1 { Age = "" },
  13. c = "c3",
  14. GetA = "A3",
  15. SetB = "B3"
  16. };
  17. var sourceList = new List<Source1> { source1, source3 };
  18. var destViewModelList = sourceList.MapToList<Source1,Dest1>();

运行结果:

以上就是我个人所得,如有错误,欢迎大家指正。

//2017.12.4 修改:destination和source写反了,导致我的总结有些错误,现在纠正一下:错误结论已经红色标注,中间的截图也换成正确的了,工具类方法也已经修正。

出处:https://www.cnblogs.com/dawenyang/p/7966850.html

===========================================================

一、最简单的用法

有两个类User和UserDto

  1. public class User
  2. {
  3. public int Id { get; set; }
  4. public string Name { get; set; }
  5. public int Age { get; set; }
  6. }
  7.  
  8. public class UserDto
  9. {
  10. public string Name { get; set; }
  11. public int Age { get; set; }
  12. }

将User转换成UserDto也和简单

  1. Mapper.Initialize(x => x.CreateMap<User, UserDto>());
  2. User user = new User()
  3. {
  4. Id = ,
  5. Name = "caoyc",
  6. Age =
  7. };
  8. var dto = Mapper.Map<UserDto>(user);

这是一种最简单的使用,AutoMapper会更加字段名称去自动对于,忽略大小写。

二、如果属性名称不同

将UserDto的Name属性改成Name2

  1. Mapper.Initialize(x =>
  2. x.CreateMap<User, UserDto>()
  3. .ForMember(d =>d.Name2, opt => {
  4. opt.MapFrom(s => s.Name);
  5. })
  6. );
  7.  
  8. User user = new User()
  9. {
  10. Id = ,
  11. Name = "caoyc",
  12. Age =
  13. };
  14.  
  15. var dto = Mapper.Map<UserDto>(user);

三、使用Profile配置

自定义一个UserProfile类继承Profile,并重写Configure方法

  1. public class UserProfile : Profile
  2. {
  3. protected override void Configure()
  4. {
  5. CreateMap<User, UserDto>()
  6. .ForMember(d => d.Name2, opt =>
  7. {
  8. opt.MapFrom(s => s.Name);
  9. });
  10. }
  11. }

新版本的 autoMapper.UserProfile.Configure()”: 可能会有提示:没有找到适合的方法来重写 。

可以改为构造函数注入的方式

  1. public class UserProfile : Profile
  2. {
  3. public UserProfile ()
  4. {
  5. CreateMap<User, UserDto>()
  6. .ForMember(d => d.Name2, opt =>
  7. {
  8. opt.MapFrom(s => s.Name);
  9. });
  10. }
  11. }

使用时就这样

  1. Mapper.Initialize(x => x.AddProfile<UserProfile>());
  2.  
  3. User user = new User()
  4. {
  5. Id = ,
  6. Name = "caoyc",
  7. Age =
  8. };
  9.  
  10. var dto = Mapper.Map<UserDto>(user);

四、空值替换NullSubstitute

空值替换允许我们将Source对象中的空值在转换为Destination的值的时候,使用指定的值来替换空值。

  1. public class UserProfile : Profile
  2. {
  3. protected override void Configure()
  4. {
  5. CreateMap<User, UserDto>()
  6. .ForMember(d => d.Name2, opt => opt.MapFrom(s => s.Name))
  7. .ForMember(d => d.Name2, opt => opt.NullSubstitute("值为空"));
  8.  
  9. }
  10. }
  1. Mapper.Initialize(x => x.AddProfile<UserProfile>());
  2.  
  3. User user = new User()
  4. {
  5. Id = ,
  6. Age =
  7. };
  8.  
  9. var dto = Mapper.Map<UserDto>(user);

结果为:

五、忽略属性Ignore

  1. public class User
  2. {
  3. public int Id { get; set; }
  4. public string Name { get; set; }
  5. public int Age { get; set; }
  6. }
  7.  
  8. public class UserDto
  9. {
  10. public string Name { get; set; }
  11. public int Age { get; set; }
  12.  
  13. }
  14.  
  15. public class UserProfile : Profile
  16. {
  17. protected override void Configure()
  18. {
  19. CreateMap<User, UserDto>().ForMember("Name", opt => opt.Ignore());
  20. }
  21. }

使用

  1. Mapper.Initialize(x => x.AddProfile<UserProfile>());
  2.  
  3. User user = new User()
  4. {
  5. Id = ,
  6. Name="caoyc",
  7. Age =
  8. };
  9.  
  10. var dto = Mapper.Map<UserDto>(user);

结果:

六、预设值

如果目标属性多于源属性,可以进行预设值

  1. public class User
  2. {
  3. public int Id { get; set; }
  4. public string Name { get; set; }
  5. public int Age { get; set; }
  6. }
  7.  
  8. public class UserDto
  9. {
  10. public string Name { get; set; }
  11. public int Age { get; set; }
  12. public string Gender { get; set; }
  13.  
  14. }
  15.  
  16. public class UserProfile : Profile
  17. {
  18. protected override void Configure()
  19. {
  20. CreateMap<User, UserDto>();
  21. }
  22. }

使用

  1. Mapper.Initialize(x => x.AddProfile<UserProfile>());
  2.  
  3. User user = new User()
  4. {
  5. Id = ,
  6. Name="caoyc",
  7. Age =
  8. };
  9.  
  10. UserDto dto = new UserDto() {Gender = "男"};
  11. Mapper.Map(user, dto);

七、类型转换ITypeConverter

如果数据中Gender存储的int类型,而DTO中Gender是String类型

  1. public class User
  2. {
  3. public int Gender { get; set; }
  4. }
  5.  
  6. public class UserDto
  7. {
  8. public string Gender { get; set; }
  9. }

类型转换类,需要实现接口ITypeConverter

  1. public class GenderTypeConvertert : ITypeConverter<int, string>
  2. {
  3. public string Convert(int source, string destination, ResolutionContext context)
  4. {
  5. switch (source)
  6. {
  7. case :
  8. destination = "男";
  9. break;
  10. case :
  11. destination = "女";
  12. break;
  13. default:
  14. destination = "未知";
  15. break;
  16. }
  17. return destination;
  18. }
  19. }

配置规则

  1. public class UserProfile : Profile
  2. {
  3. protected override void Configure()
  4. {
  5. CreateMap<User, UserDto>();
  6.  
  7. CreateMap<int, string>().ConvertUsing<GenderTypeConvertert>();
  8. //也可以写这样
  9. //CreateMap<int, string>().ConvertUsing(new GenderTypeConvertert());
  10. }
  11. }

使用

  1. Mapper.Initialize(x => x.AddProfile<UserProfile>());
  2.  
  3. User user0 = new User() { Gender = };
  4. User user1 = new User() { Gender = };
  5. User user2 = new User() { Gender = };
  6. var dto0= Mapper.Map<UserDto>(user0);
  7. var dto1 = Mapper.Map<UserDto>(user1);
  8. var dto2 = Mapper.Map<UserDto>(user2);
  9.  
  10. Console.WriteLine("dto0:{0}", dto0.Gender);
  11. Console.WriteLine("dto1:{0}", dto1.Gender);
  12. Console.WriteLine("dto2:{0}", dto2.Gender);

结果

八、条件约束Condition

当满足条件时才进行映射字段,例如人类年龄,假设我们现在人类年龄范围为0-200岁(这只是假设),只有满足在这个条件才进行映射

DTO和Entity

  1. public class User
  2. {
  3. public int Age { get; set; }
  4. }
  5.  
  6. public class UserDto
  7. {
  8. public int Age { get; set; }
  9. }

Profile

  1. public class UserProfile : Profile
  2. {
  3. protected override void Configure()
  4. {
  5. CreateMap<User, UserDto>().ForMember(dest=>dest.Age,opt=>opt.Condition(src=>src.Age>= && src.Age<=));
  6. }
  7. }

使用代码

  1. Mapper.Initialize(x => x.AddProfile<UserProfile>());
  2.  
  3. User user0 = new User() { Age = };
  4. User user1 = new User() { Age = };
  5. User user2 = new User() { Age = };
  6. var dto0= Mapper.Map<UserDto>(user0);
  7. var dto1 = Mapper.Map<UserDto>(user1);
  8. var dto2 = Mapper.Map<UserDto>(user2);
  9.  
  10. Console.WriteLine("dto0:{0}", dto0.Age);
  11. Console.WriteLine("dto1:{0}", dto1.Age);
  12. Console.WriteLine("dto2:{0}", dto2.Age);

输出结果

出处:https://www.cnblogs.com/caoyc/p/6367828.html

===================================================

AutoMapper介绍

为什么要使用AutoMapper?

我们在实现两个实体之间的转换,首先想到的就是新的一个对象,这个实体的字段等于另一个实体的字段,这样确实能够实现两个实体之间的转换,但这种方式的扩展性,灵活性非常差,维护起来相当麻烦;实体之前转换的工具有很多,不过我还是决定使用AutoMapper,因为它足够轻量级,而且也非常流行,国外的大牛们都使用它使用AutoMapper可以很方便的实现实体和实体之间的转换,它是一个强大的对象映射工具。

一,如何添加AutoMapper到项目中?

在vs中使用打开工具 - 库程序包管理器 - 程序包管理控制平台,输入“Install-Package AutoMapper”命令,就可以把AutoMapper添加到项目中了〜

二,举个栗子

栗子1:两个实体之间的映射

  1. Mapper.CreateMap <Test1Test2>(); Test1 test1 = new Test1 {Id = 1Name =“张三”,Date = DateTime.Now}; Test2 test2 = Mapper.Map <Test2>(test1);
 

栗子2:两个实体不同字段之间的映射

  1. Mapper.CreateMap <Test1Test2>()。ForMemberd => d.Name121opt => opt.MapFroms => s.Name));
 

栗子3:泛型之间的映射

  1.  
      Mapper.CreateMap <Test1,Test2>(); 
  2.  
                var testList = Mapper.Map <List <Test1>,List <Test2 >>(testList);

三,扩展映射方法使映射变得更简单

  1.  
    using System.Collections;
  2.  
    using System.Collections.Generic;
  3.  
    using System.Data;
  4.  
    using AutoMapper;
  5.  
    namespace Infrastructure.Utility
  6.  
     
  7.  
    {
  8.  
    /// <summary>
  9.  
    /// AutoMapper扩展帮助类
  10.  
    /// </summary>
  11.  
    public static class AutoMapperHelper
  12.  
    {
  13.  
    /// <summary>
  14.  
    /// 类型映射
  15.  
    /// </summary>
  16.  
    public static T MapTo<T>(this object obj)
  17.  
    {
  18.  
    if (obj == null) return default(T);
  19.  
    Mapper.CreateMap(obj.GetType(), typeof(T));
  20.  
    return Mapper.Map<T>(obj);
  21.  
    }
  22.  
    /// <summary>
  23.  
    /// 集合列表类型映射
  24.  
    /// </summary>
  25.  
    public static List<TDestination> MapToList<TDestination>(this IEnumerable source)
  26.  
    {
  27.  
    foreach (var first in source)
  28.  
    {
  29.  
    var type = first.GetType();
  30.  
    Mapper.CreateMap(type, typeof(TDestination));
  31.  
    break;
  32.  
    }
  33.  
    return Mapper.Map<List<TDestination>>(source);
  34.  
    }
  35.  
    /// <summary>
  36.  
    /// 集合列表类型映射
  37.  
    /// </summary>
  38.  
    public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
  39.  
    {
  40.  
    //IEnumerable<T> 类型需要创建元素的映射
  41.  
    Mapper.CreateMap<TSource, TDestination>();
  42.  
    return Mapper.Map<List<TDestination>>(source);
  43.  
    }
  44.  
    /// <summary>
  45.  
    /// 类型映射
  46.  
    /// </summary>
  47.  
    public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
  48.  
    where TSource : class
  49.  
    where TDestination : class
  50.  
    {
  51.  
    if (source == null) return destination;
  52.  
    Mapper.CreateMap<TSource, TDestination>();
  53.  
    return Mapper.Map(source, destination);
  54.  
    }
  55.  
    /// <summary>
  56.  
    /// DataReader映射
  57.  
    /// </summary>
  58.  
    public static IEnumerable<T> DataReaderMapTo<T>(this IDataReader reader)
  59.  
    {
  60.  
    Mapper.Reset();
  61.  
    Mapper.CreateMap<IDataReader, IEnumerable<T>>();
  62.  
    return Mapper.Map<IDataReader, IEnumerable<T>>(reader);
  63.  
    }
  64.  
    }
  65.  
    }

这样的话,你就可以这样使用了

var testDto = test.MapTo <Test2>();

var testDtoList = testList.MapTo <Test2>();

出处:https://blog.csdn.net/qq_35193189/article/details/80805451

=========================================================

构造函数映射:

Automapper – 如何映射到构造函数参数,而不是属性设置

我是使用的AutoMapper的版本是9.0

使用ConstructUsing

这将允许您指定在映射期间使用的构造函数。但是所有其他属性将根据约定自动映射。

注意,这不同于ConvertUsing,因为convert使用将不会继续通过约定映射,它会让你完全控制映射。

  1. Mapper.CreateMap<ObjectFrom, ObjectTo>()
  2. .ConstructUsing(x => new ObjectTo(x.arg0, x.arg1, x.etc));

具体使用,参考如下代码:

  1. namespace AutoMapperTest
  2. {
  3. class Program
  4. {
  5. static void Main(string[] args)
  6. {
  7. var config = new MapperConfiguration(cif => cif.AddProfile <UserProfile>()); //方式一
  8. //var config = new MapperConfiguration(cif => cif.AddProfile(new UserProfile()));//方式二
  9. var mapper = config.CreateMapper();
  10.  
  11. var f = new ObjectFrom { TestName = "aaa", TestAge = , TestSex = "m" };
  12. Console.WriteLine(JsonConvert.SerializeObject(f) + Environment.NewLine);
  13.  
  14. var t = mapper.Map<ObjectTo>(f);
  15. Console.WriteLine(JsonConvert.SerializeObject(t) + Environment.NewLine);
  16.  
  17. Console.ReadKey();
  18. }
  19. }
  20.  
  21. public class ObjectFrom
  22. {
  23. public string TestName { get; set; }
  24. public int TestAge { get; set; }
  25. public string TestSex { get; set; }
  26. }
  27.  
  28. public class ObjectTo
  29. {
  30. public ObjectTo(string name)
  31. {
  32. if (name == null)
  33. {
  34. throw new InvalidDataException("name cannot be null");
  35. }
  36. else
  37. {
  38. this._name = name;
  39. }
  40. }
  41.  
  42. private readonly string _name;
  43. public string Name { get { return _name; } }
  44. public int Age { get; set; }
  45. public string Gender { get; set; }
  46.  
  47. }
  48.  
  49. }

参考出处:http://www.voidcn.com/article/p-swatacoc-bsk.html

=========================================================

根据上面的理解和站在巨人的肩膀上,自己重新封装一次,用到项目中。

  1. public static class AutoMapHelper
  2. {
  3.  
  4. /// <summary>
  5. /// 类型映射,默认字段名字一一对应
  6. /// </summary>
  7. /// <typeparam name="TDestination"></typeparam>
  8. /// <param name="obj"></param>
  9. /// <returns></returns>
  10. public static TDestination AutoMapTo<TDestination>(this object obj)
  11. {
  12. if (obj == null) return default(TDestination);
  13. var config = new AutoMapper.MapperConfiguration(cfg => cfg.CreateMap(obj.GetType(), typeof(TDestination)));
  14. return config.CreateMapper().Map<TDestination>(obj);
  15. }
  16.  
  17. /// <summary>
  18. /// 类型映射,可指定映射字段的配置信息
  19. /// </summary>
  20. /// <typeparam name="TSource">源数据:要被转化的实体对象</typeparam>
  21. /// <typeparam name="TDestination">目标数据:转换后的实体对象</typeparam>
  22. /// <param name="source">任何引用类型对象</param>
  23. /// <param name="cfgExp">可为null,则自动一一映射</param>
  24. /// <returns></returns>
  25. public static TDestination AutoMapTo<TSource, TDestination>(this TSource source, Action<AutoMapper.IMapperConfigurationExpression> cfgExp)
  26. where TDestination : class
  27. where TSource : class
  28. {
  29. if (source == null) return default(TDestination);
  30. var config = new AutoMapper.MapperConfiguration(cfgExp != null ? cfgExp : cfg => cfg.CreateMap<TSource, TDestination>());
  31. var mapper = config.CreateMapper();
  32. return mapper.Map<TDestination>(source);
  33. }
  34.  
  35. /// <summary>
  36. /// 类型映射,默认字段名字一一对应
  37. /// </summary>
  38. /// <typeparam name="TSource">源数据:要被转化的实体对象</typeparam>
  39. /// <typeparam name="TDestination">目标数据:转换后的实体对象</typeparam>
  40. /// <param name="source">任何引用类型对象</param>
  41. /// <returns>转化之后的实体</returns>
  42. public static TDestination AutoMapTo<TSource, TDestination>(this TSource source)
  43. where TDestination : class
  44. where TSource : class
  45. {
  46. if (source == null) return default(TDestination);
  47. var config = new AutoMapper.MapperConfiguration(cfg => cfg.CreateMap<TSource, TDestination>());
  48. var mapper = config.CreateMapper();
  49. return mapper.Map<TDestination>(source);
  50. }
  51.  
  52. /// <summary>
  53. /// 集合列表类型映射,默认字段名字一一对应
  54. /// </summary>
  55. /// <typeparam name="TDestination">转化之后的实体对象,可以理解为viewmodel</typeparam>
  56. /// <typeparam name="TSource">要被转化的实体对象,Entity</typeparam>
  57. /// <param name="source">通过泛型指定的这个扩展方法的类型,理论任何引用类型</param>
  58. /// <returns>转化之后的实体列表</returns>
  59. public static IEnumerable<TDestination> AutoMapTo<TSource, TDestination>(this IEnumerable<TSource> source)
  60. where TDestination : class
  61. where TSource : class
  62. {
  63. if (source == null) return new List<TDestination>();
  64. var config = new AutoMapper.MapperConfiguration(cfg => cfg.CreateMap<TSource, TDestination>());
  65. var mapper = config.CreateMapper();
  66. return mapper.Map<List<TDestination>>(source);
  67. }
  68.  
  69. }

其实还可以继续优化,在泛型中不需要知道指定source的类型了,因为可以直接获取到,后面有时间再调整吧。

c# AutoMapper 使用方式和再封装的更多相关文章

  1. iOS开发之网络请求(基于AFNetworking的再封装)

    最近一直很忙也没有什么时间写博客了.放假了休息一下,就写一篇博客来总结一下最近做项目中出现过的问题吧!!! 首先,在项目中我的起到了什么作用,无非就是把美工(UI设计师)给我们的图显示出来,然后再和服 ...

  2. 打印 Logger 日志时,需不需要再封装一下工具类?

    在开发过程中,打印日志是必不可少的,因为日志关乎于应用的问题排查.应用监控等.现在打印日志一般都是使用 slf4j,因为使用日志门面,有助于打印方式统一,即使后面更换日志框架,也非常方便.在 < ...

  3. 对Zlib单元进行再封装

    对Zlib单元进行再封装 低版本DELPHI,如D7,ZLIB.pas单元封装的很简陋,因此有必要再封装,以增加使用的便利性. 高版本DELPHI,zlib.pas本身提供的接口已经相当完善. Zli ...

  4. c# AutoMapper 使用方式

    安装方式:使用vs自带的nuget管理工具,搜索AutoMapper ,选择第一个安装到你的项目即可. 我从网上找了一些资料,下载了个demo,然后自己又写了一遍,我把AutoMapper 的使用分为 ...

  5. RecyclerView再封装

    RecyclerView做为ListView的替代品,已经出了很久了,既然是替代品,那自然有些ListView没有的优点.比如说:可以随意切换list,grid,stagger.可以指定一个或多个it ...

  6. lodash源码分析之缓存使用方式的进一步封装

    在世界上所有的民族之中,支配着他们的喜怒选择的并不是天性,而是他们的观点. --卢梭<社会与契约论> 本文为读 lodash 源码的第九篇,后续文章会更新到这个仓库中,欢迎 star:po ...

  7. struts2 中属性驱动(其实就是struts2 action 中处理 request 的参数【old 方式servlet api 封装数据到javabean中(or beanutils)】),这里属性驱动是新方式

    1.属性驱动 a\  一般的set public class UserAction extends ActionSupport { private String username; private S ...

  8. mvc中使用Pagination,对其进行再封装

    对其进行再次封装: (function($) { $["fn"]["easyPaging"] = function(o) { if (!o.pageSelect ...

  9. Redisclient连接方式Hiredis简单封装使用,连接池、屏蔽连接细节

    工作须要对Hiredis进行了简单封装,实现功能: 1.API进行统一,对外仅仅提供一个接口. 2.屏蔽上层应用对连接的细节处理: 3.底层採用队列的方式保持连接池,保存连接会话. 4.重连时採用时间 ...

随机推荐

  1. C++二维数组、指针、对象数组、对象指针

    项目中用到,随手记一下: 1.二维数组.与指针 创建二维数组指针的方式: a.已知一维的大小 1 int **array=new int *[rows]; 2 (for int i=0;i<ro ...

  2. vim详解

    vim介绍: 1.vim是vi的升级版本 2.vim是带有颜色显示的 3.vim三个模式:一般模式.编辑模式.命令模式 最小化模式下默认是没有安装vim的: [root@linux-xl ~]# yu ...

  3. 没有与这些操作数匹配的 "<<" 运算符 操作数类型为: std::ostream << std::string

    错误显示:没有与这些操作数匹配的 "<<" 运算符       操作数类型为:  std::ostream << std::string 错误改正:要在头文 ...

  4. background属性冲突导致的部分浏览器背景图片不显示问题

    前几天在项目中遇到了一个让人摸不着头脑的bug,测试说页面显示有点问题并发了截图, 正常的显示状态是这样 首先我自信地用自己的手机检查了一下,没有问题,问清楚后得知是UC浏览器中出现的,UC的内核是u ...

  5. head语法

    head 与 tail 就像它的名字一样的浅显易懂,它是用来显示开头或结尾某个数量的文字区块,head 用来显示档案的开头至标准输出中,而 tail 想当然尔就是看档案的结尾.1.命令格式:head ...

  6. TCP长连接与短连接、心跳机制

    1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次 ...

  7. java编码与解码(一)

    转:https://blog.csdn.net/heyanxi0101/article/details/80356870 java编码与解码(一) 编码表概述和常见的编码表 概述:有字符及其对应的数值 ...

  8. ubuntu下,python2.7安装mysqlldb驱动方法

    安装依赖: sudo apt-get install libmysqlclient-dev libmysqld-dev python-dev python-setuptools 安装MySQLdb p ...

  9. 面试知识点准备-C++常见问题

    博客园写写格式简单的文章还行,格式一复杂就不行了,可能是我不会用吧,我有强迫症,有道云格式很好用,以后去有道写这种东西了 有道云笔记链接:http://note.youdao.com/noteshar ...

  10. IDEA 自动生成Hibernate实体类和Mapping文件

    一.新建工程Demo(如果选的时候勾选了hibernate,IDEA会自动下载Hibernate包,不需要手动导入) 二.导入相关包 Mysql && Hibernate 三.添加Hi ...